diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index 0c59db39f..2cd31f9d9 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -91,7 +91,7 @@ ENDIF(NOT CMAKE_COMPILER_IS_GNUCC_RUN) # configure variables set in this file for fast reload later on CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCCompiler.cmake IMMEDIATE) + "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCCompiler.cmake" IMMEDIATE) MARK_AS_ADVANCED(CMAKE_AR) SET(CMAKE_C_COMPILER_ENV_VAR "CC") diff --git a/Modules/Platform/Windows-cl.cmake b/Modules/Platform/Windows-cl.cmake index 5da472118..3c21bd0ee 100644 --- a/Modules/Platform/Windows-cl.cmake +++ b/Modules/Platform/Windows-cl.cmake @@ -1,7 +1,7 @@ # try to load any previously computed information for C on this platform -INCLUDE( ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCPlatform.cmake OPTIONAL) +INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake OPTIONAL) # try to load any previously computed information for CXX on this platform -INCLUDE( ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake OPTIONAL) +INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake OPTIONAL) SET(CMAKE_LIBRARY_PATH_FLAG "-LIBPATH:") SET(CMAKE_LINK_LIBRARY_FLAG "") @@ -273,14 +273,14 @@ SET (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELW # save computed information for this platform -IF(NOT EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCPlatform.cmake") +IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCPlatform.cmake IMMEDIATE) -ENDIF(NOT EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCPlatform.cmake") +ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") -IF(NOT EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake") +IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake IMMEDIATE) -ENDIF(NOT EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake") +ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") INCLUDE(Platform/WindowsPaths) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 3e46a48f7..d562953be 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -169,42 +169,21 @@ cmGlobalGenerator::EnableLanguage(std::vectorconst& languages, // files from the parent cmake bin dir, into the try compile bin dir if(this->ConfiguredFilesPath.size()) { - std::string src = this->ConfiguredFilesPath; - src += "/CMakeSystem.cmake"; - std::string dst = rootBin; - dst += "/CMakeSystem.cmake"; - cmSystemTools::CopyFileIfDifferent(src.c_str(), dst.c_str()); for(std::vector::const_iterator l = languages.begin(); l != languages.end(); ++l) { if(*l == "NONE") { this->SetLanguageEnabled("NONE", mf); - continue; + break; } - const char* lang = l->c_str(); - std::string src2 = this->ConfiguredFilesPath; - src2 += "/CMake"; - src2 += lang; - src2 += "Compiler.cmake"; - std::string dst2 = rootBin; - dst2 += "/CMake"; - dst2 += lang; - dst2 += "Compiler.cmake"; - cmSystemTools::CopyFileIfDifferent(src2.c_str(), dst2.c_str()); - src2 = this->ConfiguredFilesPath; - src2 += "/CMake"; - src2 += lang; - src2 += "Platform.cmake"; - dst2 = rootBin; - dst2 += "/CMake"; - dst2 += lang; - dst2 += "Platform.cmake"; - cmSystemTools::CopyFileIfDifferent(src2.c_str(), dst2.c_str()); } rootBin = this->ConfiguredFilesPath; } + // set the dir for parent files so they can be used by modules + mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str()); + // find and make sure CMAKE_MAKE_PROGRAM is defined this->FindMakeProgram(mf); diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 1a922935e..0a876b44c 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -501,6 +501,66 @@ cmGlobalUnixMakefileGenerator3 this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", false, true); } + +std::string cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(const char* makeProgram, + const char *projectName, const char* additionalOptions, const char *targetName, + const char* config, bool ignoreErrors) +{ + // Project name and config are not used yet. + (void)projectName; + (void)config; + + std::string makeCommand = cmSystemTools::ConvertToUnixOutputPath(makeProgram); + + // Since we have full control over the invocation of nmake, let us + // make it quiet. + if ( strcmp(this->GetName(), "NMake Makefiles") == 0 ) + { + makeCommand += " /NOLOGO "; + } + if ( ignoreErrors ) + { + makeCommand += " -i"; + } + if ( additionalOptions ) + { + makeCommand += " "; + makeCommand += additionalOptions; + } + if ( targetName && strlen(targetName)) + { + cmLocalUnixMakefileGenerator3 *lg; + if (this->LocalGenerators.size()) + { + lg = static_cast(this->LocalGenerators[0]); + } + else + { + lg = static_cast(this->CreateLocalGenerator()); + // set the Start directories + lg->GetMakefile()->SetStartDirectory + (this->CMakeInstance->GetStartDirectory()); + lg->GetMakefile()->SetStartOutputDirectory + (this->CMakeInstance->GetStartOutputDirectory()); + lg->GetMakefile()->MakeStartDirectoriesCurrent(); + } + + makeCommand += "\""; + std::string tname = targetName; + tname += "/fast"; + tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT, + cmLocalGenerator::SHELL); + tname = lg->ConvertToMakeTarget(tname.c_str()); + makeCommand += tname.c_str(); + makeCommand += "\""; + if (!this->LocalGenerators.size()) + { + delete lg; + } + } + return makeCommand; +} + //---------------------------------------------------------------------------- void cmGlobalUnixMakefileGenerator3 @@ -550,8 +610,35 @@ cmGlobalUnixMakefileGenerator3 "Build rule for target.", t->second.GetName(), depends, commands, true); + + // Add a fast rule to build the target + std::string localName = lg->GetRelativeTargetDirectory(t->second); + std::string makefileName; + makefileName = localName; + makefileName += "/build.make"; + depends.clear(); + commands.clear(); + std::string makeTargetName = localName; + makeTargetName += "/build"; + localName = t->second.GetName(); + localName += "/fast"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(), makeTargetName.c_str())); + lg->WriteMakeRule(ruleFileStream, "fast build rule for target.", + localName.c_str(), depends, commands, true); } } + else + { + // Add a fast rule to build the target + depends.clear(); + commands.clear(); + std::string localName = t->second.GetName(); + depends.push_back(localName); + localName += "/fast"; + lg->WriteMakeRule(ruleFileStream, "fast build rule for target.", + localName.c_str(), depends, commands, true); + } } } } @@ -578,117 +665,120 @@ cmGlobalUnixMakefileGenerator3 cmTargets& targets = lg->GetMakefile()->GetTargets(); for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) { - if (((t->second.GetType() == cmTarget::EXECUTABLE) || - (t->second.GetType() == cmTarget::STATIC_LIBRARY) || - (t->second.GetType() == cmTarget::SHARED_LIBRARY) || - (t->second.GetType() == cmTarget::MODULE_LIBRARY) || - (t->second.GetType() == cmTarget::UTILITY)) && - t->second.GetName() && - strlen(t->second.GetName())) + if (t->second.GetName() && strlen(t->second.GetName())) { - bool needRequiresStep = - this->NeedRequiresStep(lg,t->second.GetName()); + std::string makefileName; // Add a rule to build the target by name. localName = lg->GetRelativeTargetDirectory(t->second); - std::string makefileName = localName; + makefileName = localName; makefileName += "/build.make"; - lg->WriteDivider(ruleFileStream); - ruleFileStream - << "# Target rules for target " - << localName << "\n\n"; - - commands.clear(); - if (t->second.GetType() != cmTarget::UTILITY) + if (((t->second.GetType() == cmTarget::EXECUTABLE) || + (t->second.GetType() == cmTarget::STATIC_LIBRARY) || + (t->second.GetType() == cmTarget::SHARED_LIBRARY) || + (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::UTILITY))) { + bool needRequiresStep = + this->NeedRequiresStep(lg,t->second.GetName()); + + lg->WriteDivider(ruleFileStream); + ruleFileStream + << "# Target rules for target " + << localName << "\n\n"; + + commands.clear(); + if (t->second.GetType() != cmTarget::UTILITY) + { + makeTargetName = localName; + makeTargetName += "/depend"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); + + // add requires if we need it for this generator + if (needRequiresStep) + { + makeTargetName = localName; + makeTargetName += "/requires"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); + } + } makeTargetName = localName; - makeTargetName += "/depend"; + makeTargetName += "/build"; commands.push_back(lg->GetRecursiveMakeCall (makefileName.c_str(),makeTargetName.c_str())); - // add requires if we need it for this generator - if (needRequiresStep) + // Write the rule. + localName += "/all"; + depends.clear(); + this->AppendGlobalTargetDepends(depends,t->second); + lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", + localName.c_str(), depends, commands, true); + + // add the all/all dependency + if (!exclude && t->second.IsInAll()) { - makeTargetName = localName; - makeTargetName += "/requires"; - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(),makeTargetName.c_str())); + depends.clear(); + depends.push_back(localName); + commands.clear(); + lg->WriteMakeRule(ruleFileStream, "Include target in all.", + "all", depends, commands, true); } - } - makeTargetName = localName; - makeTargetName += "/build"; - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(),makeTargetName.c_str())); - - // Write the rule. - localName += "/all"; - depends.clear(); - this->AppendGlobalTargetDepends(depends,t->second); - lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", - localName.c_str(), depends, commands, true); - - // add the all/all dependency - if (!exclude && t->second.IsInAll()) - { + + // Write the rule. + commands.clear(); + commands.push_back(lg->GetRecursiveMakeCall + ("CMakeFiles/Makefile2",localName.c_str())); + depends.clear(); + depends.push_back("cmake_check_build_system"); + localName = lg->GetRelativeTargetDirectory(t->second); + localName += "/rule"; + lg->WriteMakeRule(ruleFileStream, + "Build rule for subdir invocation for target.", + localName.c_str(), depends, commands, true); + + // Add a target with the canonical name (no prefix, suffix or path). + commands.clear(); depends.clear(); depends.push_back(localName); - commands.clear(); - lg->WriteMakeRule(ruleFileStream, "Include target in all.", - "all", depends, commands, true); - } - - // Write the rule. - commands.clear(); - commands.push_back(lg->GetRecursiveMakeCall - ("CMakeFiles/Makefile2",localName.c_str())); - depends.clear(); - depends.push_back("cmake_check_build_system"); - localName = lg->GetRelativeTargetDirectory(t->second); - localName += "/rule"; - lg->WriteMakeRule(ruleFileStream, - "Build rule for subdir invocation for target.", - localName.c_str(), depends, commands, true); - - // Add a target with the canonical name (no prefix, suffix or path). - commands.clear(); - depends.clear(); - depends.push_back(localName); - lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", - t->second.GetName(), depends, commands, true); - - // Add rules to prepare the target for installation. - if(t->second.NeedRelinkBeforeInstall()) - { + lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", + t->second.GetName(), depends, commands, true); + + // Add rules to prepare the target for installation. + if(t->second.NeedRelinkBeforeInstall()) + { + localName = lg->GetRelativeTargetDirectory(t->second); + localName += "/preinstall"; + depends.clear(); + commands.clear(); + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(), localName.c_str())); + this->AppendGlobalTargetDepends(depends,t->second); + lg->WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.", + localName.c_str(), depends, commands, true); + depends.clear(); + depends.push_back(localName); + commands.clear(); + lg->WriteMakeRule(ruleFileStream, "Prepare target for install.", + "preinstall", depends, commands, true); + } + + // add the clean rule localName = lg->GetRelativeTargetDirectory(t->second); - localName += "/preinstall"; + makeTargetName = localName; + makeTargetName += "/clean"; depends.clear(); commands.clear(); commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(), localName.c_str())); - this->AppendGlobalTargetDepends(depends,t->second); - lg->WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.", - localName.c_str(), depends, commands, true); - depends.clear(); - depends.push_back(localName); + (makefileName.c_str(), makeTargetName.c_str())); + lg->WriteMakeRule(ruleFileStream, "clean rule for target.", + makeTargetName.c_str(), depends, commands, true); commands.clear(); - lg->WriteMakeRule(ruleFileStream, "Prepare target for install.", - "preinstall", depends, commands, true); + depends.push_back(makeTargetName); + lg->WriteMakeRule(ruleFileStream, "clean rule for target.", + "clean", depends, commands, true); } - - // add the clean rule - localName = lg->GetRelativeTargetDirectory(t->second); - makeTargetName = localName; - makeTargetName += "/clean"; - depends.clear(); - commands.clear(); - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(), makeTargetName.c_str())); - lg->WriteMakeRule(ruleFileStream, "clean rule for target.", - makeTargetName.c_str(), depends, commands, true); - commands.clear(); - depends.push_back(makeTargetName); - lg->WriteMakeRule(ruleFileStream, "clean rule for target.", - "clean", depends, commands, true); } } } diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 76bc01186..72b67617a 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -113,6 +113,15 @@ public: /** Get the command to use for a non-symbolic target file that has no rule. This is used for multiple output dependencies. */ std::string GetEmptyCommandHack() { return this->EmptyCommandsHack; } + + + // change the build command for speed + virtual std::string GenerateBuildCommand + (const char* makeProgram, + const char *projectName, const char* additionalOptions, + const char *targetName, + const char* config, bool ignoreErrors); + protected: void WriteMainMakefile2(); void WriteMainCMakefile(); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 85c749ae7..bfbe26b44 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1418,6 +1418,11 @@ void cmLocalUnixMakefileGenerator3 this->Makefile->GetStartOutputDirectory()); this->WriteMakeRule(ruleFileStream, "The main clean target", "clean", depends, commands, true); + commands.clear(); + depends.clear(); + depends.push_back("clean"); + this->WriteMakeRule(ruleFileStream, "The main clean target", "clean/fast", + depends, commands, true); // Write the preinstall rule. dir = this->Makefile->GetStartOutputDirectory();