diff options
Diffstat (limited to 'Source')
42 files changed, 764 insertions, 368 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 7808f23..ab62d2b 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -176,6 +176,8 @@ set(SRCS cmExportFileGenerator.cxx cmExportInstallFileGenerator.h cmExportInstallFileGenerator.cxx + cmExportTryCompileFileGenerator.h + cmExportTryCompileFileGenerator.cxx cmExportSet.h cmExportSet.cxx cmExportSetMap.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a03488f..6f3e6ef 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 10) -set(CMake_VERSION_TWEAK 20130220) +set(CMake_VERSION_TWEAK 20130313) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 9f86ea2..62bfa91 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -432,11 +432,14 @@ int cmCPackNSISGenerator::InitializeInternal() int retVal = 1; bool resS = cmSystemTools::RunSingleCommand(nsisCmd.c_str(), &output, &retVal, 0, this->GeneratorVerbose, 0); - cmsys::RegularExpression versionRex("v([0-9]+.[0-9]+)"); - if ( !resS || retVal || !versionRex.find(output)) + cmsys::RegularExpression versionRexCVS("v(.*)\\.cvs"); + if ( !resS || retVal || + (!versionRex.find(output) && !versionRexCVS.find(output)) + ) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + const char* topDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + std::string tmpFile = topDir ? topDir : "."; tmpFile += "/NSISOutput.log"; cmGeneratedFileStream ofs(tmpFile.c_str()); ofs << "# Run command: " << nsisCmd.c_str() << std::endl @@ -448,17 +451,26 @@ int cmCPackNSISGenerator::InitializeInternal() << "Please check " << tmpFile.c_str() << " for errors" << std::endl); return 0; } - double nsisVersion = atof(versionRex.match(1).c_str()); - double minNSISVersion = 2.09; - cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: " - << nsisVersion << std::endl); - if ( nsisVersion < minNSISVersion ) + if ( versionRex.find(output)) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "CPack requires NSIS Version 2.09 or greater. NSIS found on the system " - "was: " + double nsisVersion = atof(versionRex.match(1).c_str()); + double minNSISVersion = 2.09; + cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: " << nsisVersion << std::endl); - return 0; + if ( nsisVersion < minNSISVersion ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPack requires NSIS Version 2.09 or greater. " + "NSIS found on the system was: " + << nsisVersion << std::endl); + return 0; + } + } + if ( versionRexCVS.find(output)) + { + // No version check for NSIS cvs build + cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: CVS " + << versionRexCVS.match(1).c_str() << std::endl); } this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", nsisPath.c_str()); this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLES_DIRECTORY", "bin"); diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 2c1a0af..5b34491 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -68,7 +68,7 @@ std::string cmCTestGIT::GetWorkingRevision() { // Run plumbing "git rev-list" to get work tree revision. const char* git = this->CommandLineTool.c_str(); - const char* git_rev_list[] = {git, "rev-list", "-n", "1", "HEAD", 0}; + const char* git_rev_list[] = {git, "rev-list", "-n", "1", "HEAD", "--", 0}; std::string rev; OneLineParser out(this, "rl-out> ", rev); OutputLogger err(this->Log, "rl-err> "); @@ -639,7 +639,7 @@ void cmCTestGIT::LoadModifications() this->RunChild(git_update_index, &ui_out, &ui_err); // Use 'git diff-index' to get modified files. - const char* git_diff_index[] = {git, "diff-index", "-z", "HEAD", 0}; + const char* git_diff_index[] = {git, "diff-index", "-z", "HEAD", "--", 0}; DiffParser out(this, "di-out> "); OutputLogger err(this->Log, "di-err> "); this->RunChild(git_diff_index, &out, &err); diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 9efeda4..5b1c9c6 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -78,7 +78,7 @@ bool cmAddSubDirectoryCommand::InitialPass // No binary directory was specified. If the source directory is // not a subdirectory of the current directory then it is an // error. - if(!cmSystemTools::FindLastString(srcPath.c_str(), + if(!cmSystemTools::IsSubDirectory(srcPath.c_str(), this->Makefile->GetCurrentDirectory())) { cmOStringStream e; @@ -93,10 +93,15 @@ bool cmAddSubDirectoryCommand::InitialPass // Remove the CurrentDirectory from the srcPath and replace it // with the CurrentOutputDirectory. - binPath = srcPath; - cmSystemTools::ReplaceString(binPath, - this->Makefile->GetCurrentDirectory(), - this->Makefile->GetCurrentOutputDirectory()); + const char* src = this->Makefile->GetCurrentDirectory(); + const char* bin = this->Makefile->GetCurrentOutputDirectory(); + size_t srcLen = strlen(src); + size_t binLen = strlen(bin); + if(srcLen > 0 && src[srcLen-1] == '/') + { --srcLen; } + if(binLen > 0 && bin[binLen-1] == '/') + { --binLen; } + binPath = std::string(bin, binLen) + srcPath.substr(srcLen); } else { diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 4231243..3d5b24b 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -584,23 +584,15 @@ bool cmCacheManager::DeleteCache(const char* path) cmSystemTools::ConvertToUnixSlashes(cacheFile); std::string cmakeFiles = cacheFile; cacheFile += "/CMakeCache.txt"; - cmSystemTools::RemoveFile(cacheFile.c_str()); - // now remove the files in the CMakeFiles directory - // this cleans up language cache files - cmsys::Directory dir; - cmakeFiles += cmake::GetCMakeFilesDirectory(); - dir.Load(cmakeFiles.c_str()); - for (unsigned long fileNum = 0; - fileNum < dir.GetNumberOfFiles(); - ++fileNum) - { - if(!cmSystemTools:: - FileIsDirectory(dir.GetFile(fileNum))) + if(cmSystemTools::FileExists(cacheFile.c_str())) + { + cmSystemTools::RemoveFile(cacheFile.c_str()); + // now remove the files in the CMakeFiles directory + // this cleans up language cache files + cmakeFiles += cmake::GetCMakeFilesDirectory(); + if(cmSystemTools::FileIsDirectory(cmakeFiles.c_str())) { - std::string fullPath = cmakeFiles; - fullPath += "/"; - fullPath += dir.GetFile(fileNum); - cmSystemTools::RemoveFile(fullPath.c_str()); + cmSystemTools::RemoveADirectory(cmakeFiles.c_str()); } } return true; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 84714f3..896b50a 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1816,7 +1816,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, (outputRuntime && this->Target->HaveInstallTreeRPATH() && linking_for_install); bool use_build_rpath = - (outputRuntime && this->Target->HaveBuildTreeRPATH() && + (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) && !linking_for_install); bool use_link_rpath = outputRuntime && linking_for_install && diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 1ae7035..387f6ed 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -13,8 +13,11 @@ #include "cmake.h" #include "cmCacheManager.h" #include "cmGlobalGenerator.h" +#include "cmExportTryCompileFileGenerator.h" #include <cmsys/Directory.hxx> +#include <assert.h> + int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) { this->BinaryDirectory = argv[1].c_str(); @@ -39,7 +42,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) // is not used, so it matches regular command line parsing which has // the program name as arg 0 for (; i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" && - argv[i] != "OUTPUT_VARIABLE"; + argv[i] != "OUTPUT_VARIABLE" && + argv[i] != "LINK_LIBRARIES"; ++i) { extraArgs++; @@ -75,7 +79,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) { extraArgs++; for (i = i + 1; i < argv.size() && argv[i] != "CMAKE_FLAGS" && - argv[i] != "OUTPUT_VARIABLE"; + argv[i] != "OUTPUT_VARIABLE" && + argv[i] != "LINK_LIBRARIES"; ++i) { extraArgs++; @@ -85,6 +90,61 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) } } + std::vector<cmTarget*> targets; + std::string libsToLink = " "; + bool useOldLinkLibs = true; + for (i = 3; i < argv.size(); ++i) + { + if (argv[i] == "LINK_LIBRARIES") + { + if ( argv.size() <= (i+1) ) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "LINK_LIBRARIES specified but there is no content"); + return -1; + } + extraArgs++; + ++i; + useOldLinkLibs = false; + for ( ; i < argv.size() && argv[i] != "CMAKE_FLAGS" + && argv[i] != "COMPILE_DEFINITIONS" && argv[i] != "OUTPUT_VARIABLE"; + ++i) + { + extraArgs++; + libsToLink += argv[i] + " "; + cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i].c_str()); + if (!tgt) + { + continue; + } + switch(tgt->GetType()) + { + case cmTarget::SHARED_LIBRARY: + case cmTarget::STATIC_LIBRARY: + case cmTarget::UNKNOWN_LIBRARY: + break; + case cmTarget::EXECUTABLE: + if (tgt->IsExecutableWithExports()) + { + break; + } + default: + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "Only libraries may be used as try_compile IMPORTED " + "LINK_LIBRARIES. Got " + std::string(tgt->GetName()) + " of " + "type " + tgt->GetTargetTypeName(tgt->GetType()) + "."); + return -1; + } + if (!tgt->IsImported()) + { + continue; + } + targets.push_back(tgt); + } + break; + } + } + // look for COPY_FILE std::string copyFile; for (i = 3; i < argv.size(); ++i) @@ -247,6 +307,32 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) fprintf(fout, ")\n"); } + /* Use a random file name to avoid rapid creation and deletion + of the same executable name (some filesystems fail on that). */ + sprintf(targetNameBuf, "cmTryCompileExec%u", + cmSystemTools::RandomSeed()); + targetName = targetNameBuf; + + if (!targets.empty()) + { + std::string fname = "/" + std::string(targetName) + "Targets.cmake"; + cmExportTryCompileFileGenerator tcfg; + tcfg.SetExportFile((this->BinaryDirectory + fname).c_str()); + tcfg.SetExports(targets); + tcfg.SetConfig(this->Makefile->GetDefinition( + "CMAKE_TRY_COMPILE_CONFIGURATION")); + + if(!tcfg.GenerateImportFile()) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "could not write export file."); + return -1; + } + fprintf(fout, + "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n", + fname.c_str()); + } + /* 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 CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to @@ -286,18 +372,22 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) fprintf(fout, "SET(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n"); } - /* Use a random file name to avoid rapid creation and deletion - of the same executable name (some filesystems fail on that). */ - sprintf(targetNameBuf, "cmTryCompileExec%u", - cmSystemTools::RandomSeed()); - targetName = targetNameBuf; - /* Put the executable at a known location (for COPY_FILE). */ fprintf(fout, "SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n", this->BinaryDirectory.c_str()); /* Create the actual executable. */ fprintf(fout, "ADD_EXECUTABLE(%s \"%s\")\n", targetName, source.c_str()); - fprintf(fout, "TARGET_LINK_LIBRARIES(%s ${LINK_LIBRARIES})\n",targetName); + if (useOldLinkLibs) + { + fprintf(fout, + "TARGET_LINK_LIBRARIES(%s ${LINK_LIBRARIES})\n",targetName); + } + else + { + fprintf(fout, "TARGET_LINK_LIBRARIES(%s %s)\n", + targetName, + libsToLink.c_str()); + } fclose(fout); projectName = "CMAKE_TRY_COMPILE"; // if the source is not in CMakeTmp diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 8b80a8a..6cc3f25 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -26,6 +26,8 @@ "strings which contain a '>' for example.\n" \ " $<COMMA> = A literal ','. Used to compare " \ "strings which contain a ',' for example.\n" \ + " $<SEMICOLON> = A literal ';'. Used to prevent " \ + "list expansion on an argument with ';'.\n" \ " $<TARGET_NAME:...> = Marks ... as being the name of a " \ "target. This is required if exporting targets to multiple " \ "dependent export sets. The '...' must be a literal name of a " \ @@ -37,7 +39,6 @@ "target in the same buildsystem. Expands to the empty string " \ "otherwise.\n" \ " $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \ - " $<TARGET_DEFINED:tgt> = '1' if tgt is a target, else '0'\n" \ " $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \ " $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \ "where \"tgt\" is the name of a target. " \ diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 204bd9a..326a4ce 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1551,7 +1551,14 @@ void cmDocumentVariables::DefineVariables(cmake* cm) ("CMAKE_COMPILER_IS_GNU<LANG>", cmProperty::VARIABLE, "True if the compiler is GNU.", "If the selected <LANG> compiler is the GNU " - "compiler then this is TRUE, if not it is FALSE.",false, + "compiler then this is TRUE, if not it is FALSE. " + "Unlike the other per-language variables, this uses the GNU syntax for " + "identifying languages instead of the CMake syntax. Recognized values of " + "the <LANG> suffix are:\n" + " CC = C compiler\n" + " CXX = C++ compiler\n" + " G77 = Fortran compiler", + false, "Variables for Languages"); cm->DefineProperty diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h index e4bb251..ee963f9 100644 --- a/Source/cmEnableLanguageCommand.h +++ b/Source/cmEnableLanguageCommand.h @@ -65,7 +65,12 @@ public: "any of the extra variables that are created by the project command. " "Example languages are CXX, C, Fortran. " "If OPTIONAL is used, use the CMAKE_<languageName>_COMPILER_WORKS " - "variable to check whether the language has been enabled successfully."; + "variable to check whether the language has been enabled successfully." + "\n" + "This command must be called on file scope (not inside a function) and " + "the language enabled can only be used in the calling project or its " + "subdirectories added by add_subdirectory(). Also note that at present, " + "the OPTIONAL argument does not work."; } cmTypeMacro(cmEnableLanguageCommand, cmCommand); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index ef4ea38..7fd0380 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -679,6 +679,9 @@ cmExportFileGenerator case cmTarget::MODULE_LIBRARY: os << "add_library(" << targetName << " MODULE IMPORTED)\n"; break; + case cmTarget::UNKNOWN_LIBRARY: + os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n"; + break; default: // should never happen break; } @@ -754,29 +757,46 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, { if (missingTargets.empty()) { + os << "# This file does not depend on other imported targets which have\n" + "# been exported from the same project but in a separate " + "export set.\n\n"; return; } os << "# Make sure the targets which have been exported in some other \n" - "# export set exist.\n"; + "# export set exist.\n" + "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" + "foreach(_target "; std::set<std::string> emitted; for(unsigned int i=0; i<missingTargets.size(); ++i) { if (emitted.insert(missingTargets[i]).second) { - os << "if(NOT TARGET \"" << missingTargets[i] << "\" )\n" - << " if(CMAKE_FIND_PACKAGE_NAME)\n" - << " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" - << " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " - << "\"Required imported target \\\"" << missingTargets[i] - << "\\\" not found ! \")\n" - << " else()\n" - << " message(FATAL_ERROR \"Required imported target \\\"" - << missingTargets[i] << "\\\" not found ! \")\n" - << " endif()\n" - << "endif()\n"; + os << "\"" << missingTargets[i] << "\" "; } } - os << "\n"; + os << ")\n" + " if(NOT TARGET \"${_target}\" )\n" + " set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets \"" + "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets} ${_target}\")" + "\n" + " endif()\n" + "endforeach()\n" + "\n" + "if(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" + " if(CMAKE_FIND_PACKAGE_NAME)\n" + " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" + " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " + "\"The following imported targets are " + "referenced, but are missing: " + "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n" + " else()\n" + " message(FATAL_ERROR \"The following imported targets are " + "referenced, but are missing: " + "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n" + " endif()\n" + "endif()\n" + "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" + "\n"; } diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index b6600f0..8b8b846 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -74,17 +74,35 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) const char* installDest = this->IEGen->GetDestination(); if(!cmSystemTools::FileIsFullPath(installDest)) { - std::string dest = installDest; - os << "# Compute the installation prefix relative to this file.\n" - << "get_filename_component(_IMPORT_PREFIX " - << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"; - while(!dest.empty()) + std::string installPrefix = + this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); + std::string absDest = installPrefix + "/" + installDest + "/"; + if(strncmp(absDest.c_str(), "/lib/", 5) == 0 || + strncmp(absDest.c_str(), "/lib64/", 7) == 0 || + strncmp(absDest.c_str(), "/usr/lib/", 9) == 0 || + strncmp(absDest.c_str(), "/usr/lib64/", 11) == 0) { - os << - "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n"; - dest = cmSystemTools::GetFilenamePath(dest); + // Assume this is a build for system package installation rather than a + // relocatable distribution. Use an absolute prefix because some Linux + // distros symlink /lib to /usr/lib which confuses the relative path + // computation below if we generate for /lib under one prefix and but the + // file is loaded from another. + os << "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"; + } + else + { + std::string dest = installDest; + os << "# Compute the installation prefix relative to this file.\n" + << "get_filename_component(_IMPORT_PREFIX " + << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"; + while(!dest.empty()) + { + os << + "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n"; + dest = cmSystemTools::GetFilenamePath(dest); + } + os << "\n"; } - os << "\n"; // Import location properties may reference this variable. this->ImportPrefix = "${_IMPORT_PREFIX}/"; diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx new file mode 100644 index 0000000..75f2651 --- /dev/null +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -0,0 +1,114 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + 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. +============================================================================*/ + +#include "cmExportTryCompileFileGenerator.h" + +#include "cmGeneratedFileStream.h" +#include "cmGeneratorExpressionDAGChecker.h" + +//---------------------------------------------------------------------------- +bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os) +{ + std::set<cmTarget*> emitted; + std::set<cmTarget*> emittedDeps; + while(!this->Exports.empty()) + { + cmTarget* te = this->Exports.back(); + this->Exports.pop_back(); + if (emitted.insert(te).second) + { + emittedDeps.insert(te); + this->GenerateImportTargetCode(os, te); + + ImportPropertyMap properties; + + this->FindTargets("INTERFACE_INCLUDE_DIRECTORIES", te, emittedDeps); + this->FindTargets("INTERFACE_COMPILE_DEFINITIONS", te, emittedDeps); + + this->PopulateProperties(te, properties, emittedDeps); + + this->GenerateInterfaceProperties(te, os, properties); + } + } + return true; +} + +std::string cmExportTryCompileFileGenerator::FindTargets(const char *propName, + cmTarget *tgt, + std::set<cmTarget*> &emitted) +{ + const char *prop = tgt->GetProperty(propName); + if(!prop) + { + return std::string(); + } + + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + tgt->GetName(), + propName, 0, 0); + + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); + + cmTarget dummyHead; + dummyHead.SetType(cmTarget::EXECUTABLE, "try_compile_dummy_exe"); + dummyHead.SetMakefile(tgt->GetMakefile()); + + std::string result = cge->Evaluate(tgt->GetMakefile(), this->Config, + false, &dummyHead, tgt, &dagChecker); + + const std::set<cmTarget*> &allTargets = cge->GetAllTargetsSeen(); + for(std::set<cmTarget*>::const_iterator li = allTargets.begin(); + li != allTargets.end(); ++li) + { + if(emitted.insert(*li).second) + { + this->Exports.push_back(*li); + } + } + return result; +} + +//---------------------------------------------------------------------------- +void +cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target, + ImportPropertyMap& properties, + std::set<cmTarget*> &emitted) +{ + cmPropertyMap props = target->GetProperties(); + for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i) + { + properties[i->first] = i->second.GetValue(); + + if(i->first.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0) + { + const std::string libs = i->second.GetValue(); + + std::string evalResult = this->FindTargets(i->first.c_str(), + target, emitted); + + std::vector<std::string> depends; + cmSystemTools::ExpandListArgument(evalResult, depends); + for(std::vector<std::string>::const_iterator li = depends.begin(); + li != depends.end(); ++li) + { + cmTarget *tgt = target->GetMakefile()->FindTargetToUse(li->c_str()); + if(tgt && emitted.insert(tgt).second) + { + this->Exports.push_back(tgt); + } + } + } + } +} diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h new file mode 100644 index 0000000..ed393ab --- /dev/null +++ b/Source/cmExportTryCompileFileGenerator.h @@ -0,0 +1,55 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + 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. +============================================================================*/ +#ifndef cmExportInstallFileGenerator_h +#define cmExportInstallFileGenerator_h + +#include "cmExportFileGenerator.h" + +class cmInstallExportGenerator; +class cmInstallTargetGenerator; + +class cmExportTryCompileFileGenerator: public cmExportFileGenerator +{ +public: + /** Set the list of targets to export. */ + void SetExports(const std::vector<cmTarget*> &exports) + { this->Exports = exports; } + void SetConfig(const char *config) { this->Config = config; } +protected: + + // Implement virtual methods from the superclass. + virtual bool GenerateMainFile(std::ostream& os); + + virtual void GenerateImportTargetsConfig(std::ostream&, + const char*, + std::string const&, + std::vector<std::string>&) {} + virtual void HandleMissingTarget(std::string&, + std::vector<std::string>&, + cmMakefile*, + cmTarget*, + cmTarget*) {} + + void PopulateProperties(cmTarget* target, + ImportPropertyMap& properties, + std::set<cmTarget*> &emitted); + +private: + std::string FindTargets(const char *prop, cmTarget *tgt, + std::set<cmTarget*> &emitted); + + + std::vector<cmTarget*> Exports; + const char *Config; +}; + +#endif diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 470ceca..aa3a73d 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -95,7 +95,8 @@ void cmFindPackageCommand::GenerateDocumentation() "Finds and loads settings from an external project. " "<package>_FOUND will be set to indicate whether the package was found. " "When the package is found package-specific information is provided " - "through variables documented by the package itself. " + "through variables and imported targets documented by the package " + "itself. " "The QUIET option disables messages if the package cannot be found. " "The MODULE option disables the second signature documented below. " "The REQUIRED option stops processing with an error message if the " diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 5d162fe..3f59129 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -114,7 +114,8 @@ const char *cmCompiledGeneratorExpression::Evaluate( this->HadContextSensitiveCondition = context.HadContextSensitiveCondition; } - this->Targets = context.Targets; + this->DependTargets = context.DependTargets; + this->AllTargetsSeen = context.AllTargets; // TODO: Return a std::string from here instead? return this->Output.c_str(); } @@ -153,7 +154,8 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() } //---------------------------------------------------------------------------- -static std::string stripEmptyListElements(const std::string &input) +std::string cmGeneratorExpression::StripEmptyListElements( + const std::string &input) { std::string result; @@ -223,7 +225,7 @@ static std::string stripAllGeneratorExpressions(const std::string &input) lastPos = pos; } result += input.substr(lastPos); - return stripEmptyListElements(result); + return cmGeneratorExpression::StripEmptyListElements(result); } //---------------------------------------------------------------------------- @@ -284,7 +286,7 @@ static std::string stripExportInterface(const std::string &input, } result += input.substr(lastPos); - return stripEmptyListElements(result); + return cmGeneratorExpression::StripEmptyListElements(result); } //---------------------------------------------------------------------------- @@ -300,12 +302,20 @@ void cmGeneratorExpression::Split(const std::string &input, if (!part.empty()) { std::string::size_type startPos = input.rfind(";", pos); - if (startPos != pos - 1 && startPos >= lastPos) + if (startPos == std::string::npos) + { + preGenex = part; + part = ""; + } + else if (startPos != pos - 1 && startPos >= lastPos) { part = input.substr(lastPos, startPos - lastPos); preGenex = input.substr(startPos + 1, pos - startPos - 1); } - cmSystemTools::ExpandListArgument(part.c_str(), output); + if(!part.empty()) + { + cmSystemTools::ExpandListArgument(part.c_str(), output); + } } pos += 2; int nestingLevel = 1; @@ -383,7 +393,7 @@ bool cmGeneratorExpression::IsValidTargetName(const std::string &input) cmsys::RegularExpression targetNameValidator; // The ':' is supported to allow use with IMPORTED targets. At least // Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter. - targetNameValidator.compile("^[A-Za-z0-9_.:-]+$"); + targetNameValidator.compile("^[A-Za-z0-9_.:+-]+$"); return targetNameValidator.find(input.c_str()); } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 489b052..86b6f25 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -66,6 +66,7 @@ public: static bool IsValidTargetName(const std::string &input); + static std::string StripEmptyListElements(const std::string &input); private: cmGeneratorExpression(const cmGeneratorExpression &); void operator=(const cmGeneratorExpression &); @@ -88,11 +89,14 @@ public: /** Get set of targets found during evaluations. */ std::set<cmTarget*> const& GetTargets() const - { return this->Targets; } + { return this->DependTargets; } std::set<cmStdString> const& GetSeenTargetProperties() const { return this->SeenTargetProperties; } + std::set<cmTarget*> const& GetAllTargetsSeen() const + { return this->AllTargetsSeen; } + ~cmCompiledGeneratorExpression(); std::string GetInput() const @@ -123,7 +127,8 @@ private: const std::string Input; bool NeedsParsing; - mutable std::set<cmTarget*> Targets; + mutable std::set<cmTarget*> DependTargets; + mutable std::set<cmTarget*> AllTargetsSeen; mutable std::set<cmStdString> SeenTargetProperties; mutable std::string Output; mutable bool HadContextSensitiveCondition; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 57e7358..5cb50b9 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -33,8 +33,8 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( } this->CheckResult = this->checkGraph(); - if (CheckResult == DAG && (top->Property == "INCLUDE_DIRECTORIES" - || top->Property == "COMPILE_DEFINITIONS") ) + if (CheckResult == DAG && (top->EvaluatingIncludeDirectories() + || top->EvaluatingCompileDefinitions())) { std::map<cmStdString, std::set<cmStdString> >::const_iterator it = top->Seen.find(target); @@ -126,7 +126,7 @@ cmGeneratorExpressionDAGChecker::checkGraph() const { if (this->Target == parent->Target && this->Property == parent->Property) { - return parent->Parent ? CYCLIC_REFERENCE : SELF_REFERENCE; + return (parent == this->Parent) ? SELF_REFERENCE : CYCLIC_REFERENCE; } parent = parent->Parent; } @@ -153,7 +153,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries() } //---------------------------------------------------------------------------- -bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() +bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() const { const char *prop = this->Property.c_str(); return (strcmp(prop, "INCLUDE_DIRECTORIES") == 0 @@ -161,7 +161,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() } //---------------------------------------------------------------------------- -bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() +bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const { const char *prop = this->Property.c_str(); return (strcmp(prop, "COMPILE_DEFINITIONS") == 0 diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index a2e5ce4..62a5cdf 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -38,8 +38,8 @@ struct cmGeneratorExpressionDAGChecker const std::string &expr); bool EvaluatingLinkLibraries(); - bool EvaluatingIncludeDirectories(); - bool EvaluatingCompileDefinitions(); + bool EvaluatingIncludeDirectories() const; + bool EvaluatingCompileDefinitions() const; private: Result checkGraph() const; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index cd6a40b..6618e83 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -227,6 +227,22 @@ static const struct CommaNode : public cmGeneratorExpressionNode } commaNode; //---------------------------------------------------------------------------- +static const struct SemicolonNode : public cmGeneratorExpressionNode +{ + SemicolonNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return ";"; + } +} semicolonNode; + +//---------------------------------------------------------------------------- static const struct ConfigurationNode : public cmGeneratorExpressionNode { ConfigurationNode() {} @@ -291,22 +307,6 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode } configurationTestNode; -static const struct TargetDefinedNode : public cmGeneratorExpressionNode -{ - TargetDefinedNode() {} - - virtual int NumExpectedParameters() const { return 1; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return context->Makefile->FindTargetToUse(parameters.front().c_str()) - ? "1" : "0"; - } -} targetDefinedNode; - //---------------------------------------------------------------------------- static const char* targetPropertyTransitiveWhitelist[] = { "INTERFACE_INCLUDE_DIRECTORIES" @@ -392,6 +392,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode reportError(context, content->GetOriginalExpression(), e.str()); return std::string(); } + context->AllTargets.insert(target); } if (target == context->HeadTarget) @@ -452,8 +453,6 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode const char *prop = target->GetProperty(propertyName.c_str()); - std::string linkedTargetsContent; - if (dagCheckerParent) { if (dagCheckerParent->EvaluatingLinkLibraries()) @@ -467,47 +466,74 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode { assert(dagCheckerParent->EvaluatingIncludeDirectories() || dagCheckerParent->EvaluatingCompileDefinitions()); + } + } + + std::string linkedTargetsContent; + + std::string interfacePropertyName; + + if (propertyName == "INTERFACE_INCLUDE_DIRECTORIES" + || propertyName == "INCLUDE_DIRECTORIES") + { + interfacePropertyName = "INTERFACE_INCLUDE_DIRECTORIES"; + } + else if (propertyName == "INTERFACE_COMPILE_DEFINITIONS" + || propertyName == "COMPILE_DEFINITIONS" + || strncmp(propertyName.c_str(), "COMPILE_DEFINITIONS_", 20) == 0) + { + interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; + } + + if (interfacePropertyName == "INTERFACE_INCLUDE_DIRECTORIES" + || interfacePropertyName == "INTERFACE_COMPILE_DEFINITIONS") + { + const cmTarget::LinkInterface *iface = target->GetLinkInterface( + context->Config, + context->HeadTarget); + if(iface) + { + cmGeneratorExpression ge(context->Backtrace); - if (propertyName == "INTERFACE_INCLUDE_DIRECTORIES" - || propertyName == "INTERFACE_COMPILE_DEFINITIONS") + std::string sep; + std::string depString; + for (std::vector<std::string>::const_iterator + it = iface->Libraries.begin(); + it != iface->Libraries.end(); ++it) { - const cmTarget::LinkInterface *iface = target->GetLinkInterface( - context->Config, - context->HeadTarget); - if(iface) + if (*it == target->GetName()) { - cmGeneratorExpression ge(context->Backtrace); - - std::string sep; - std::string depString; - for (std::vector<std::string>::const_iterator - it = iface->Libraries.begin(); - it != iface->Libraries.end(); ++it) - { - if (context->Makefile->FindTargetToUse(it->c_str())) - { - depString += - sep + "$<TARGET_PROPERTY:" + *it + "," + propertyName + ">"; - sep = ";"; - } - } - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(depString); - linkedTargetsContent = cge->Evaluate(context->Makefile, - context->Config, - context->Quiet, - context->HeadTarget, - target, - &dagChecker); - if (cge->GetHadContextSensitiveCondition()) - { - context->HadContextSensitiveCondition = true; - } + // Broken code can have a target in its own link interface. + // Don't follow such link interface entries so as not to create a + // self-referencing loop. + continue; } + if (context->Makefile->FindTargetToUse(it->c_str())) + { + depString += + sep + "$<TARGET_PROPERTY:" + *it + "," + + interfacePropertyName + ">"; + sep = ";"; + } + } + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(depString); + linkedTargetsContent = cge->Evaluate(context->Makefile, + context->Config, + context->Quiet, + context->HeadTarget, + target, + &dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; } } } + linkedTargetsContent = + cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); + if (!prop) { if (target->IsImported()) @@ -541,7 +567,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode sizeof(*targetPropertyTransitiveWhitelist)); ++i) { - if (targetPropertyTransitiveWhitelist[i] == propertyName) + if (targetPropertyTransitiveWhitelist[i] == interfacePropertyName) { cmGeneratorExpression ge(context->Backtrace); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); @@ -852,7 +878,8 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode "Target \"" + name + "\" is not an executable or library."); return std::string(); } - context->Targets.insert(target); + context->DependTargets.insert(target); + context->AllTargets.insert(target); std::string result = TargetFilesystemArtifactResultCreator<linker, soname>::Create( @@ -932,6 +959,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &angle_rNode; else if (identifier == "COMMA") return &commaNode; + else if (identifier == "SEMICOLON") + return &semicolonNode; else if (identifier == "TARGET_PROPERTY") return &targetPropertyNode; else if (identifier == "TARGET_NAME") @@ -942,8 +971,6 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &buildInterfaceNode; else if (identifier == "INSTALL_INTERFACE") return &installInterfaceNode; - else if (identifier == "TARGET_DEFINED") - return &targetDefinedNode; else if (identifier == "INSTALL_PREFIX") return &installPrefixNode; return 0; diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 37d5c86..ce7ad69 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -23,7 +23,8 @@ class cmTarget; struct cmGeneratorExpressionContext { cmListFileBacktrace Backtrace; - std::set<cmTarget*> Targets; + std::set<cmTarget*> DependTargets; + std::set<cmTarget*> AllTargets; std::set<cmStdString> SeenTargetProperties; cmMakefile *Makefile; const char *Config; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ba29589..fcd6f71 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1067,6 +1067,8 @@ bool cmGlobalGenerator::CheckTargets() void cmGlobalGenerator::CreateAutomocTargets() { #ifdef CMAKE_BUILD_WITH_CMAKE + typedef std::vector<std::pair<cmQtAutomoc, cmTarget*> > Automocs; + Automocs automocs; for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { cmTargets& targets = @@ -1084,11 +1086,17 @@ void cmGlobalGenerator::CreateAutomocTargets() if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported()) { cmQtAutomoc automoc; - automoc.SetupAutomocTarget(&target); + automoc.InitializeMocSourceFile(&target); + automocs.push_back(std::make_pair(automoc, &target)); } } } } + for (Automocs::iterator it = automocs.begin(); it != automocs.end(); + ++it) + { + it->first.SetupAutomocTarget(it->second); + } #endif } @@ -2074,6 +2082,38 @@ bool cmGlobalGenerator::UseFolderProperty() } //---------------------------------------------------------------------------- +void cmGlobalGenerator::EnableMinGWLanguage(cmMakefile *mf) +{ + this->FindMakeProgram(mf); + std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); + std::vector<std::string> locations; + locations.push_back(cmSystemTools::GetProgramPath(makeProgram.c_str())); + locations.push_back("/mingw/bin"); + locations.push_back("c:/mingw/bin"); + std::string tgcc = cmSystemTools::FindProgram("gcc", locations); + std::string gcc = "gcc.exe"; + if(tgcc.size()) + { + gcc = tgcc; + } + std::string tgxx = cmSystemTools::FindProgram("g++", locations); + std::string gxx = "g++.exe"; + if(tgxx.size()) + { + gxx = tgxx; + } + std::string trc = cmSystemTools::FindProgram("windres", locations); + std::string rc = "windres.exe"; + if(trc.size()) + { + rc = trc; + } + mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str()); + mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str()); + mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str()); +} + +//---------------------------------------------------------------------------- cmTarget cmGlobalGenerator::CreateGlobalTarget( const char* name, const char* message, const cmCustomCommandLines* commandLines, diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index f8275e8..11616e0 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -340,6 +340,7 @@ protected: virtual const char* GetPredefinedTargetsFolder(); virtual bool UseFolderProperty(); + void EnableMinGWLanguage(cmMakefile *mf); private: cmMakefile* TryCompileOuterMakefile; diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx index e202b02..1f374d3 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.cxx +++ b/Source/cmGlobalMinGWMakefileGenerator.cxx @@ -26,33 +26,7 @@ void cmGlobalMinGWMakefileGenerator cmMakefile *mf, bool optional) { - this->FindMakeProgram(mf); - std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); - std::vector<std::string> locations; - locations.push_back(cmSystemTools::GetProgramPath(makeProgram.c_str())); - locations.push_back("/mingw/bin"); - locations.push_back("c:/mingw/bin"); - std::string tgcc = cmSystemTools::FindProgram("gcc", locations); - std::string gcc = "gcc.exe"; - if(tgcc.size()) - { - gcc = tgcc; - } - std::string tgxx = cmSystemTools::FindProgram("g++", locations); - std::string gxx = "g++.exe"; - if(tgxx.size()) - { - gxx = tgxx; - } - std::string trc = cmSystemTools::FindProgram("windres", locations); - std::string rc = "windres.exe"; - if(trc.size()) - { - rc = trc; - } - mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str()); + this->EnableMinGWLanguage(mf); this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 60f5a47..01c685d 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -17,6 +17,8 @@ #include "cmGeneratorTarget.h" #include "cmVersion.h" +#include <algorithm> + const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja"; const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja"; const char* cmGlobalNinjaGenerator::INDENT = " "; @@ -491,69 +493,20 @@ void cmGlobalNinjaGenerator::Generate() // Used in: // Source/cmMakefile.cxx: void cmGlobalNinjaGenerator -::EnableLanguage(std::vector<std::string>const& languages, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& langs, + cmMakefile* makefile, bool optional) { - std::string path; - for(std::vector<std::string>::const_iterator l = languages.begin(); - l != languages.end(); ++l) + if (makefile->IsOn("CMAKE_COMPILER_IS_MINGW")) { - std::vector<std::string> language; - language.push_back(*l); - - if(*l == "NONE") - { - this->cmGlobalGenerator::EnableLanguage(language, mf, optional); - continue; - } - else if(*l == "Fortran") - { - std::string message = "The \""; - message += this->GetName(); - message += "\" generator does not support the language \""; - message += *l; - message += "\" yet."; - cmSystemTools::Error(message.c_str()); - } - else if(*l == "RC") - { - // check if mingw is used - if(mf->IsOn("CMAKE_COMPILER_IS_MINGW")) - { - UsingMinGW = true; - if(!mf->GetDefinition("CMAKE_RC_COMPILER")) - { - std::string windres = cmSystemTools::FindProgram("windres"); - if(windres.empty()) - { - std::string compiler_path; - std::string::size_type prefix = std::string::npos; - if (mf->GetDefinition("CMAKE_C_COMPILER")) - { - compiler_path = mf->GetDefinition("CMAKE_C_COMPILER"); - prefix = compiler_path.rfind("gcc"); - } - else if (mf->GetDefinition("CMAKE_CXX_COMPILER")) - { - compiler_path = mf->GetDefinition("CMAKE_CXX_COMPILER"); - prefix = compiler_path.rfind("++"); - prefix--; - } - if (prefix != std::string::npos) - { - windres = compiler_path.substr(0, prefix) + "windres"; - windres = cmSystemTools::FindProgram(windres.c_str()); - } - } - if(!windres.empty()) - mf->AddDefinition("CMAKE_RC_COMPILER", windres.c_str()); - } - } - } - this->cmGlobalGenerator::EnableLanguage(language, mf, optional); - this->ResolveLanguageCompiler(*l, mf, optional); + UsingMinGW = true; + this->EnableMinGWLanguage(makefile); + } + if (std::find(langs.begin(), langs.end(), "Fortran") != langs.end()) + { + cmSystemTools::Error("The Ninja generator does not support Fortran yet."); } + this->cmGlobalGenerator::EnableLanguage(langs, makefile, optional); } bool cmGlobalNinjaGenerator::UsingMinGW = false; diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index cb15c30..9f3af71 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -41,11 +41,8 @@ void cmGlobalVisualStudio6Generator bool optional) { cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf); - mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); - mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); - mf->AddDefinition("CMAKE_GENERATOR_Fortran", "ifort"); this->GenerateConfigurations(mf); this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); } diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 71d79a1..63cbdb8 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -27,8 +27,6 @@ void cmGlobalVisualStudio7Generator ::EnableLanguage(std::vector<std::string>const & lang, cmMakefile *mf, bool optional) { - mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); - mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort"); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 9600771..2222a0e 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -237,8 +237,6 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const& cmCacheManager::STRING); } } - mf->AddDefinition("CMAKE_GENERATOR_CC", "gcc"); - mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); if(!this->PlatformToolset.empty()) { @@ -956,6 +954,15 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen) } //---------------------------------------------------------------------------- +struct cmSourceFilePathCompare +{ + bool operator()(cmSourceFile* l, cmSourceFile* r) + { + return l->GetFullPath() < r->GetFullPath(); + } +}; + +//---------------------------------------------------------------------------- void cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>& @@ -981,7 +988,9 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, } // organize the sources - std::vector<cmSourceFile*> const &classes = cmtarget.GetSourceFiles(); + std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles(); + std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare()); + std::vector<cmXCodeObject*> externalObjFiles; std::vector<cmXCodeObject*> headerFiles; std::vector<cmXCodeObject*> resourceFiles; @@ -2101,6 +2110,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, debugStr = "NO"; } + buildSettings->AddAttribute("COMBINE_HIDPI_IMAGES", + this->CreateString("YES")); buildSettings->AddAttribute("GCC_GENERATE_DEBUGGING_SYMBOLS", this->CreateString(debugStr)); buildSettings->AddAttribute("GCC_OPTIMIZATION_LEVEL", @@ -2517,47 +2528,25 @@ std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name, void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget) { - // make sure a target does not depend on itself - if(target == dependTarget) - { - return; - } - // now avoid circular references if dependTarget already - // depends on target then skip it. Circular references crashes - // xcode - cmXCodeObject* dependTargetDepends = - dependTarget->GetObject("dependencies"); - if(dependTargetDepends) - { - if(dependTargetDepends->HasObject(target->GetPBXTargetDependency())) - { - return; - } - } - - cmXCodeObject* targetdep = dependTarget->GetPBXTargetDependency(); - if(!targetdep) - { - cmXCodeObject* container = - this->CreateObject(cmXCodeObject::PBXContainerItemProxy); - container->SetComment("PBXContainerItemProxy"); - container->AddAttribute("containerPortal", - this->CreateObjectReference(this->RootObject)); - container->AddAttribute("proxyType", this->CreateString("1")); - container->AddAttribute("remoteGlobalIDString", - this->CreateObjectReference(dependTarget)); - container->AddAttribute("remoteInfo", - this->CreateString( - dependTarget->GetTarget()->GetName())); - targetdep = - this->CreateObject(cmXCodeObject::PBXTargetDependency); - targetdep->SetComment("PBXTargetDependency"); - targetdep->AddAttribute("target", - this->CreateObjectReference(dependTarget)); - targetdep->AddAttribute("targetProxy", - this->CreateObjectReference(container)); - dependTarget->SetPBXTargetDependency(targetdep); - } + // This is called once for every edge in the target dependency graph. + cmXCodeObject* container = + this->CreateObject(cmXCodeObject::PBXContainerItemProxy); + container->SetComment("PBXContainerItemProxy"); + container->AddAttribute("containerPortal", + this->CreateObjectReference(this->RootObject)); + container->AddAttribute("proxyType", this->CreateString("1")); + container->AddAttribute("remoteGlobalIDString", + this->CreateObjectReference(dependTarget)); + container->AddAttribute("remoteInfo", + this->CreateString( + dependTarget->GetTarget()->GetName())); + cmXCodeObject* targetdep = + this->CreateObject(cmXCodeObject::PBXTargetDependency); + targetdep->SetComment("PBXTargetDependency"); + targetdep->AddAttribute("target", + this->CreateObjectReference(dependTarget)); + targetdep->AddAttribute("targetProxy", + this->CreateObjectReference(container)); cmXCodeObject* depends = target->GetObject("dependencies"); if(!depends) @@ -2914,7 +2903,7 @@ cmXCodeObject* cmGlobalXCodeGenerator { std::vector<std::string> folders = cmSystemTools::tokenize(sg->GetFullName(), "\\"); - cmStdString curr_folder = cmtarget.GetName(); + cmStdString curr_folder = target; curr_folder += "/"; for(std::vector<std::string>::size_type i = 0; i < folders.size();i++) { diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index ee92906..7aff731 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -36,6 +36,8 @@ public: cmExportSet* GetExportSet() {return this->ExportSet;} + cmMakefile* GetMakefile() const { return this->Makefile; } + const std::string& GetNamespace() const { return this->Namespace; } protected: diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 84cf6ca..a1c34f0 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -49,29 +49,29 @@ public: /** * Calls TraceVSDependencies() on all targets of this generator. */ - virtual void TraceDependencies(); + void TraceDependencies(); virtual void AddHelperCommands() {} /** * Perform any final calculations prior to generation */ - virtual void ConfigureFinalPass(); + void ConfigureFinalPass(); /** * Generate the install rules files in this directory. */ - virtual void GenerateInstallRules(); + void GenerateInstallRules(); /** * Generate the test files for tests. */ - virtual void GenerateTestFiles(); + void GenerateTestFiles(); /** * Generate a manifest of target files that will be built. */ - virtual void GenerateTargetManifest(); + void GenerateTargetManifest(); ///! Get the makefile for this generator cmMakefile *GetMakefile() { diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index f07ebef..dfe8280 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1621,17 +1621,30 @@ cmLocalVisualStudio7Generator return dir_max; } -void cmLocalVisualStudio7Generator +bool cmLocalVisualStudio7Generator ::WriteGroup(const cmSourceGroup *sg, cmTarget& target, std::ostream &fout, const char *libName, std::vector<std::string> *configs) { const std::vector<const cmSourceFile *> &sourceFiles = sg->GetSourceFiles(); + std::vector<cmSourceGroup> const& children = sg->GetGroupChildren(); + + // Write the children to temporary output. + bool hasChildrenWithSources = false; + cmOStringStream tmpOut; + for(unsigned int i=0;i<children.size();++i) + { + if(this->WriteGroup(&children[i], target, tmpOut, libName, configs)) + { + hasChildrenWithSources = true; + } + } + // If the group is empty, don't write it at all. - if(sourceFiles.empty() && sg->GetGroupChildren().empty()) + if(sourceFiles.empty() && !hasChildrenWithSources) { - return; + return false; } // If the group has a name, write the header. @@ -1752,11 +1765,10 @@ void cmLocalVisualStudio7Generator } } - std::vector<cmSourceGroup> const& children = sg->GetGroupChildren(); - - for(unsigned int i=0;i<children.size();++i) + // If the group has children with source files, write the children. + if(hasChildrenWithSources) { - this->WriteGroup(&children[i], target, fout, libName, configs); + fout << tmpOut.str(); } // If the group has a name, write the footer. @@ -1764,6 +1776,8 @@ void cmLocalVisualStudio7Generator { this->WriteVCProjEndGroup(fout); } + + return true; } void cmLocalVisualStudio7Generator:: diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 5a1d208..d9e2ef0 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -109,7 +109,7 @@ private: FCInfo& fcinfo); void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target); - void WriteGroup(const cmSourceGroup *sg, + bool WriteGroup(const cmSourceGroup *sg, cmTarget& target, std::ostream &fout, const char *libName, std::vector<std::string> *configs); diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 4818f1b..10ce641 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -119,6 +119,22 @@ cmQtAutomoc::cmQtAutomoc() } } +void cmQtAutomoc::InitializeMocSourceFile(cmTarget* target) +{ + std::string automocTargetName = target->GetName(); + cmMakefile *makefile = target->GetMakefile(); + automocTargetName += "_automoc"; + std::string mocCppFile = makefile->GetCurrentOutputDirectory(); + mocCppFile += "/"; + mocCppFile += automocTargetName; + mocCppFile += ".cpp"; + cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), + true); + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + mocCppFile.c_str(), false); + + target->AddSourceFile(mocCppSource); +} void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) { @@ -268,17 +284,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) outputFile += "/AutomocInfo.cmake"; makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, false); - - std::string mocCppFile = makefile->GetCurrentOutputDirectory(); - mocCppFile += "/"; - mocCppFile += automocTargetName; - mocCppFile += ".cpp"; - cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), - true); - target->AddSourceFile(mocCppSource); - - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", - mocCppFile.c_str(), false); } diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index 69da80e..962e254 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -23,6 +23,7 @@ public: cmQtAutomoc(); bool Run(const char* targetDirectory); + void InitializeMocSourceFile(cmTarget* target); void SetupAutomocTarget(cmTarget* target); private: diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 4423a90..30dbaa5 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -136,6 +136,9 @@ public: " [^ ] Matches any character(s) not inside the brackets\n" " - Inside brackets, specifies an inclusive range between\n" " characters on either side e.g. [a-f] is [abcdef]\n" + " To match a literal - using brackets, make it the first\n" + " or the last character e.g. [+*/-] matches basic\n" + " mathematical operators.\n" " * Matches preceding pattern zero or more times\n" " + Matches preceding pattern one or more times\n" " ? Matches preceding pattern zero or once only\n" @@ -144,6 +147,10 @@ public: " in the REGEX REPLACE operation. Additionally it is saved\n" " by all regular expression-related commands, including \n" " e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).\n" + "*, + and ? have higher precedence than concatenation. | has lower " + "precedence than concatenation. This means that the regular expression " + "\"^ab+d$\" matches \"abbd\" but not \"ababd\", and the regular " + "expression \"^(ab|cd)$\" matches \"ab\" but not \"abd\".\n" "TIMESTAMP will write a string representation of " "the current date and/or time to the output variable.\n" "Should the command be unable to obtain a timestamp " diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 07da31f..e0d7fa4 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -92,6 +92,7 @@ public: // Others not copied here are result caches. this->SourceEntries = r.SourceEntries; } + ~cmTargetInternals(); typedef cmTarget::SourceFileFlags SourceFileFlags; std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap; bool SourceFileFlagsConstructed; @@ -138,9 +139,36 @@ public: }; std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries; std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries; + + std::vector<IncludeDirectoriesEntry*> + CachedLinkInterfaceIncludeDirectoriesEntries; + std::map<std::string, std::string> CachedLinkInterfaceCompileDefinitions; + + std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone; + std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone; }; //---------------------------------------------------------------------------- +void deleteAndClear( + std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries) +{ + for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator + it = entries.begin(), + end = entries.end(); + it != end; ++it) + { + delete *it; + } + entries.clear(); +} + +//---------------------------------------------------------------------------- +cmTargetInternals::~cmTargetInternals() +{ + deleteAndClear(CachedLinkInterfaceIncludeDirectoriesEntries); +} + +//---------------------------------------------------------------------------- cmTarget::cmTarget() { this->Makefile = 0; @@ -1204,7 +1232,9 @@ void cmTarget::DefineProperties(cmake *cm) ("GENERATOR_FILE_NAME", cmProperty::TARGET, "Generator's file for this target.", "An internal property used by some generators to record the name of " - "project or dsp file associated with this target."); + "project or dsp file associated with this target. Note that at configure " + "time, this property is only set for targets created by " + "include_external_msproject()."); cm->DefineProperty ("SOURCES", cmProperty::TARGET, @@ -2655,20 +2685,6 @@ void cmTarget::GatherDependencies( const cmMakefile& mf, } //---------------------------------------------------------------------------- -void deleteAndClear( - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries) -{ - for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator - it = entries.begin(), - end = entries.end(); - it != end; ++it) - { - delete *it; - } - entries.clear(); -} - -//---------------------------------------------------------------------------- void cmTarget::SetProperty(const char* prop, const char* value) { if (!prop) @@ -2870,41 +2886,54 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) config, debugIncludes); - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> - linkInterfaceIncludeDirectoriesEntries; - - for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(), - end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end(); - it != end; ++it) + std::string configString = config ? config : ""; + if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString]) { - { - cmGeneratorExpression ge(lfbt); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(it->Value); - std::string result = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(result.c_str())) + for (std::vector<cmValueWithOrigin>::const_iterator + it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(), + end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end(); + it != end; ++it) { - continue; + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(it->Value); + std::string result = cge->Evaluate(this->Makefile, config, + false, this, 0, 0); + if (!cmGeneratorExpression::IsValidTargetName(result.c_str()) + || !this->Makefile->FindTargetToUse(result.c_str())) + { + continue; + } } - } - cmGeneratorExpression ge(it->Backtrace); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse( - "$<TARGET_PROPERTY:" + it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>"); + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse( + "$<TARGET_PROPERTY:" + + it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>"); - linkInterfaceIncludeDirectoriesEntries.push_back( + this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries.push_back( new cmTargetInternals::IncludeDirectoriesEntry(cge)); + } } processIncludeDirectories(this, - linkInterfaceIncludeDirectoriesEntries, + this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries, includes, uniqueIncludes, &dagChecker, config, debugIncludes); - deleteAndClear(linkInterfaceIncludeDirectoriesEntries); + if (!this->Makefile->IsGeneratingBuildSystem()) + { + deleteAndClear( + this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries); + } + else + { + this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString] + = true; + } return includes; } @@ -2949,7 +2978,9 @@ std::string cmTarget::GetCompileDefinitions(const char *config) for (std::vector<std::string>::const_iterator it = libs.begin(); it != libs.end(); ++it) { - if (this->Makefile->FindTargetToUse(it->c_str())) + if ((cmGeneratorExpression::IsValidTargetName(it->c_str()) + || cmGeneratorExpression::Find(it->c_str()) != std::string::npos) + && this->Makefile->FindTargetToUse(it->c_str())) { depString += sep + "$<TARGET_PROPERTY:" + *it + ",INTERFACE_COMPILE_DEFINITIONS>"; @@ -2957,16 +2988,34 @@ std::string cmTarget::GetCompileDefinitions(const char *config) } } - cmGeneratorExpression ge2(lfbt); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge2 = ge2.Parse(depString); - std::string depResult = cge2->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker); - if (!depResult.empty()) + std::string configString = config ? config : ""; + if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString]) + { + cmGeneratorExpression ge2(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge2 = + ge2.Parse(depString); + this->Internal->CachedLinkInterfaceCompileDefinitions[configString] = + cge2->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker); + } + if (!this->Internal->CachedLinkInterfaceCompileDefinitions[configString] + .empty()) + { + result += (result.empty() ? "" : ";") + + this->Internal->CachedLinkInterfaceCompileDefinitions[configString]; + } + + if (!this->Makefile->IsGeneratingBuildSystem()) { - result += (result.empty() ? "" : ";") + depResult; + this->Internal->CachedLinkInterfaceCompileDefinitions[configString] = ""; + } + else + { + this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString] + = true; } return result; @@ -4209,10 +4258,15 @@ void cmTarget::SetPropertyDefault(const char* property, } //---------------------------------------------------------------------------- -bool cmTarget::HaveBuildTreeRPATH() +bool cmTarget::HaveBuildTreeRPATH(const char *config) { - return (!this->GetPropertyAsBool("SKIP_BUILD_RPATH") && - !this->LinkLibraries.empty()); + if (this->GetPropertyAsBool("SKIP_BUILD_RPATH")) + { + return false; + } + std::vector<std::string> libs; + this->GetDirectLinkLibraries(config, libs, this); + return !libs.empty(); } //---------------------------------------------------------------------------- @@ -4283,7 +4337,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config) // If either a build or install tree rpath is set then the rpath // will likely change between the build tree and install tree and // this target must be relinked. - return this->HaveBuildTreeRPATH() || this->HaveInstallTreeRPATH(); + return this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(); } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e659baf..0e6dd42 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -401,7 +401,7 @@ public: */ bool NeedRelinkBeforeInstall(const char* config); - bool HaveBuildTreeRPATH(); + bool HaveBuildTreeRPATH(const char *config); bool HaveInstallTreeRPATH(); /** Return true if builtin chrpath will work for this target */ diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h index 68ec666..6caa130 100644 --- a/Source/cmTryCompileCommand.h +++ b/Source/cmTryCompileCommand.h @@ -67,6 +67,7 @@ public: " try_compile(RESULT_VAR <bindir> <srcfile>\n" " [CMAKE_FLAGS flags...]\n" " [COMPILE_DEFINITIONS flags...]\n" + " [LINK_LIBRARIES libs...]\n" " [OUTPUT_VARIABLE <var>]\n" " [COPY_FILE <fileName>])\n" "Try building a source file into an executable. " @@ -90,7 +91,12 @@ public: "Some extra flags that can be included are, " "INCLUDE_DIRECTORIES, LINK_DIRECTORIES, and LINK_LIBRARIES. " "COMPILE_DEFINITIONS are -Ddefinition that will be passed to the " - "compile line. " + "compile line.\n" + "The srcfile signature also accepts a LINK_LIBRARIES argument which " + "may contain a list of libraries or IMPORTED targets which will be " + "linked to in the generated project. If LINK_LIBRARIES is specified " + "as a parameter to try_compile, then any LINK_LIBRARIES passed as " + "CMAKE_FLAGS will be ignored.\n" "try_compile creates a CMakeList.txt " "file on the fly that looks like this:\n" " add_definitions( <expanded COMPILE_DEFINITIONS from calling " diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 171ed9a..f4984c7 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1390,7 +1390,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) std::string flags; if(stackVal) { - flags += " "; + flags += " /STACK:"; flags += stackVal; } std::string linkFlagVarBase = "CMAKE_"; diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx index de150ee..6abf6bf 100644 --- a/Source/cmXCodeObject.cxx +++ b/Source/cmXCodeObject.cxx @@ -38,7 +38,6 @@ cmXCodeObject::~cmXCodeObject() cmXCodeObject::cmXCodeObject(PBXType ptype, Type type) { this->Version = 15; - this->PBXTargetDependencyValue = 0; this->Target = 0; this->Object =0; diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h index bb2d5b2..b89f78c 100644 --- a/Source/cmXCodeObject.h +++ b/Source/cmXCodeObject.h @@ -120,14 +120,6 @@ public: return 0; } - cmXCodeObject* GetPBXTargetDependency() - { - return this->PBXTargetDependencyValue; - } - void SetPBXTargetDependency(cmXCodeObject* d) - { - this->PBXTargetDependencyValue = d; - } void CopyAttributes(cmXCodeObject* ); void AddDependLibrary(const char* configName, @@ -170,7 +162,6 @@ protected: cmStdString Comment; cmStdString String; cmXCodeObject* Object; - cmXCodeObject* PBXTargetDependencyValue; std::vector<cmXCodeObject*> List; std::map<cmStdString, StringVec> DependLibraries; std::map<cmStdString, StringVec> DependTargets; |