diff options
Diffstat (limited to 'Source')
31 files changed, 582 insertions, 464 deletions
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 0e16a40..5475c2f 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -637,19 +637,21 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( globalGenerator->FindMakeProgram(this->MakefileMap); const char* cmakeMakeProgram = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM"); - std::string buildCommand - = globalGenerator->GenerateBuildCommand(cmakeMakeProgram, - installProjectName.c_str(), 0, 0, + std::vector<std::string> buildCommand; + globalGenerator->GenerateBuildCommand(buildCommand, cmakeMakeProgram, + installProjectName.c_str(), installDirectory.c_str(), globalGenerator->GetPreinstallTargetName(), - buildConfig, false, false); + buildConfig, false); + std::string buildCommandStr = + cmSystemTools::PrintSingleCommand(buildCommand); cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Install command: " << buildCommand << std::endl); + "- Install command: " << buildCommandStr << std::endl); cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Run preinstall target for: " << installProjectName << std::endl); std::string output; int retVal = 1; bool resB = - cmSystemTools::RunSingleCommand(buildCommand.c_str(), + cmSystemTools::RunSingleCommand(buildCommand, &output, &retVal, installDirectory.c_str(), @@ -659,12 +661,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/PreinstallOutput.log"; cmGeneratedFileStream ofs(tmpFile.c_str()); - ofs << "# Run command: " << buildCommand.c_str() << std::endl + ofs << "# Run command: " << buildCommandStr.c_str() << std::endl << "# Directory: " << installDirectory.c_str() << std::endl << "# Output:" << std::endl << output.c_str() << std::endl; cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem running install command: " << buildCommand.c_str() + "Problem running install command: " << buildCommandStr.c_str() << std::endl << "Please check " << tmpFile.c_str() << " for errors" << std::endl); diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 5e53dbe..0fac136 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -18,6 +18,7 @@ #include "cmGlobalGenerator.h" #include <cmsys/Process.h> #include "cmCTestTestHandler.h" +#include "cmCacheManager.h" //---------------------------------------------------------------------- cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() @@ -184,14 +185,14 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) cmOStringStream out; // if the generator and make program are not specified then it is an error - if (!this->BuildGenerator.size() || !this->BuildMakeProgram.size()) + if (!this->BuildGenerator.size()) { if(outstring) { *outstring = - "--build-and-test requires that both the generator and makeprogram " - "be provided using the --build-generator and --build-makeprogram " - "command line options. "; + "--build-and-test requires that the generator " + "be provided using the --build-generator " + "command line option. "; } return 1; } @@ -238,9 +239,13 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) if(this->BuildNoCMake) { + // Make the generator available for the Build call below. cm.SetGlobalGenerator(cm.CreateGlobalGenerator( this->BuildGenerator.c_str())); cm.SetGeneratorToolset(this->BuildGeneratorToolset); + + // Load the cache to make CMAKE_MAKE_PROGRAM available. + cm.GetCacheManager()->LoadCache(this->BinaryDir.c_str()); } else { @@ -508,23 +513,14 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments( { this->BuildNoClean = true; } - if(currentArg.find("--build-options",0) == 0 && idx < allArgs.size() - 1) + if(currentArg.find("--build-options",0) == 0) { - ++idx; - bool done = false; - while(idx < allArgs.size() && !done) + while(idx+1 < allArgs.size() && + allArgs[idx+1] != "--build-target" && + allArgs[idx+1] != "--test-command") { + ++idx; this->BuildOptions.push_back(allArgs[idx]); - if(idx+1 < allArgs.size() - && (allArgs[idx+1] == "--build-target" || - allArgs[idx+1] == "--test-command")) - { - done = true; - } - else - { - ++idx; - } } } if(currentArg.find("--test-command",0) == 0 && idx < allArgs.size() - 1) diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 1f63185..12ff718 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -114,9 +114,6 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() this->Makefile->GetCMakeInstance()->CreateGlobalGenerator( cmakeGeneratorName); } - this->GlobalGenerator->FindMakeProgram(this->Makefile); - const char* cmakeMakeProgram - = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM"); if(strlen(cmakeBuildConfiguration) == 0) { const char* config = 0; @@ -133,10 +130,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory"); std::string buildCommand = this->GlobalGenerator-> - GenerateBuildCommand(cmakeMakeProgram, - cmakeProjectName, dir.c_str(), - cmakeBuildAdditionalFlags, cmakeBuildTarget, - cmakeBuildConfiguration, true, false); + GenerateCMakeBuildCommand(cmakeBuildTarget, cmakeBuildConfiguration, + cmakeBuildAdditionalFlags, true); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "SetMakeCommand:" << buildCommand.c_str() << "\n"); diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index b6e2569..c06b8ad 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -85,18 +85,7 @@ bool cmBuildCommand } } - const char* makeprogram - = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM"); - if(!makeprogram) - { - this->Makefile->IssueMessage( - cmake::FATAL_ERROR, - "build_command() requires CMAKE_MAKE_PROGRAM to be defined. " - "Call project() or enable_language() first."); - return true; - } - - // If null/empty CONFIGURATION argument, GenerateBuildCommand uses 'Debug' + // If null/empty CONFIGURATION argument, cmake --build uses 'Debug' // in the currently implemented multi-configuration global generators... // so we put this code here to end up with the same default configuration // as the original 2-arg build_command signature: @@ -110,19 +99,15 @@ bool cmBuildCommand configuration = "Release"; } - // If null/empty PROJECT_NAME argument, use the Makefile's project name: - // - if(!project_name || !*project_name) + if(project_name && *project_name) { - project_name = this->Makefile->GetProjectName(); + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, + "Ignoring PROJECT_NAME option because it has no effect."); } - // If null/empty TARGET argument, GenerateBuildCommand omits any mention - // of a target name on the build command line... - // std::string makecommand = this->Makefile->GetLocalGenerator() - ->GetGlobalGenerator()->GenerateBuildCommand - (makeprogram, project_name, 0, 0, target, configuration, true, false); + ->GetGlobalGenerator()->GenerateCMakeBuildCommand(target, configuration, + 0, true); this->Makefile->AddDefinition(variable, makecommand.c_str()); @@ -142,7 +127,6 @@ bool cmBuildCommand const char* define = args[0].c_str(); const char* cacheValue = this->Makefile->GetDefinition(define); - std::string makeprogram = args[1]; std::string configType = "Release"; const char* cfg = getenv("CMAKE_CONFIG_TYPE"); @@ -152,9 +136,8 @@ bool cmBuildCommand } std::string makecommand = this->Makefile->GetLocalGenerator() - ->GetGlobalGenerator()->GenerateBuildCommand - (makeprogram.c_str(), this->Makefile->GetProjectName(), 0, 0, - 0, configType.c_str(), true, false); + ->GetGlobalGenerator()->GenerateCMakeBuildCommand(0, configType.c_str(), + 0, true); if(cacheValue) { diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index b76b943..65a7118 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -88,6 +88,26 @@ bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts) return false; } +std::string cmGlobalGenerator::SelectMakeProgram(const char* makeProgram, + std::string makeDefault) +{ + if(cmSystemTools::IsOff(makeProgram)) + { + makeProgram = + this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); + if(cmSystemTools::IsOff(makeProgram)) + { + makeProgram = makeDefault.c_str(); + } + if(cmSystemTools::IsOff(makeProgram) && + !(makeProgram && *makeProgram)) + { + makeProgram = "CMAKE_MAKE_PROGRAM-NOTFOUND"; + } + } + return makeProgram; +} + void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, cmMakefile *mf, bool optional) @@ -1542,15 +1562,6 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir, this->FirstTimeProgress); } - std::string makeCommand = this->CMakeInstance-> - GetCacheManager()->GetCacheValue("CMAKE_MAKE_PROGRAM"); - if(makeCommand.size() == 0) - { - cmSystemTools::Error( - "Generator cannot find the appropriate make command."); - return 1; - } - std::string newTarget; if (target && strlen(target)) { @@ -1570,45 +1581,16 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir, const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); return this->Build(srcdir,bindir,projectName, newTarget.c_str(), - output,makeCommand.c_str(),config,false,fast, + output,0,config,false,fast, this->TryCompileTimeout); } -std::string cmGlobalGenerator -::GenerateBuildCommand(const char* makeProgram, const char *projectName, - const char *projectDir, const char* additionalOptions, - const char *targetName, const char* config, - bool ignoreErrors, bool) +void cmGlobalGenerator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, const char*, const char*, const char*, + const char*, const char*, bool, std::vector<std::string> const&) { - // Project name & dir and config are not used yet. - (void)projectName; - (void)projectDir; - (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 ) - { - makeCommand += " "; - makeCommand += targetName; - } - return makeCommand; + makeCommand.push_back( + "cmGlobalGenerator::GenerateBuildCommand not implemented"); } int cmGlobalGenerator::Build( @@ -1620,7 +1602,6 @@ int cmGlobalGenerator::Build( bool clean, bool fast, double timeout, cmSystemTools::OutputOption outputflag, - const char* extraOptions, std::vector<std::string> const& nativeOptions) { /** @@ -1648,17 +1629,17 @@ int cmGlobalGenerator::Build( // should we do a clean first? if (clean) { - std::string cleanCommand = - this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, - 0, "clean", config, false, fast); + std::vector<std::string> cleanCommand; + this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName, + bindir, "clean", config, fast); if(output) { *output += "\nRun Clean Command:"; - *output += cleanCommand; + *output += cmSystemTools::PrintSingleCommand(cleanCommand); *output += "\n"; } - if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), outputPtr, + if (!cmSystemTools::RunSingleCommand(cleanCommand, outputPtr, &retVal, 0, outputflag, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); @@ -1680,37 +1661,29 @@ int cmGlobalGenerator::Build( } // now build - std::string makeCommand = - this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, - extraOptions, target, - config, false, fast); + std::vector<std::string> makeCommand; + this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, + bindir, target, config, fast, nativeOptions); + std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand); if(output) { *output += "\nRun Build Command:"; - *output += makeCommand; + *output += makeCommandStr; *output += "\n"; } - std::vector<cmStdString> command = - cmSystemTools::ParseArguments(makeCommand.c_str()); - for(std::vector<std::string>::const_iterator ni = nativeOptions.begin(); - ni != nativeOptions.end(); ++ni) - { - command.push_back(*ni); - } - - if (!cmSystemTools::RunSingleCommand(command, outputPtr, + if (!cmSystemTools::RunSingleCommand(makeCommand, outputPtr, &retVal, 0, outputflag, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::Error ("Generator: execution of make failed. Make command was: ", - makeCommand.c_str()); + makeCommandStr.c_str()); if (output) { *output += *outputPtr; *output += "\nGenerator: execution of make failed. Make command was: " - + makeCommand + "\n"; + + makeCommandStr + "\n"; } // return to the original directory @@ -1735,6 +1708,46 @@ int cmGlobalGenerator::Build( return retVal; } +//---------------------------------------------------------------------------- +std::string cmGlobalGenerator::GenerateCMakeBuildCommand( + const char* target, const char* config, const char* native, + bool ignoreErrors) +{ + std::string makeCommand = cmSystemTools::GetCMakeCommand(); + makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str()); + makeCommand += " --build ."; + if(config && *config) + { + makeCommand += " --config \""; + makeCommand += config; + makeCommand += "\""; + } + if(target && *target) + { + makeCommand += " --target \""; + makeCommand += target; + makeCommand += "\""; + } + const char* sep = " -- "; + if(ignoreErrors) + { + const char* iflag = this->GetBuildIgnoreErrorsFlag(); + if(iflag && *iflag) + { + makeCommand += sep; + makeCommand += iflag; + sep = " "; + } + } + if(native && *native) + { + makeCommand += sep; + makeCommand += native; + } + return makeCommand; +} + +//---------------------------------------------------------------------------- void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg) { this->LocalGenerators.push_back(lg); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 8aebae8..ae139ed 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -123,17 +123,22 @@ public: bool clean, bool fast, double timeout, cmSystemTools::OutputOption outputflag=cmSystemTools::OUTPUT_NONE, - const char* extraOptions = 0, std::vector<std::string> const& nativeOptions = std::vector<std::string>()); - virtual std::string GenerateBuildCommand( + virtual void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const char* makeProgram, const char *projectName, const char *projectDir, - const char* additionalOptions, - const char *targetName, const char* config, - bool ignoreErrors, bool fast); + const char *targetName, const char* config, bool fast, + std::vector<std::string> const& makeOptions = std::vector<std::string>() + ); + /** Generate a "cmake --build" call for a given target and config. */ + std::string GenerateCMakeBuildCommand(const char* target, + const char* config, + const char* native, + bool ignoreErrors); ///! Set the CMake instance void SetCMakeInstance(cmake *cm); @@ -198,7 +203,7 @@ public: /* * Determine what program to use for building the project. */ - void FindMakeProgram(cmMakefile*); + virtual void FindMakeProgram(cmMakefile*); ///! Find a target by name by searching the local generators. cmTarget* FindTarget(const char* project, const char* name, @@ -331,6 +336,8 @@ protected: typedef std::vector<std::pair<cmQtAutoGenerators, cmTarget*> > AutogensType; void CreateQtAutoGeneratorsTargets(AutogensType& autogens); + std::string SelectMakeProgram(const char* makeProgram, + std::string makeDefault = ""); // Fill the ProjectMap, this must be called after LocalGenerators // has been populated. @@ -424,6 +431,8 @@ private: void ClearGeneratorMembers(); + virtual const char* GetBuildIgnoreErrorsFlag() const { return 0; } + // Cache directory content and target files to be built. struct DirectoryContent: public std::set<cmStdString> { diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx index e7c857e..273d4bb 100644 --- a/Source/cmGlobalKdevelopGenerator.cxx +++ b/Source/cmGlobalKdevelopGenerator.cxx @@ -462,7 +462,7 @@ void cmGlobalKdevelopGenerator " <numberofjobs>1</numberofjobs>\n" " <dontact>false</dontact>\n" " <makebin>" << this->GlobalGenerator->GetLocalGenerators()[0]-> - GetMakefile()->GetRequiredDefinition("CMAKE_BUILD_TOOL") + GetMakefile()->GetRequiredDefinition("CMAKE_MAKE_PROGRAM") << " </makebin>\n" " <selectedenvironment>default</selectedenvironment>\n" " <environments>\n" diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index e938065..77571b2 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -549,47 +549,34 @@ bool cmGlobalNinjaGenerator::UsingMinGW = false; // cmGlobalXCodeGenerator // Called by: // cmGlobalGenerator::Build() -std::string cmGlobalNinjaGenerator -::GenerateBuildCommand(const char* makeProgram, - const char* projectName, - const char* projectDir, - const char* additionalOptions, +void cmGlobalNinjaGenerator +::GenerateBuildCommand(std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* /*projectName*/, + const char* /*projectDir*/, const char* targetName, - const char* config, - bool ignoreErrors, - bool fast) + const char* /*config*/, + bool /*fast*/, + std::vector<std::string> const& makeOptions) { - // Project name & dir and config are not used yet. - (void)projectName; - (void)projectDir; - (void)config; - // Ninja does not have -i equivalent option yet. - (void)ignoreErrors; - // We do not handle fast build yet. - (void)fast; - - std::string makeCommand = - cmSystemTools::ConvertToUnixOutputPath(makeProgram); - - if(additionalOptions) - { - makeCommand += " "; - makeCommand += additionalOptions; - } - if(targetName) + makeCommand.push_back( + this->SelectMakeProgram(makeProgram) + ); + + makeCommand.insert(makeCommand.end(), + makeOptions.begin(), makeOptions.end()); + if(targetName && *targetName) { if(strcmp(targetName, "clean") == 0) { - makeCommand += " -t clean"; + makeCommand.push_back("-t"); + makeCommand.push_back("clean"); } else { - makeCommand += " "; - makeCommand += targetName; + makeCommand.push_back(targetName); } } - - return makeCommand; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index e9c8684..4fd0d5c 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -191,14 +191,16 @@ public: bool optional); /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand() - virtual std::string GenerateBuildCommand(const char* makeProgram, - const char* projectName, - const char* projectDir, - const char* additionalOptions, - const char* targetName, - const char* config, - bool ignoreErrors, - bool fast); + virtual void GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* projectDir, + const char* targetName, + const char* config, + bool fast, + std::vector<std::string> const& makeOptions = std::vector<std::string>() + ); // Setup target names virtual const char* GetAllTargetName() const { return "all"; } diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index cfd93c2..e1af2f9 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -555,36 +555,29 @@ cmGlobalUnixMakefileGenerator3 this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true); } - -std::string cmGlobalUnixMakefileGenerator3 -::GenerateBuildCommand(const char* makeProgram, const char *projectName, - const char *projectDir, const char* additionalOptions, - const char *targetName, const char* config, - bool ignoreErrors, bool fast) +//---------------------------------------------------------------------------- +void cmGlobalUnixMakefileGenerator3 +::GenerateBuildCommand(std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* /*projectName*/, + const char* /*projectDir*/, + const char* targetName, + const char* /*config*/, + bool fast, + std::vector<std::string> const& makeOptions) { - // Project name & dir and config are not used yet. - (void)projectName; - (void)projectDir; - (void)config; - - std::string makeCommand = - cmSystemTools::ConvertToUnixOutputPath(makeProgram); + makeCommand.push_back( + this->SelectMakeProgram(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; + makeCommand.push_back("/NOLOGO"); } + makeCommand.insert(makeCommand.end(), + makeOptions.begin(), makeOptions.end()); if ( targetName && strlen(targetName)) { cmLocalUnixMakefileGenerator3 *lg; @@ -605,22 +598,19 @@ std::string cmGlobalUnixMakefileGenerator3 lg->GetMakefile()->MakeStartDirectoriesCurrent(); } - makeCommand += " \""; std::string tname = targetName; if(fast) { tname += "/fast"; } - tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT, - cmLocalGenerator::MAKEFILE); - makeCommand += tname.c_str(); - makeCommand += "\""; + tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT); + cmSystemTools::ConvertToOutputSlashes(tname); + makeCommand.push_back(tname); if (!this->LocalGenerators.size()) { delete lg; } } - return makeCommand; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 608f643..284f5d1 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -107,12 +107,16 @@ public: std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; } // change the build command for speed - virtual std::string GenerateBuildCommand - (const char* makeProgram, - const char *projectName, const char *projectDir, - const char* additionalOptions, - const char *targetName, - const char* config, bool ignoreErrors, bool fast); + virtual void GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* projectDir, + const char* targetName, + const char* config, + bool fast, + std::vector<std::string> const& makeOptions = std::vector<std::string>() + ); /** Record per-target progress information. */ void RecordTargetProgress(cmMakefileTargetGenerator* tg); @@ -188,6 +192,7 @@ protected: cmGeneratedFileStream *CommandDatabase; private: + virtual const char* GetBuildIgnoreErrorsFlag() const { return "-i"; } virtual std::string GetEditCacheCommand() const; virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; }; diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 5e29fd7..29401c6 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -92,12 +92,12 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator( : cmGlobalVisualStudio8Generator(name, platformName, additionalPlatformDefinition) { - this->FindMakeProgramFile = "CMakeVS10FindMake.cmake"; std::string vc10Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0\\Setup\\VC;" "ProductDir", vc10Express, cmSystemTools::KeyWOW64_32); this->MasmEnabled = false; + this->MSBuildCommandInitialized = false; } //---------------------------------------------------------------------------- @@ -255,50 +255,121 @@ std::string cmGlobalVisualStudio10Generator::GetUserMacrosRegKeyBase() return "Software\\Microsoft\\VisualStudio\\10.0\\vsmacros"; } +//---------------------------------------------------------------------------- +std::string const& cmGlobalVisualStudio10Generator::GetMSBuildCommand() +{ + if(!this->MSBuildCommandInitialized) + { + this->MSBuildCommandInitialized = true; + this->MSBuildCommand = this->FindMSBuildCommand(); + } + return this->MSBuildCommand; +} -std::string cmGlobalVisualStudio10Generator -::GenerateBuildCommand(const char* makeProgram, - const char *projectName, const char *projectDir, - const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors, bool fast) +//---------------------------------------------------------------------------- +std::string cmGlobalVisualStudio10Generator::FindMSBuildCommand() { - // now build the test - std::string makeCommand - = cmSystemTools::ConvertToOutputPath(makeProgram); - std::string lowerCaseCommand = makeCommand; - cmSystemTools::LowerCase(lowerCaseCommand); - - // If makeProgram is devenv, parent class knows how to generate command: - if (lowerCaseCommand.find("devenv") != std::string::npos || - lowerCaseCommand.find("VCExpress") != std::string::npos) + std::string msbuild; + std::string mskey = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\"; + mskey += this->GetToolsVersion(); + mskey += ";MSBuildToolsPath"; + if(cmSystemTools::ReadRegistryValue(mskey.c_str(), msbuild, + cmSystemTools::KeyWOW64_32)) { - return cmGlobalVisualStudio7Generator::GenerateBuildCommand(makeProgram, - projectName, projectDir, additionalOptions, targetName, config, - ignoreErrors, fast); + cmSystemTools::ConvertToUnixSlashes(msbuild); + msbuild += "/"; } + msbuild += "MSBuild.exe"; + return msbuild; +} - // Otherwise, assume MSBuild command line, and construct accordingly. +//---------------------------------------------------------------------------- +std::string cmGlobalVisualStudio10Generator::FindDevEnvCommand() +{ + if(this->ExpressEdition) + { + // Visual Studio Express >= 10 do not have "devenv.com" or + // "VCExpress.exe" that we can use to build reliably. + // Tell the caller it needs to use MSBuild instead. + return ""; + } + // Skip over the cmGlobalVisualStudio8Generator implementation because + // we expect a real devenv and do not want to look for VCExpress. + return this->cmGlobalVisualStudio71Generator::FindDevEnvCommand(); +} - // if there are spaces in the makeCommand, assume a full path - // and convert it to a path with no spaces in it as the - // RunSingleCommand does not like spaces - if(makeCommand.find(' ') != std::string::npos) +//---------------------------------------------------------------------------- +void cmGlobalVisualStudio10Generator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* projectDir, + const char* targetName, + const char* config, + bool fast, + std::vector<std::string> const& makeOptions) +{ + // Select the caller- or user-preferred make program, else MSBuild. + std::string makeProgramSelected = + this->SelectMakeProgram(makeProgram, this->GetMSBuildCommand()); + + // Check if the caller explicitly requested a devenv tool. + std::string makeProgramLower = makeProgramSelected; + cmSystemTools::LowerCase(makeProgramLower); + bool useDevEnv = + (makeProgramLower.find("devenv") != std::string::npos || + makeProgramLower.find("vcexpress") != std::string::npos); + + // MSBuild is preferred (and required for VS Express), but if the .sln has + // an Intel Fortran .vfproj then we have to use devenv. Parse it to find out. + cmSlnData slnData; + { + std::string slnFile; + if(projectDir && *projectDir) + { + slnFile = projectDir; + slnFile += "/"; + } + slnFile += projectName; + slnFile += ".sln"; + cmVisualStudioSlnParser parser; + if(parser.ParseFile(slnFile, slnData, + cmVisualStudioSlnParser::DataGroupProjects)) + { + std::vector<cmSlnProjectEntry> slnProjects = slnData.GetProjects(); + for(std::vector<cmSlnProjectEntry>::iterator i = slnProjects.begin(); + !useDevEnv && i != slnProjects.end(); ++i) + { + std::string proj = i->GetRelativePath(); + if(proj.size() > 7 && + proj.substr(proj.size()-7) == ".vfproj") + { + useDevEnv = true; + } + } + } + } + if(useDevEnv) { - cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + // Use devenv to build solutions containing Intel Fortran projects. + cmGlobalVisualStudio7Generator::GenerateBuildCommand( + makeCommand, makeProgram, projectName, projectDir, + targetName, config, fast, makeOptions); + return; } + + makeCommand.push_back(makeProgramSelected); + // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD if(!targetName || strlen(targetName) == 0) { targetName = "ALL_BUILD"; } - bool clean = false; if ( targetName && strcmp(targetName, "clean") == 0 ) { - clean = true; - makeCommand += " "; - makeCommand += projectName; - makeCommand += ".sln "; - makeCommand += "/t:Clean "; + makeCommand.push_back(std::string(projectName)+".sln"); + makeCommand.push_back("/t:Clean"); } else { @@ -307,51 +378,29 @@ std::string cmGlobalVisualStudio10Generator if (targetProject.find('/') == std::string::npos) { // it might be in a subdir - cmVisualStudioSlnParser parser; - cmSlnData slnData; - std::string slnFile; - if (projectDir && *projectDir) - { - slnFile = projectDir; - slnFile += '/'; - slnFile += projectName; - } - else + if (cmSlnProjectEntry const* proj = + slnData.GetProjectByName(targetName)) { - slnFile = projectName; - } - if (parser.ParseFile(slnFile + ".sln", slnData, - cmVisualStudioSlnParser::DataGroupProjects)) - { - if (cmSlnProjectEntry const* proj = - slnData.GetProjectByName(targetName)) - { - targetProject = proj->GetRelativePath(); - cmSystemTools::ConvertToUnixSlashes(targetProject); - } + targetProject = proj->GetRelativePath(); + cmSystemTools::ConvertToUnixSlashes(targetProject); } } - makeCommand += " "; - makeCommand += targetProject; - makeCommand += " "; + makeCommand.push_back(targetProject); } - makeCommand += "/p:Configuration="; + std::string configArg = "/p:Configuration="; if(config && strlen(config)) { - makeCommand += config; + configArg += config; } else { - makeCommand += "Debug"; - } - makeCommand += " /p:VisualStudioVersion="; - makeCommand += this->GetIDEVersion(); - if ( additionalOptions ) - { - makeCommand += " "; - makeCommand += additionalOptions; + configArg += "Debug"; } - return makeCommand; + makeCommand.push_back(configArg); + makeCommand.push_back(std::string("/p:VisualStudioVersion=")+ + this->GetIDEVersion()); + makeCommand.insert(makeCommand.end(), + makeOptions.begin(), makeOptions.end()); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index e9e7cb1..66440ea 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -32,11 +32,16 @@ public: virtual bool SetGeneratorToolset(std::string const& ts); - virtual std::string - GenerateBuildCommand(const char* makeProgram, - const char *projectName, const char *projectDir, - const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors, bool); + virtual void GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* projectDir, + const char* targetName, + const char* config, + bool fast, + std::vector<std::string> const& makeOptions = std::vector<std::string>() + ); virtual void AddPlatformDefinitions(cmMakefile* mf); @@ -89,6 +94,8 @@ public: protected: virtual const char* GetIDEVersion() { return "10.0"; } + std::string const& GetMSBuildCommand(); + std::string PlatformToolset; bool ExpressEdition; bool MasmEnabled; @@ -106,5 +113,11 @@ private: std::string SourceRel; }; LongestSourcePath LongestSource; + + std::string MSBuildCommand; + bool MSBuildCommandInitialized; + virtual std::string FindMSBuildCommand(); + virtual std::string FindDevEnvCommand(); + virtual std::string GetVSMakeProgram() { return this->GetMSBuildCommand(); } }; #endif diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index d968c6d..f1d7312 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -112,7 +112,6 @@ cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator( : cmGlobalVisualStudio10Generator(name, platformName, additionalPlatformDefinition) { - this->FindMakeProgramFile = "CMakeVS11FindMake.cmake"; std::string vc11Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;" diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index f3806df..edd5567 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -87,7 +87,6 @@ cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator( : cmGlobalVisualStudio11Generator(name, platformName, additionalPlatformDefinition) { - this->FindMakeProgramFile = "CMakeVS12FindMake.cmake"; std::string vc12Express; this->ExpressEdition = cmSystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\12.0\\Setup\\VC;" diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 4006df4..8651da7 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -32,7 +32,7 @@ std::string GetVS6TargetName(const std::string& targetName) cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator() { - this->FindMakeProgramFile = "CMakeVS6FindMake.cmake"; + this->MSDevCommandInitialized = false; } void cmGlobalVisualStudio6Generator @@ -77,52 +77,53 @@ void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf) } } -std::string cmGlobalVisualStudio6Generator -::GenerateBuildCommand(const char* makeProgram, - const char *projectName, - const char *projectDir, - const char* additionalOptions, - const char *targetName, - const char* config, - bool ignoreErrors, - bool) +//---------------------------------------------------------------------------- +std::string const& cmGlobalVisualStudio6Generator::GetMSDevCommand() { - // Visual studio 6 doesn't need project dir - (void) projectDir; - // Ingoring errors is not implemented in visual studio 6 - (void) ignoreErrors; - - // now build the test - std::vector<std::string> mp; - mp.push_back("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio" - "\\6.0\\Setup;VsCommonDir]/MSDev98/Bin"); - cmSystemTools::ExpandRegistryValues(mp[0]); - std::string originalCommand = makeProgram; - std::string makeCommand = - cmSystemTools::FindProgram(makeProgram, mp); - if(makeCommand.size() == 0) + if(!this->MSDevCommandInitialized) { - std::string e = "Generator cannot find Visual Studio 6 msdev program \""; - e += originalCommand; - e += "\" specified by CMAKE_MAKE_PROGRAM cache entry. "; - e += "Please fix the setting."; - cmSystemTools::Error(e.c_str()); - return ""; + this->MSDevCommandInitialized = true; + this->MSDevCommand = this->FindMSDevCommand(); } - makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str()); + return this->MSDevCommand; +} - // if there are spaces in the makeCommand, assume a full path - // and convert it to a path with no spaces in it as the - // RunSingleCommand does not like spaces -#if defined(_WIN32) && !defined(__CYGWIN__) - if(makeCommand.find(' ') != std::string::npos) +//---------------------------------------------------------------------------- +std::string cmGlobalVisualStudio6Generator::FindMSDevCommand() +{ + std::string vscmd; + std::string vskey = this->GetRegistryBase() + "\\Setup;VsCommonDir"; + if(cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd, + cmSystemTools::KeyWOW64_32)) { - cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + cmSystemTools::ConvertToUnixSlashes(vscmd); + vscmd += "/MSDev98/Bin/"; } -#endif - makeCommand += " "; - makeCommand += projectName; - makeCommand += ".dsw /MAKE \""; + vscmd += "msdev.exe"; + return vscmd; +} + +//---------------------------------------------------------------------------- +void +cmGlobalVisualStudio6Generator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* /*projectDir*/, + const char* targetName, + const char* config, + bool /*fast*/, + std::vector<std::string> const& makeOptions + ) +{ + // now build the test + makeCommand.push_back( + this->SelectMakeProgram(makeProgram, this->GetMSDevCommand()) + ); + + makeCommand.push_back(std::string(projectName)+".dsw"); + makeCommand.push_back("/MAKE"); + std::string targetArg; bool clean = false; if ( targetName && strcmp(targetName, "clean") == 0 ) { @@ -131,35 +132,32 @@ std::string cmGlobalVisualStudio6Generator } if (targetName && strlen(targetName)) { - makeCommand += targetName; + targetArg += targetName; } else { - makeCommand += "ALL_BUILD"; + targetArg += "ALL_BUILD"; } - makeCommand += " - "; + targetArg += " - "; if(config && strlen(config)) { - makeCommand += config; + targetArg += config; } else { - makeCommand += "Debug"; + targetArg += "Debug"; } + makeCommand.push_back(targetArg); if(clean) { - makeCommand += "\" /CLEAN"; + makeCommand.push_back("/CLEAN"); } else { - makeCommand += "\" /BUILD"; - } - if ( additionalOptions ) - { - makeCommand += " "; - makeCommand += additionalOptions; + makeCommand.push_back("/BUILD"); } - return makeCommand; + makeCommand.insert(makeCommand.end(), + makeOptions.begin(), makeOptions.end()); } ///! Create a local generator appropriate to this Global Generator diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h index 6bd39ca..8fe5792 100644 --- a/Source/cmGlobalVisualStudio6Generator.h +++ b/Source/cmGlobalVisualStudio6Generator.h @@ -52,14 +52,16 @@ public: * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. */ - virtual std::string GenerateBuildCommand(const char* makeProgram, - const char *projectName, - const char *projectDir, - const char* additionalOptions, - const char *targetName, - const char* config, - bool ignoreErrors, - bool fast); + virtual void GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* projectDir, + const char* targetName, + const char* config, + bool fast, + std::vector<std::string> const& makeOptions = std::vector<std::string>() + ); /** * Generate the all required files for building this project/tree. This @@ -90,6 +92,7 @@ public: protected: virtual const char* GetIDEVersion() { return "6.0"; } private: + virtual std::string GetVSMakeProgram() { return this->GetMSDevCommand(); } void GenerateConfigurations(cmMakefile* mf); void WriteDSWFile(std::ostream& fout); void WriteDSWHeader(std::ostream& fout); @@ -100,6 +103,10 @@ private: const std::set<cmStdString>& dependencies); void WriteDSWFooter(std::ostream& fout); virtual std::string WriteUtilityDepend(cmTarget* target); + std::string MSDevCommand; + bool MSDevCommandInitialized; + std::string const& GetMSDevCommand(); + std::string FindMSDevCommand(); }; #endif diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 2643719..61d3c4c 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -19,7 +19,6 @@ cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator( const char* platformName) : cmGlobalVisualStudio7Generator(platformName) { - this->FindMakeProgramFile = "CMakeVS71FindMake.cmake"; this->ProjectConfigurationSectionName = "ProjectConfiguration"; } diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index d476c24..3d939f3 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -20,8 +20,8 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator( const char* platformName) { - this->FindMakeProgramFile = "CMakeVS7FindMake.cmake"; this->IntelProjectVersion = 0; + this->DevEnvCommandInitialized = false; if (!platformName) { @@ -110,35 +110,60 @@ void cmGlobalVisualStudio7Generator } -std::string cmGlobalVisualStudio7Generator -::GenerateBuildCommand(const char* makeProgram, - const char *projectName, const char *projectDir, - const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors, bool) +//---------------------------------------------------------------------------- +std::string const& cmGlobalVisualStudio7Generator::GetDevEnvCommand() +{ + if(!this->DevEnvCommandInitialized) + { + this->DevEnvCommandInitialized = true; + this->DevEnvCommand = this->FindDevEnvCommand(); + } + return this->DevEnvCommand; +} + +//---------------------------------------------------------------------------- +std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand() { - // Visual studio 7 doesn't need project dir - (void) projectDir; - // Ingoring errors is not implemented in visual studio 6 - (void) ignoreErrors; + std::string vscmd; + std::string vskey = this->GetRegistryBase() + ";InstallDir"; + if(cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd, + cmSystemTools::KeyWOW64_32)) + { + cmSystemTools::ConvertToUnixSlashes(vscmd); + vscmd += "/"; + } + vscmd += "devenv.com"; + return vscmd; +} - // now build the test - std::string makeCommand = - cmSystemTools::ConvertToOutputPath(makeProgram); - std::string lowerCaseCommand = makeCommand; - cmSystemTools::LowerCase(lowerCaseCommand); +//---------------------------------------------------------------------------- +void cmGlobalVisualStudio7Generator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* /*projectDir*/, + const char* targetName, + const char* config, + bool /*fast*/, + std::vector<std::string> const& makeOptions) +{ + // Select the caller- or user-preferred make program, else devenv. + std::string makeProgramSelected = + this->SelectMakeProgram(makeProgram, this->GetDevEnvCommand()); - // if there are spaces in the makeCommand, assume a full path - // and convert it to a path with no spaces in it as the - // RunSingleCommand does not like spaces -#if defined(_WIN32) && !defined(__CYGWIN__) - if(makeCommand.find(' ') != std::string::npos) + // Ignore the above preference if it is msbuild. + // Assume any other value is either a devenv or + // command-line compatible with devenv. + std::string makeProgramLower = makeProgramSelected; + cmSystemTools::LowerCase(makeProgramLower); + if(makeProgramLower.find("msbuild") != std::string::npos) { - cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + makeProgramSelected = this->GetDevEnvCommand(); } -#endif - makeCommand += " "; - makeCommand += projectName; - makeCommand += ".sln "; + + makeCommand.push_back(makeProgramSelected); + + makeCommand.push_back(std::string(projectName) + ".sln"); bool clean = false; if ( targetName && strcmp(targetName, "clean") == 0 ) { @@ -147,37 +172,33 @@ std::string cmGlobalVisualStudio7Generator } if(clean) { - makeCommand += "/clean "; + makeCommand.push_back("/clean"); } else { - makeCommand += "/build "; + makeCommand.push_back("/build"); } if(config && strlen(config)) { - makeCommand += config; + makeCommand.push_back(config); } else { - makeCommand += "Debug"; + makeCommand.push_back("Debug"); } - makeCommand += " /project "; + makeCommand.push_back("/project"); if (targetName && strlen(targetName)) { - makeCommand += targetName; + makeCommand.push_back(targetName); } else { - makeCommand += "ALL_BUILD"; - } - if ( additionalOptions ) - { - makeCommand += " "; - makeCommand += additionalOptions; + makeCommand.push_back("ALL_BUILD"); } - return makeCommand; + makeCommand.insert(makeCommand.end(), + makeOptions.begin(), makeOptions.end()); } ///! Create a local generator appropriate to this Global Generator diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 66dc443..c7b0081 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -60,14 +60,16 @@ public: * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ - virtual std::string GenerateBuildCommand(const char* makeProgram, - const char *projectName, - const char *projectDir, - const char* additionalOptions, - const char *targetName, - const char* config, - bool ignoreErrors, - bool fast); + virtual void GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* projectDir, + const char* targetName, + const char* config, + bool fast, + std::vector<std::string> const& makeOptions = std::vector<std::string>() + ); /** * Generate the all required files for building this project/tree. This @@ -108,6 +110,9 @@ public: protected: virtual const char* GetIDEVersion() { return "7.0"; } + std::string const& GetDevEnvCommand(); + virtual std::string FindDevEnvCommand(); + static cmIDEFlagTable const* GetExtraFlagTableVS7(); virtual void OutputSLNFile(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); @@ -166,6 +171,9 @@ protected: private: char* IntelProjectVersion; + std::string DevEnvCommand; + bool DevEnvCommandInitialized; + virtual std::string GetVSMakeProgram() { return this->GetDevEnvCommand(); } }; #define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK" diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index b9bc1ae..69b0a7a 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -94,7 +94,6 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator( const char* additionalPlatformDefinition) : cmGlobalVisualStudio71Generator(platformName) { - this->FindMakeProgramFile = "CMakeVS8FindMake.cmake"; this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms"; this->Name = name; @@ -105,6 +104,26 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator( } //---------------------------------------------------------------------------- +std::string cmGlobalVisualStudio8Generator::FindDevEnvCommand() +{ + // First look for VCExpress. + std::string vsxcmd; + std::string vsxkey = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\"; + vsxkey += this->GetIDEVersion(); + vsxkey += ";InstallDir"; + if(cmSystemTools::ReadRegistryValue(vsxkey.c_str(), vsxcmd, + cmSystemTools::KeyWOW64_32)) + { + cmSystemTools::ConvertToUnixSlashes(vsxcmd); + vsxcmd += "/VCExpress.exe"; + return vsxcmd; + } + // Now look for devenv. + return this->cmGlobalVisualStudio71Generator::FindDevEnvCommand(); +} + +//---------------------------------------------------------------------------- ///! Create a local generator appropriate to this Global Generator cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator() { diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 2376f8a..ad01a24 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -69,6 +69,8 @@ public: protected: virtual const char* GetIDEVersion() { return "8.0"; } + virtual std::string FindDevEnvCommand(); + virtual bool VSLinksDependencies() const { return false; } bool AddCheckTarget(); diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index aadf982..ccc27ad 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -101,7 +101,6 @@ cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator( : cmGlobalVisualStudio8Generator(name, platformName, additionalPlatformDefinition) { - this->FindMakeProgramFile = "CMakeVS9FindMake.cmake"; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index af80070..7afcfa7 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -500,6 +500,19 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) } //---------------------------------------------------------------------------- +void cmGlobalVisualStudioGenerator::FindMakeProgram(cmMakefile* mf) +{ + // Visual Studio generators know how to lookup their build tool + // directly instead of needing a helper module to do it, so we + // do not actually need to put CMAKE_MAKE_PROGRAM into the cache. + if(cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) + { + mf->AddDefinition("CMAKE_MAKE_PROGRAM", + this->GetVSMakeProgram().c_str()); + } +} + +//---------------------------------------------------------------------------- void cmGlobalVisualStudioGenerator::AddPlatformDefinitions(cmMakefile* mf) { if(this->AdditionalPlatformDefinition) diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index ce03a0e..da2d021 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -82,6 +82,8 @@ public: }; class OrderedTargetDependSet; + virtual void FindMakeProgram(cmMakefile*); + protected: // Does this VS version link targets to each other if there are // dependencies in the SLN file? This was done for VS versions @@ -107,6 +109,7 @@ protected: const char* AdditionalPlatformDefinition; private: + virtual std::string GetVSMakeProgram() = 0; void PrintCompilerAdvice(std::ostream&, std::string, const char*) {} void ComputeTargetObjects(cmGeneratorTarget* gt) const; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 13ed143..be0459d 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -257,39 +257,30 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const& } //---------------------------------------------------------------------------- -std::string cmGlobalXCodeGenerator -::GenerateBuildCommand(const char* makeProgram, - const char *projectName, - const char *projectDir, - const char* additionalOptions, - const char *targetName, - const char* config, - bool ignoreErrors, - bool) -{ - // Config is not used yet - (void) ignoreErrors; - (void) projectDir; - +void +cmGlobalXCodeGenerator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* /*projectDir*/, + const char* targetName, + const char* config, + bool /*fast*/, + std::vector<std::string> const& makeOptions) +{ // now build the test - if(makeProgram == 0 || !strlen(makeProgram)) - { - cmSystemTools::Error( - "Generator cannot find the appropriate make command."); - return ""; - } - std::string makeCommand = - cmSystemTools::ConvertToOutputPath(makeProgram); - std::string lowerCaseCommand = makeCommand; - cmSystemTools::LowerCase(lowerCaseCommand); + makeCommand.push_back( + this->SelectMakeProgram(makeProgram, "xcodebuild") + ); - makeCommand += " -project "; - makeCommand += projectName; - makeCommand += ".xcode"; + makeCommand.push_back("-project"); + std::string projectArg = projectName; + projectArg += ".xcode"; if(this->XcodeVersion > 20) { - makeCommand += "proj"; + projectArg += "proj"; } + makeCommand.push_back(projectArg); bool clean = false; if ( targetName && strcmp(targetName, "clean") == 0 ) @@ -299,13 +290,13 @@ std::string cmGlobalXCodeGenerator } if(clean) { - makeCommand += " clean"; + makeCommand.push_back("clean"); } else { - makeCommand += " build"; + makeCommand.push_back("build"); } - makeCommand += " -target "; + makeCommand.push_back("-target"); // if it is a null string for config don't use it if(config && *config == 0) { @@ -313,27 +304,24 @@ std::string cmGlobalXCodeGenerator } if (targetName && strlen(targetName)) { - makeCommand += targetName; + makeCommand.push_back(targetName); } else { - makeCommand += "ALL_BUILD"; + makeCommand.push_back("ALL_BUILD"); } if(this->XcodeVersion == 15) { - makeCommand += " -buildstyle Development "; + makeCommand.push_back("-buildstyle"); + makeCommand.push_back("Development"); } else { - makeCommand += " -configuration "; - makeCommand += config?config:"Debug"; - } - if ( additionalOptions ) - { - makeCommand += " "; - makeCommand += additionalOptions; + makeCommand.push_back("-configuration"); + makeCommand.push_back(config?config:"Debug"); } - return makeCommand; + makeCommand.insert(makeCommand.end(), + makeOptions.begin(), makeOptions.end()); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 97072b2..e8cbd14 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -53,14 +53,16 @@ public: * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. */ - virtual std::string GenerateBuildCommand(const char* makeProgram, - const char *projectName, - const char *projectDir, - const char* additionalOptions, - const char *targetName, - const char* config, - bool ignoreErrors, - bool fast); + virtual void GenerateBuildCommand( + std::vector<std::string>& makeCommand, + const char* makeProgram, + const char* projectName, + const char* projectDir, + const char* targetName, + const char* config, + bool fast, + std::vector<std::string> const& makeOptions = std::vector<std::string>() + ); /** * Generate the all required files for building this project/tree. This diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index f5376eb..b3dbd05 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -616,8 +616,24 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command, OutputOption outputflag , double timeout ) { + std::vector<std::string> cmd; + for(std::vector<cmStdString>::const_iterator i = command.begin(); + i != command.end(); ++i) + { + cmd.push_back(*i); + } + return cmSystemTools::RunSingleCommand(cmd, output, retVal, dir, + outputflag, timeout); +} + +bool cmSystemTools::RunSingleCommand(std::vector<std::string>const& command, + std::string* output , + int* retVal , const char* dir , + OutputOption outputflag , + double timeout ) +{ std::vector<const char*> argv; - for(std::vector<cmStdString>::const_iterator a = command.begin(); + for(std::vector<std::string>::const_iterator a = command.begin(); a != command.end(); ++a) { argv.push_back(a->c_str()); @@ -779,6 +795,23 @@ bool cmSystemTools::RunSingleCommand( dir, outputflag, timeout); } +std::string +cmSystemTools::PrintSingleCommand(std::vector<std::string> const& command) +{ + std::string commandStr; + const char* sep = ""; + for(std::vector<std::string>::const_iterator i = command.begin(); + i != command.end(); ++i) + { + commandStr += sep; + commandStr += "\""; + commandStr += *i; + commandStr += "\""; + sep = " "; + } + return commandStr; +} + bool cmSystemTools::DoesFileExistWithExtensions( const char* name, const std::vector<std::string>& headerExts) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 69f6381..4e854c8 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -228,12 +228,19 @@ public: * the command to run, and each argument to the command should * be in comand[1]...command[command.size()] */ + static bool RunSingleCommand(std::vector<std::string> const& command, + std::string* output = 0, + int* retVal = 0, const char* dir = 0, + OutputOption outputflag = OUTPUT_MERGE, + double timeout = 0.0); static bool RunSingleCommand(std::vector<cmStdString> const& command, std::string* output = 0, int* retVal = 0, const char* dir = 0, OutputOption outputflag = OUTPUT_MERGE, double timeout = 0.0); + static std::string PrintSingleCommand(std::vector<std::string> const&); + /** * Parse arguments out of a single string command */ diff --git a/Source/cmake.cxx b/Source/cmake.cxx index f0f9ef7..bf27c78 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2663,26 +2663,19 @@ int cmake::Build(const std::string& dir, this->CreateGlobalGenerator(it.GetValue())); std::string output; std::string projName; - std::string makeProgram; if(!it.Find("CMAKE_PROJECT_NAME")) { std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n"; return 1; } projName = it.GetValue(); - if(!it.Find("CMAKE_MAKE_PROGRAM")) - { - std::cerr << "Error: could not find CMAKE_MAKE_PROGRAM in Cache\n"; - return 1; - } - makeProgram = it.GetValue(); return gen->Build(0, dir.c_str(), projName.c_str(), target.c_str(), &output, - makeProgram.c_str(), + 0, config.c_str(), clean, false, 0, cmSystemTools::OUTPUT_PASSTHROUGH, - 0, nativeOptions); + nativeOptions); } void cmake::WatchUnusedCli(const char* var) diff --git a/Source/cmaketest.h.in b/Source/cmaketest.h.in deleted file mode 100644 index aada52d..0000000 --- a/Source/cmaketest.h.in +++ /dev/null @@ -1,16 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#define CMAKE_BINARY_DIR "${CMake_BINARY_DIR}" -#define EXECUTABLE_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}" -#define MAKEPROGRAM "${MAKEPROGRAM}" -#define CMAKE_GENERATOR "${CMAKE_GENERATOR}" -#define DART_MAKECOMMAND "${MAKECOMMAND}" |