diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx index 77e061f484..eba8ca63fc 100644 --- a/Source/cmTryCompileCommand.cxx +++ b/Source/cmTryCompileCommand.cxx @@ -20,26 +20,83 @@ // cmExecutableCommand bool cmTryCompileCommand::InitialPass(std::vector const& argv) { - if(argv.size() < 4) + if(argv.size() < 3) { return false; } - - const char* sourceDirectory = argv[1].c_str(); + + // where will the binaries be stored const char* binaryDirectory = argv[2].c_str(); - const char* projectName = argv[3].c_str(); + const char* sourceDirectory = argv[1].c_str(); + const char* projectName = 0; const char* targetName = 0; - - if (argv.size() == 5) + std::string tmpString; + + // compute the binary dir when TRY_COMPILE is called with a src file + // signature + if (argv.size() == 3) { - targetName = argv[4].c_str(); + tmpString = argv[2] + "/CMakeTmp"; + binaryDirectory = tmpString.c_str(); } + // do not allow recursive try Compiles + if (!strcmp(binaryDirectory,m_Makefile->GetHomeOutputDirectory())) + { + cmSystemTools::Error("Attempt at a recursive or nested TRY_COMPILE", + binaryDirectory); + return false; + } + + // which signature are we using? If we are using var srcfile bindir + if (argv.size() == 3) + { + // remove any CMakeCache.txt files so we will have a clean test + std::string ccFile = tmpString + "/CMakeCache.txt"; + cmSystemTools::RemoveFile(ccFile.c_str()); + + // we need to create a directory and CMakeList file etc... + // first create the directories + sourceDirectory = binaryDirectory; + cmSystemTools::MakeDirectory(binaryDirectory); + + // now create a CMakeList.txt file in that directory + std::string outFileName = tmpString + "/CMakeLists.txt"; + FILE *fout = fopen(outFileName.c_str(),"w"); + if (!fout) + { + cmSystemTools::Error("Failed to create CMakeList file for ", + outFileName.c_str()); + return false; + } + fprintf(fout,"PROJECT(CMAKE_TRY_COMPILE)\n"); + fprintf(fout,"ADD_EXECUTABLE(cmTryCompileExec \"%s\")\n",argv[1].c_str()); + fclose(fout); + projectName = "CMAKE_TRY_COMPILE"; + targetName = "cmTryCompileExec"; + } + // else the srcdir bindir project target signature + else + { + projectName = argv[3].c_str(); + + if (argv.size() == 5) + { + targetName = argv[4].c_str(); + } + } + + // actually do the try compile now that everything is setup int res = m_Makefile->TryCompile(sourceDirectory, binaryDirectory, projectName, targetName); // set the result var to the return value to indicate success or failure m_Makefile->AddDefinition(argv[0].c_str(), (res == 0 ? "TRUE" : "FALSE")); + + // if we created a directory etc, then cleanup after ourselves + // Actually right now lets not clean up after ourselves, removing + // a directory is tricky and putting that code in could be a risk + return true; } diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h index 4226da153b..047fb3c7fa 100644 --- a/Source/cmTryCompileCommand.h +++ b/Source/cmTryCompileCommand.h @@ -65,7 +65,9 @@ public: "TRY_COMPILE(RESULT_VAR srcdir bindir projectName )\n" "Try compiling a program. Return the success or failure in RESULT_VAR " "If is specified then build just that target " - "otherwise the all or ALL_BUILD target is built."; + "otherwise the all or ALL_BUILD target is built.\n" + "TRY_COMPILE(RESULT_VAR srcfile bindir)\n" + "Try compiling a srcfile. Return the success or failure in RESULT_VAR."; } cmTypeMacro(cmTryCompileCommand, cmCommand);