mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 05:40:54 -06:00
Merge topic 'export-properties'
6db61f0725 Export: allow exporting of additional properties
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1834
This commit is contained in:
@@ -176,6 +176,7 @@ Properties on Targets
|
||||
/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG
|
||||
/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD
|
||||
/prop_tgt/EXPORT_NAME
|
||||
/prop_tgt/EXPORT_PROPERTIES
|
||||
/prop_tgt/FOLDER
|
||||
/prop_tgt/Fortran_FORMAT
|
||||
/prop_tgt/Fortran_MODULE_DIRECTORY
|
||||
|
||||
14
Help/prop_tgt/EXPORT_PROPERTIES.rst
Normal file
14
Help/prop_tgt/EXPORT_PROPERTIES.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
EXPORT_PROPERTIES
|
||||
-----------------
|
||||
|
||||
List additional properties to export for a target.
|
||||
|
||||
This property contains a list of property names that should be exported by
|
||||
the :command:`install(EXPORT)` and :command:`export` commands. By default
|
||||
only a limited number of properties are exported. This property can be used
|
||||
to additionally export other properties as well.
|
||||
|
||||
Properties starting with ``INTERFACE_`` or ``IMPORTED_`` are not allowed as
|
||||
they are reserved for internal CMake use.
|
||||
|
||||
Properties containing generator expressions are also not allowed.
|
||||
6
Help/release/dev/export-properties.rst
Normal file
6
Help/release/dev/export-properties.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
EXPORT_PROPERTIES
|
||||
-----------------
|
||||
|
||||
* An :prop_tgt:`EXPORT_PROPERTIES` target property was added to specify a
|
||||
custom list of target properties to include in targets exported by the
|
||||
:command:`install(EXPORT)` and :command:`export` commands.
|
||||
@@ -97,6 +97,15 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gte,
|
||||
properties);
|
||||
|
||||
std::string errorMessage;
|
||||
if (!this->PopulateExportProperties(gte, properties, errorMessage)) {
|
||||
this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
|
||||
cmake::FATAL_ERROR, errorMessage,
|
||||
this->LG->GetMakefile()->GetBacktrace());
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool newCMP0022Behavior =
|
||||
gte->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
|
||||
gte->GetPolicyStatusCMP0022() != cmPolicies::OLD;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "cmMakefile.h"
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmProperty.h"
|
||||
#include "cmPropertyMap.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
@@ -1097,3 +1099,41 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
|
||||
|
||||
os << ")\n\n";
|
||||
}
|
||||
|
||||
bool cmExportFileGenerator::PopulateExportProperties(
|
||||
cmGeneratorTarget* gte, ImportPropertyMap& properties,
|
||||
std::string& errorMessage)
|
||||
{
|
||||
auto& targetProperties = gte->Target->GetProperties();
|
||||
const auto& exportProperties = targetProperties.find("EXPORT_PROPERTIES");
|
||||
if (exportProperties != targetProperties.end()) {
|
||||
std::vector<std::string> propsToExport;
|
||||
cmSystemTools::ExpandListArgument(exportProperties->second.GetValue(),
|
||||
propsToExport);
|
||||
for (auto& prop : propsToExport) {
|
||||
/* Black list reserved properties */
|
||||
if (cmSystemTools::StringStartsWith(prop, "IMPORTED_") ||
|
||||
cmSystemTools::StringStartsWith(prop, "INTERFACE_")) {
|
||||
std::ostringstream e;
|
||||
e << "Target \"" << gte->Target->GetName() << "\" contains property \""
|
||||
<< prop << "\" in EXPORT_PROPERTIES but IMPORTED_* and INTERFACE_* "
|
||||
<< "properties are reserved.";
|
||||
errorMessage = e.str();
|
||||
return false;
|
||||
}
|
||||
auto propertyValue = targetProperties.GetPropertyValue(prop);
|
||||
std::string evaluatedValue = cmGeneratorExpression::Preprocess(
|
||||
propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
|
||||
if (evaluatedValue != propertyValue) {
|
||||
std::ostringstream e;
|
||||
e << "Target \"" << gte->Target->GetName() << "\" contains property \""
|
||||
<< prop << "\" in EXPORT_PROPERTIES but this property contains a "
|
||||
<< "generator expression. This is not allowed.";
|
||||
errorMessage = e.str();
|
||||
return false;
|
||||
}
|
||||
properties[prop] = propertyValue;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -168,6 +168,10 @@ protected:
|
||||
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
|
||||
const char* versionString);
|
||||
|
||||
bool PopulateExportProperties(cmGeneratorTarget* gte,
|
||||
ImportPropertyMap& properties,
|
||||
std::string& errorMessage);
|
||||
|
||||
// The namespace in which the exports are placed in the generated file.
|
||||
std::string Namespace;
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
|
||||
std::string errorMessage;
|
||||
if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
|
||||
cmSystemTools::Error(errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool newCMP0022Behavior =
|
||||
gt->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
|
||||
gt->GetPolicyStatusCMP0022() != cmPolicies::OLD;
|
||||
|
||||
@@ -356,6 +356,14 @@ install(FILES
|
||||
|
||||
set_property(TARGET testLib2 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USING_TESTLIB2)
|
||||
set_property(TARGET testLib3 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USING_TESTLIB3)
|
||||
set_target_properties(testLib3 PROPERTIES
|
||||
EXPORT_PROPERTIES "EXPORTED_PROPERTY1"
|
||||
EXPORTED_PROPERTY1 "EXPORTING_TESTLIB3")
|
||||
set_target_properties(testLib4 PROPERTIES
|
||||
EXPORTED_PROPERTY2 "EXPORTING_TESTLIB4_1"
|
||||
EXPORTED_PROPERTY3 "EXPORTING_TESTLIB4_2")
|
||||
set_property(TARGET testLib4 PROPERTY
|
||||
EXPORT_PROPERTIES EXPORTED_PROPERTY2 EXPORTED_PROPERTY3)
|
||||
|
||||
set_property(TARGET cmp0022NEW APPEND PROPERTY INTERFACE_LINK_LIBRARIES testLib2)
|
||||
# set_property(TARGET cmp0022NEW APPEND PROPERTY LINK_INTERFACE_LIBRARIES testLibIncludeRequired2) # TODO: Test for error
|
||||
|
||||
@@ -32,6 +32,20 @@ add_executable(imp_testExe1
|
||||
${Import_BINARY_DIR}/exp_generated4.c
|
||||
)
|
||||
|
||||
function(checkForProperty _TARGET _PROP _EXPECTED)
|
||||
get_target_property(EXPORTED_PROPERTY ${_TARGET} "${_PROP}")
|
||||
if (NOT EXPORTED_PROPERTY STREQUAL "${_EXPECTED}")
|
||||
message(SEND_ERROR "${_TARGET} was expected to export \"${_PROP}\" with value \"${_EXPECTED}\" but got \"${EXPORTED_PROPERTY}\"")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
checkForProperty(bld_testLib3 "EXPORTED_PROPERTY1" "EXPORTING_TESTLIB3")
|
||||
checkForProperty(exp_testLib3 "EXPORTED_PROPERTY1" "EXPORTING_TESTLIB3")
|
||||
checkForProperty(bld_testLib4 "EXPORTED_PROPERTY2" "EXPORTING_TESTLIB4_1")
|
||||
checkForProperty(exp_testLib4 "EXPORTED_PROPERTY2" "EXPORTING_TESTLIB4_1")
|
||||
checkForProperty(bld_testLib4 "EXPORTED_PROPERTY3" "EXPORTING_TESTLIB4_2")
|
||||
checkForProperty(exp_testLib4 "EXPORTED_PROPERTY3" "EXPORTING_TESTLIB4_2")
|
||||
|
||||
# Try linking to a library imported from the install tree.
|
||||
target_link_libraries(imp_testExe1
|
||||
exp_testLib2
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,3 @@
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target \"foo\" contains property \"IMPORTED_FOOBAR\" in EXPORT_PROPERTIES but
|
||||
IMPORTED_\* and INTERFACE_\* properties are reserved.
|
||||
@@ -0,0 +1,12 @@
|
||||
enable_language(CXX)
|
||||
add_library(foo empty.cpp)
|
||||
set_target_properties(foo PROPERTIES
|
||||
IMPORTED_FOOBAR "Some other string"
|
||||
EXPORT_PROPERTIES "IMPORTED_FOOBAR"
|
||||
)
|
||||
export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
|
||||
install(TARGETS foo EXPORT fooExport
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,3 @@
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target \"foo\" contains property \"INTERFACE_FOOBAR\" in EXPORT_PROPERTIES but
|
||||
IMPORTED_\* and INTERFACE_\* properties are reserved.
|
||||
@@ -0,0 +1,12 @@
|
||||
enable_language(CXX)
|
||||
add_library(foo empty.cpp)
|
||||
set_target_properties(foo PROPERTIES
|
||||
INTERFACE_FOOBAR "Some string"
|
||||
EXPORT_PROPERTIES "INTERFACE_FOOBAR"
|
||||
)
|
||||
export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
|
||||
install(TARGETS foo EXPORT fooExport
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,3 @@
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target \"foo\" contains property \"JUST_A_PROPERTY\" in EXPORT_PROPERTIES but
|
||||
this property contains a generator expression. This is not allowed.
|
||||
@@ -0,0 +1,12 @@
|
||||
enable_language(CXX)
|
||||
add_library(foo empty.cpp)
|
||||
set_target_properties(foo PROPERTIES
|
||||
JUST_A_PROPERTY "$<C_COMPILER_VERSION:0>"
|
||||
EXPORT_PROPERTIES "JUST_A_PROPERTY"
|
||||
)
|
||||
export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
|
||||
install(TARGETS foo EXPORT fooExport
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
@@ -5,3 +5,6 @@ run_cmake(TargetNotFound)
|
||||
run_cmake(AppendExport)
|
||||
run_cmake(OldIface)
|
||||
run_cmake(NoExportSet)
|
||||
run_cmake(ForbiddenToExportInterfaceProperties)
|
||||
run_cmake(ForbiddenToExportImportedProperties)
|
||||
run_cmake(ForbiddenToExportPropertyWithGenExp)
|
||||
|
||||
7
Tests/RunCMake/export/empty.cpp
Normal file
7
Tests/RunCMake/export/empty.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int empty()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user