From 3a1719793fa4eb4024e2e36e17196832551d469c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 27 Jan 2013 09:42:54 +0100 Subject: [PATCH 1/2] Generate the _IMPORT_PREFIX in the non-config export file. --- Source/cmExportInstallFileGenerator.cxx | 57 ++++++++++++------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index a35f5cf6e..c7e3581d7 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -69,6 +69,27 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->GenerateExpectedTargetsCode(os, expectedTargets); } + // Add code to compute the installation prefix relative to the + // import file location. + 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()) + { + os << + "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n"; + dest = cmSystemTools::GetFilenamePath(dest); + } + os << "\n"; + + // Import location properties may reference this variable. + this->ImportPrefix = "${_IMPORT_PREFIX}/"; + } + std::vector missingTargets; // Create all the imported targets. @@ -107,6 +128,13 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) << "endforeach()\n" << "\n"; + // Cleanup the import prefix variable. + if(!this->ImportPrefix.empty()) + { + os << "# Cleanup temporary variables.\n" + << "set(_IMPORT_PREFIX)\n" + << "\n"; + } this->GenerateImportedFileCheckLoop(os); // Generate an import file for each configuration. @@ -187,27 +215,6 @@ cmExportInstallFileGenerator const char* config, std::string const& suffix, std::vector &missingTargets) { - // Add code to compute the installation prefix relative to the - // import file location. - 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()) - { - os << - "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n"; - dest = cmSystemTools::GetFilenamePath(dest); - } - os << "\n"; - - // Import location properties may reference this variable. - this->ImportPrefix = "${_IMPORT_PREFIX}/"; - } - // Add each target in the set to the export. for(std::vector::const_iterator tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); @@ -253,14 +260,6 @@ cmExportInstallFileGenerator importedLocations); } } - - // Cleanup the import prefix variable. - if(!this->ImportPrefix.empty()) - { - os << "# Cleanup temporary variables.\n" - << "set(_IMPORT_PREFIX)\n" - << "\n"; - } } //---------------------------------------------------------------------------- From 34d1ade048a87953c089d730f0126eecb6685968 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 27 Jan 2013 09:43:44 +0100 Subject: [PATCH 2/2] Add the INSTALL_PREFIX genex. --- Source/cmDocumentGeneratorExpressions.h | 2 ++ Source/cmExportFileGenerator.cxx | 10 ++++++++++ Source/cmExportFileGenerator.h | 2 ++ Source/cmExportInstallFileGenerator.cxx | 15 +++++++++++++++ Source/cmExportInstallFileGenerator.h | 2 ++ Source/cmGeneratorExpressionEvaluator.cxx | 20 ++++++++++++++++++++ Tests/ExportImport/Export/CMakeLists.txt | 17 ++++++++++++++++- Tests/GeneratorExpression/CMakeLists.txt | 1 + Tests/GeneratorExpression/check-part2.cmake | 1 + 9 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index be9f2ffa7..8b80a8a32 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -55,6 +55,8 @@ "the 'head' target was created, else '0'. If the policy was not " \ "set, the warning message for the policy will be emitted. This " \ "generator expression only works for a subset of policies.\n" \ + " $ = Content of the install prefix when " \ + "the target is exported via INSTALL(EXPORT) and empty otherwise.\n" \ "Boolean expressions:\n" \ " $ = '1' if all '?' are '1', else '0'\n" \ " $ = '0' if all '?' are '0', else '1'\n" \ diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 96e0aea0e..2ae7138bd 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -431,12 +431,22 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression( input.replace(pos, endPos - pos + 1, targetName); lastPos = endPos; } + + this->ReplaceInstallPrefix(input); + if (!errorString.empty()) { mf->IssueMessage(cmake::FATAL_ERROR, errorString); } } +//---------------------------------------------------------------------------- +void +cmExportFileGenerator::ReplaceInstallPrefix(std::string &) +{ + // Do nothing +} + //---------------------------------------------------------------------------- void cmExportFileGenerator diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index b39df0f8b..776be614d 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -152,6 +152,8 @@ private: void ResolveTargetsInGeneratorExpression(std::string &input, cmTarget* target, std::vector &missingTargets); + + virtual void ReplaceInstallPrefix(std::string &input); }; #endif diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index c7e3581d7..b6600f0b4 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -154,6 +154,21 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) return result; } +//---------------------------------------------------------------------------- +void +cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string &input) +{ + std::string::size_type pos = 0; + std::string::size_type lastPos = pos; + + while((pos = input.find("$", lastPos)) != input.npos) + { + std::string::size_type endPos = pos + sizeof("$") - 1; + input.replace(pos, endPos - pos, "${_IMPORT_PREFIX}"); + lastPos = endPos; + } +} + //---------------------------------------------------------------------------- bool cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config, diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index e1877499d..7a704311e 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -64,6 +64,8 @@ protected: cmTarget* depender, cmTarget* dependee); + virtual void ReplaceInstallPrefix(std::string &input); + void ComplainAboutMissingTarget(cmTarget* depender, cmTarget* dependee, int occurrences); diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 0c61a122f..f74b69e5f 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -614,6 +614,24 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode } targetPolicyNode; +//---------------------------------------------------------------------------- +static const struct InstallPrefixNode : public cmGeneratorExpressionNode +{ + InstallPrefixNode() {} + + virtual bool GeneratesContent() const { return false; } + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return std::string(); + } + +} installPrefixNode; + //---------------------------------------------------------------------------- template struct TargetFilesystemArtifactResultCreator @@ -849,6 +867,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &installInterfaceNode; else if (identifier == "TARGET_DEFINED") return &targetDefinedNode; + else if (identifier == "INSTALL_PREFIX") + return &installPrefixNode; return 0; } diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index eecfd6a31..cfcd9fa88 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -113,9 +113,16 @@ macro(add_include_lib _libName) add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_libName}") set_property(TARGET ${_libName} APPEND PROPERTY - INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/${_libName}") + INTERFACE_INCLUDE_DIRECTORIES + "$" + "$/include/${_libName}>" + ) if (NOT "${ARGV1}" STREQUAL "NO_HEADER") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "// no content\n") + install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" + DESTINATION include/${_libName} + ) endif() endmacro() @@ -129,6 +136,10 @@ add_include_lib(testLibIncludeRequired3 NO_HEADER) # but we are testing that the INSTALL_INTERFACE causes it not to be used # at build time. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h" "#error Should not be included\n") +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h" + DESTINATION include/testLibIncludeRequired3 +) add_include_lib(testLibIncludeRequired4) add_include_lib(testLibIncludeRequired5 NO_HEADER) # Generate testLibIncludeRequired6 in the testLibIncludeRequired5 directory @@ -139,6 +150,10 @@ add_include_lib(testLibIncludeRequired5 NO_HEADER) # the Import side of this unit test, the '6' include from the '5' directory # will not be used because it is in the BUILD_INTERFACE only. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h" "#error Should not be included\n") +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h" + DESTINATION include/testLibIncludeRequired5 +) add_include_lib(testLibIncludeRequired6) set_property(TARGET testLibRequired APPEND PROPERTY diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index ecbbedf44..a40a54124 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -89,6 +89,7 @@ add_custom_target(check-part2 ALL -Dtest_install_interface=$ -Dtest_target_name_1=$ -Dtest_target_name_2=$ + -Dtest_install_prefix=$ -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 2)" VERBATIM diff --git a/Tests/GeneratorExpression/check-part2.cmake b/Tests/GeneratorExpression/check-part2.cmake index 8855a977c..0b502045d 100644 --- a/Tests/GeneratorExpression/check-part2.cmake +++ b/Tests/GeneratorExpression/check-part2.cmake @@ -26,3 +26,4 @@ check(test_build_interface "build") check(test_install_interface "") check(test_target_name_1 "tgt,ok") check(test_target_name_2 "tgt:ok") +check(test_install_prefix "")