summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx36
-rw-r--r--Source/CTest/cmCTestGIT.cxx4
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx15
-rw-r--r--Source/cmCacheManager.cxx24
-rw-r--r--Source/cmComputeLinkInformation.cxx2
-rw-r--r--Source/cmCoreTryCompile.cxx108
-rw-r--r--Source/cmDocumentGeneratorExpressions.h3
-rw-r--r--Source/cmDocumentVariables.cxx9
-rw-r--r--Source/cmEnableLanguageCommand.h7
-rw-r--r--Source/cmExportFileGenerator.cxx46
-rw-r--r--Source/cmExportInstallFileGenerator.cxx36
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx114
-rw-r--r--Source/cmExportTryCompileFileGenerator.h55
-rw-r--r--Source/cmFindPackageCommand.cxx3
-rw-r--r--Source/cmGeneratorExpression.cxx24
-rw-r--r--Source/cmGeneratorExpression.h9
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx10
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h4
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx137
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h3
-rw-r--r--Source/cmGlobalGenerator.cxx42
-rw-r--r--Source/cmGlobalGenerator.h1
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.cxx28
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx71
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx79
-rw-r--r--Source/cmInstallExportGenerator.h2
-rw-r--r--Source/cmLocalGenerator.h10
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx28
-rw-r--r--Source/cmLocalVisualStudio7Generator.h2
-rw-r--r--Source/cmQtAutomoc.cxx27
-rw-r--r--Source/cmQtAutomoc.h1
-rw-r--r--Source/cmStringCommand.h7
-rw-r--r--Source/cmTarget.cxx154
-rw-r--r--Source/cmTarget.h2
-rw-r--r--Source/cmTryCompileCommand.h8
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx2
-rw-r--r--Source/cmXCodeObject.cxx1
-rw-r--r--Source/cmXCodeObject.h9
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> &parameters,
- 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;