Merge topic 'ImproveFindPackageModeWithTryCompile'

f15945e Use makefile->IssueMessage() for better error messages
c886e31 Improve behaviour of --find-package mode with try_run/try_compile
31f43fd Remove trailing whitespace
This commit is contained in:
David Cole 2011-09-30 15:57:20 -04:00 committed by CMake Topic Stage
commit c4e08b5533
4 changed files with 65 additions and 50 deletions

View File

@ -22,12 +22,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
// which signature were we called with ? // which signature were we called with ?
this->SrcFileSignature = false; this->SrcFileSignature = false;
unsigned int i; unsigned int i;
const char* sourceDirectory = argv[2].c_str(); const char* sourceDirectory = argv[2].c_str();
const char* projectName = 0; const char* projectName = 0;
const char* targetName = 0; const char* targetName = 0;
int extraArgs = 0; int extraArgs = 0;
// look for CMAKE_FLAGS and store them // look for CMAKE_FLAGS and store them
std::vector<std::string> cmakeFlags; std::vector<std::string> cmakeFlags;
for (i = 3; i < argv.size(); ++i) for (i = 3; i < argv.size(); ++i)
@ -37,8 +37,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
// CMAKE_FLAGS is the first argument because we need an argv[0] that // CMAKE_FLAGS is the first argument because we need an argv[0] that
// is not used, so it matches regular command line parsing which has // is not used, so it matches regular command line parsing which has
// the program name as arg 0 // the program name as arg 0
for (; i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" && for (; i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
argv[i] != "OUTPUT_VARIABLE"; argv[i] != "OUTPUT_VARIABLE";
++i) ++i)
{ {
extraArgs++; extraArgs++;
@ -73,8 +73,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
if (argv[i] == "COMPILE_DEFINITIONS") if (argv[i] == "COMPILE_DEFINITIONS")
{ {
extraArgs++; extraArgs++;
for (i = i + 1; i < argv.size() && argv[i] != "CMAKE_FLAGS" && for (i = i + 1; i < argv.size() && argv[i] != "CMAKE_FLAGS" &&
argv[i] != "OUTPUT_VARIABLE"; argv[i] != "OUTPUT_VARIABLE";
++i) ++i)
{ {
extraArgs++; extraArgs++;
@ -101,7 +101,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
break; break;
} }
} }
// do we have a srcfile signature // do we have a srcfile signature
if (argv.size() - extraArgs == 3) if (argv.size() - extraArgs == 3)
{ {
@ -133,7 +133,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
} }
// make sure the binary directory exists // make sure the binary directory exists
cmSystemTools::MakeDirectory(this->BinaryDirectory.c_str()); cmSystemTools::MakeDirectory(this->BinaryDirectory.c_str());
// do not allow recursive try Compiles // do not allow recursive try Compiles
if (this->BinaryDirectory == this->Makefile->GetHomeOutputDirectory()) if (this->BinaryDirectory == this->Makefile->GetHomeOutputDirectory())
{ {
@ -143,7 +143,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return -1; return -1;
} }
std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt"; std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
// which signature are we using? If we are using var srcfile bindir // which signature are we using? If we are using var srcfile bindir
if (this->SrcFileSignature) if (this->SrcFileSignature)
@ -151,7 +151,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
// remove any CMakeCache.txt files so we will have a clean test // remove any CMakeCache.txt files so we will have a clean test
std::string ccFile = this->BinaryDirectory + "/CMakeCache.txt"; std::string ccFile = this->BinaryDirectory + "/CMakeCache.txt";
cmSystemTools::RemoveFile(ccFile.c_str()); cmSystemTools::RemoveFile(ccFile.c_str());
// we need to create a directory and CMakeList file etc... // we need to create a directory and CMakeList file etc...
// first create the directories // first create the directories
sourceDirectory = this->BinaryDirectory.c_str(); sourceDirectory = this->BinaryDirectory.c_str();
@ -226,7 +226,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
langFlags += "_FLAGS"; langFlags += "_FLAGS";
fprintf(fout, "SET(CMAKE_VERBOSE_MAKEFILE 1)\n"); fprintf(fout, "SET(CMAKE_VERBOSE_MAKEFILE 1)\n");
fprintf(fout, "SET(CMAKE_%s_FLAGS \"", lang); fprintf(fout, "SET(CMAKE_%s_FLAGS \"", lang);
const char* flags = this->Makefile->GetDefinition(langFlags.c_str()); const char* flags = this->Makefile->GetDefinition(langFlags.c_str());
if(flags) if(flags)
{ {
fprintf(fout, " %s ", flags); fprintf(fout, " %s ", flags);
@ -247,10 +247,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
} }
/* for the TRY_COMPILEs we want to be able to specify the architecture. /* for the TRY_COMPILEs we want to be able to specify the architecture.
So the user can set CMAKE_OSX_ARCHITECTURE to i386;ppc and then set So the user can set CMAKE_OSX_ARCHITECTURE to i386;ppc and then set
CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to
have the tests run for each specific architecture. Since have the tests run for each specific architecture. Since
cmLocalGenerator doesn't allow building for "the other" cmLocalGenerator doesn't allow building for "the other"
architecture only via CMAKE_OSX_ARCHITECTURES. architecture only via CMAKE_OSX_ARCHITECTURES.
*/ */
if(this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_OSX_ARCHITECTURES")!=0) if(this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_OSX_ARCHITECTURES")!=0)
@ -286,45 +286,45 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
this->BinaryDirectory.c_str()); this->BinaryDirectory.c_str());
/* Create the actual executable. */ /* Create the actual executable. */
fprintf(fout, "ADD_EXECUTABLE(cmTryCompileExec \"%s\")\n",source.c_str()); fprintf(fout, "ADD_EXECUTABLE(cmTryCompileExec \"%s\")\n",source.c_str());
fprintf(fout, fprintf(fout,
"TARGET_LINK_LIBRARIES(cmTryCompileExec ${LINK_LIBRARIES})\n"); "TARGET_LINK_LIBRARIES(cmTryCompileExec ${LINK_LIBRARIES})\n");
fclose(fout); fclose(fout);
projectName = "CMAKE_TRY_COMPILE"; projectName = "CMAKE_TRY_COMPILE";
targetName = "cmTryCompileExec"; targetName = "cmTryCompileExec";
// if the source is not in CMakeTmp // if the source is not in CMakeTmp
if(source.find("CMakeTmp") == source.npos) if(source.find("CMakeTmp") == source.npos)
{ {
this->Makefile->AddCMakeDependFile(source.c_str()); this->Makefile->AddCMakeDependFile(source.c_str());
} }
} }
// else the srcdir bindir project target signature // else the srcdir bindir project target signature
else else
{ {
projectName = argv[3].c_str(); projectName = argv[3].c_str();
if (argv.size() - extraArgs == 5) if (argv.size() - extraArgs == 5)
{ {
targetName = argv[4].c_str(); targetName = argv[4].c_str();
} }
} }
bool erroroc = cmSystemTools::GetErrorOccuredFlag(); bool erroroc = cmSystemTools::GetErrorOccuredFlag();
cmSystemTools::ResetErrorOccuredFlag(); cmSystemTools::ResetErrorOccuredFlag();
std::string output; std::string output;
// actually do the try compile now that everything is setup // actually do the try compile now that everything is setup
int res = this->Makefile->TryCompile(sourceDirectory, int res = this->Makefile->TryCompile(sourceDirectory,
this->BinaryDirectory.c_str(), this->BinaryDirectory.c_str(),
projectName, projectName,
targetName, targetName,
this->SrcFileSignature, this->SrcFileSignature,
&cmakeFlags, &cmakeFlags,
&output); &output);
if ( erroroc ) if ( erroroc )
{ {
cmSystemTools::SetErrorOccured(); cmSystemTools::SetErrorOccured();
} }
// set the result var to the return value to indicate success or failure // set the result var to the return value to indicate success or failure
this->Makefile->AddCacheDefinition(argv[0].c_str(), this->Makefile->AddCacheDefinition(argv[0].c_str(),
(res == 0 ? "TRUE" : "FALSE"), (res == 0 ? "TRUE" : "FALSE"),
@ -335,7 +335,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
{ {
this->Makefile->AddDefinition(outputVariable.c_str(), output.c_str()); this->Makefile->AddDefinition(outputVariable.c_str(), output.c_str());
} }
if (this->SrcFileSignature) if (this->SrcFileSignature)
{ {
this->FindOutputFile(targetName); this->FindOutputFile(targetName);
@ -369,7 +369,7 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
{ {
return; return;
} }
std::string bdir = binDir; std::string bdir = binDir;
if(bdir.find("CMakeTmp") == std::string::npos) if(bdir.find("CMakeTmp") == std::string::npos)
{ {
@ -378,7 +378,7 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
"CMakeTmp:", binDir); "CMakeTmp:", binDir);
return; return;
} }
cmsys::Directory dir; cmsys::Directory dir;
dir.Load(binDir); dir.Load(binDir);
size_t fileNum; size_t fileNum;
@ -388,8 +388,8 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") && if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),"..")) strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
{ {
if(deletedFiles.find( dir.GetFile(static_cast<unsigned long>(fileNum))) if(deletedFiles.find( dir.GetFile(static_cast<unsigned long>(fileNum)))
== deletedFiles.end()) == deletedFiles.end())
{ {
deletedFiles.insert(dir.GetFile(static_cast<unsigned long>(fileNum))); deletedFiles.insert(dir.GetFile(static_cast<unsigned long>(fileNum)));

View File

@ -28,27 +28,27 @@ public:
/** /**
* This is the core code for try compile. It is here so that other * This is the core code for try compile. It is here so that other
* commands, such as TryRun can access the same logic without * commands, such as TryRun can access the same logic without
* duplication. * duplication.
*/ */
int TryCompileCode(std::vector<std::string> const& argv); int TryCompileCode(std::vector<std::string> const& argv);
/** /**
* This deletes all the files created by TryCompileCode. * This deletes all the files created by TryCompileCode.
* This way we do not have to rely on the timing and * This way we do not have to rely on the timing and
* dependencies of makefiles. * dependencies of makefiles.
*/ */
void CleanupFiles(const char* binDir); void CleanupFiles(const char* binDir);
/** /**
* This tries to find the (executable) file created by * This tries to find the (executable) file created by
TryCompileCode. The result is stored in OutputFile. If nothing is found, TryCompileCode. The result is stored in OutputFile. If nothing is found,
the error message is stored in FindErrorMessage. the error message is stored in FindErrorMessage.
*/ */
void FindOutputFile(const char* targetName); void FindOutputFile(const char* targetName);
cmTypeMacro(cmCoreTryCompile, cmCommand); cmTypeMacro(cmCoreTryCompile, cmCommand);
std::string BinaryDirectory; std::string BinaryDirectory;
std::string OutputFile; std::string OutputFile;
std::string FindErrorMessage; std::string FindErrorMessage;

View File

@ -20,6 +20,14 @@ bool cmTryCompileCommand
return false; return false;
} }
if(this->Makefile->GetCMakeInstance()->GetWorkingMode() ==
cmake::FIND_PACKAGE_MODE)
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"The TRY_COMPILE() command is not supported in --find-package mode.");
return false;
}
this->TryCompileCode(argv); this->TryCompileCode(argv);
// if They specified clean then we clean up what we can // if They specified clean then we clean up what we can
@ -32,4 +40,3 @@ bool cmTryCompileCommand
} }
return true; return true;
} }

