Teach GenerateBuildCommand to find its own make program

Add a cmGlobalGenerator::SelectMakeProgram method to select a
caller-provided make program, the CMAKE_MAKE_PROGRAM cache entry, or a
generator-provided default.  Call it from all implementations of the
GenerateBuildCommand method with the corresponding generator's default,
if any.
This commit is contained in:
Brad King 2013-11-13 15:12:06 -05:00
parent 5f5c92b9a2
commit 123a0608df
8 changed files with 95 additions and 58 deletions

View File

@ -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)

View File

@ -334,6 +334,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.

View File

@ -559,7 +559,9 @@ void cmGlobalNinjaGenerator
bool /*fast*/,
std::vector<std::string> const& makeOptions)
{
makeCommand.push_back(makeProgram);
makeCommand.push_back(
this->SelectMakeProgram(makeProgram)
);
makeCommand.insert(makeCommand.end(),
makeOptions.begin(), makeOptions.end());

View File

@ -566,7 +566,9 @@ void cmGlobalUnixMakefileGenerator3
bool fast,
std::vector<std::string> const& makeOptions)
{
makeCommand.push_back(makeProgram);
makeCommand.push_back(
this->SelectMakeProgram(makeProgram)
);
// Since we have full control over the invocation of nmake, let us
// make it quiet.

View File

@ -311,23 +311,56 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
bool fast,
std::vector<std::string> const& makeOptions)
{
// now build the test
std::string lowerCaseCommand = makeProgram;
cmSystemTools::LowerCase(lowerCaseCommand);
// Select the caller- or user-preferred make program, else MSBuild.
std::string makeProgramSelected =
this->SelectMakeProgram(makeProgram, this->GetMSBuildCommand());
// If makeProgram is devenv, parent class knows how to generate command:
if (lowerCaseCommand.find("devenv") != std::string::npos ||
lowerCaseCommand.find("VCExpress") != std::string::npos)
// 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)
{
// Use devenv to build solutions containing Intel Fortran projects.
cmGlobalVisualStudio7Generator::GenerateBuildCommand(
makeCommand, makeProgram, projectName, projectDir,
targetName, config, fast, makeOptions);
return;
}
// Otherwise, assume MSBuild command line, and construct accordingly.
makeCommand.push_back(makeProgram);
makeCommand.push_back(makeProgramSelected);
// msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD
if(!targetName || strlen(targetName) == 0)
@ -346,28 +379,11 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
if (targetProject.find('/') == std::string::npos)
{
// it might be in a subdir
cmVisualStudioSlnParser parser;
cmSlnData slnData;
std::string slnFile;
if (projectDir && *projectDir)
if (cmSlnProjectEntry const* proj =
slnData.GetProjectByName(targetName))
{
slnFile = projectDir;
slnFile += '/';
slnFile += projectName;
}
else
{
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.push_back(targetProject);

View File

@ -118,24 +118,9 @@ cmGlobalVisualStudio6Generator::GenerateBuildCommand(
)
{
// 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 makeCommandFound =
cmSystemTools::FindProgram(makeProgram, mp);
if(makeCommandFound.size() == 0)
{
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;
}
makeCommand.push_back(makeCommandFound);
makeCommand.push_back(
this->SelectMakeProgram(makeProgram, this->GetMSDevCommand())
);
makeCommand.push_back(std::string(projectName)+".dsw");
makeCommand.push_back("/MAKE");

View File

@ -148,7 +148,21 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
bool /*fast*/,
std::vector<std::string> const& makeOptions)
{
makeCommand.push_back(makeProgram);
// Select the caller- or user-preferred make program, else devenv.
std::string makeProgramSelected =
this->SelectMakeProgram(makeProgram, this->GetDevEnvCommand());
// 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)
{
makeProgramSelected = this->GetDevEnvCommand();
}
makeCommand.push_back(makeProgramSelected);
makeCommand.push_back(std::string(projectName) + ".sln");
bool clean = false;

View File

@ -269,13 +269,9 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
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;
}
makeCommand.push_back(makeProgram);
makeCommand.push_back(
this->SelectMakeProgram(makeProgram, "xcodebuild")
);
makeCommand.push_back("-project");
std::string projectArg = projectName;