View File

@ -22,6 +22,14 @@ bool cmTryRunCommand
return false; return false;
} }
if(this->Makefile->GetCMakeInstance()->GetWorkingMode() ==
cmake::FIND_PACKAGE_MODE)
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"The TRY_RUN() command is not supported in --find-package mode.");
return false;
}
// build an arg list for TryCompile and extract the runArgs, // build an arg list for TryCompile and extract the runArgs,
std::vector<std::string> tryCompile; std::vector<std::string> tryCompile;
@ -49,8 +57,8 @@ bool cmTryRunCommand
{ {
tryCompile.push_back(argv[i]); tryCompile.push_back(argv[i]);
} }
} }
else else
{ {
if (argv[i] == "OUTPUT_VARIABLE") if (argv[i] == "OUTPUT_VARIABLE")
{ {
@ -94,8 +102,8 @@ bool cmTryRunCommand
// although they could be used together, don't allow it, because // although they could be used together, don't allow it, because
// using OUTPUT_VARIABLE makes crosscompiling harder // using OUTPUT_VARIABLE makes crosscompiling harder
if (this->OutputVariable.size() if (this->OutputVariable.size()
&& ((this->RunOutputVariable.size()) && ((this->RunOutputVariable.size())
|| (this->CompileOutputVariable.size()))) || (this->CompileOutputVariable.size())))
{ {
cmSystemTools::Error( cmSystemTools::Error(
@ -141,8 +149,8 @@ bool cmTryRunCommand
std::string runOutputContents; std::string runOutputContents;
if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING")) if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING"))
{ {
this->DoNotRunExecutable(runArgs, this->DoNotRunExecutable(runArgs,
argv[3], argv[3],
captureRunOutput ? &runOutputContents : 0); captureRunOutput ? &runOutputContents : 0);
} }
else else
@ -153,7 +161,7 @@ bool cmTryRunCommand
// now put the output into the variables // now put the output into the variables
if(this->RunOutputVariable.size()) if(this->RunOutputVariable.size())
{ {
this->Makefile->AddDefinition(this->RunOutputVariable.c_str(), this->Makefile->AddDefinition(this->RunOutputVariable.c_str(),
runOutputContents.c_str()); runOutputContents.c_str());
} }
@ -167,7 +175,7 @@ bool cmTryRunCommand
{ {
runOutputContents = std::string(compileOutput) + runOutputContents; runOutputContents = std::string(compileOutput) + runOutputContents;
} }
this->Makefile->AddDefinition(this->OutputVariable.c_str(), this->Makefile->AddDefinition(this->OutputVariable.c_str(),
runOutputContents.c_str()); runOutputContents.c_str());
} }
} }
@ -212,9 +220,9 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
/* This is only used when cross compiling. Instead of running the /* This is only used when cross compiling. Instead of running the
executable, two cache variables are created which will hold the results executable, two cache variables are created which will hold the results
the executable would have produced. the executable would have produced.
*/ */
void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
const std::string& srcFile, const std::string& srcFile,
std::string* out std::string* out
) )
@ -249,7 +257,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
comment += "Run result of TRY_RUN(), indicates whether the executable " comment += "Run result of TRY_RUN(), indicates whether the executable "
"would have been able to run on its target platform.\n"; "would have been able to run on its target platform.\n";
comment += detailsString; comment += detailsString;
this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(), this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(),
"PLEASE_FILL_OUT-FAILED_TO_RUN", "PLEASE_FILL_OUT-FAILED_TO_RUN",
comment.c_str(), comment.c_str(),
cmCacheManager::STRING); cmCacheManager::STRING);
@ -276,7 +284,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
"would have printed on stdout and stderr on its target platform.\n"; "would have printed on stdout and stderr on its target platform.\n";
comment += detailsString; comment += detailsString;
this->Makefile->AddCacheDefinition(internalRunOutputName.c_str(), this->Makefile->AddCacheDefinition(internalRunOutputName.c_str(),
"PLEASE_FILL_OUT-NOTFOUND", "PLEASE_FILL_OUT-NOTFOUND",
comment.c_str(), comment.c_str(),
cmCacheManager::STRING); cmCacheManager::STRING);
@ -294,7 +302,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
if (error) if (error)
{ {
static bool firstTryRun = true; static bool firstTryRun = true;
std::ofstream file(resultFileName.c_str(), std::ofstream file(resultFileName.c_str(),
firstTryRun ? std::ios::out : std::ios::app); firstTryRun ? std::ios::out : std::ios::app);
if ( file ) if ( file )
{ {