Allow export of targets with INTERFACE_SOURCES.

Use the same rules for paths in source and binary dirs in
installed INTERFACE_SOURCES as are used for
INTERFACE_INCLUDE_DIRECTORIES.
This commit is contained in:
Stephen Kelly 2014-11-28 18:58:38 +01:00
parent 736bcb9664
commit 6da65b3907
33 changed files with 260 additions and 90 deletions

View File

@ -22,10 +22,6 @@ items will populate the :prop_tgt:`SOURCES` property of
following arguments specify sources. Repeated calls for the same following arguments specify sources. Repeated calls for the same
``<target>`` append items in the order called. ``<target>`` append items in the order called.
Targets with :prop_tgt:`INTERFACE_SOURCES` may not be exported with the
:command:`export` or :command:`install(EXPORT)` commands. This limitation may be
lifted in a future version of CMake.
Arguments to ``target_sources`` may use "generator expressions" Arguments to ``target_sources`` may use "generator expressions"
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)`

View File

@ -12,10 +12,6 @@ When target dependencies are specified using :command:`target_link_libraries`,
CMake will read this property from all target dependencies to determine the CMake will read this property from all target dependencies to determine the
sources of the consumer. sources of the consumer.
Targets with ``INTERFACE_SOURCES`` may not be exported with the
:command:`export` or :command:`install(EXPORT)` commands. This limitation may be
lifted in a future version of CMake.
Contents of ``INTERFACE_SOURCES`` may use "generator expressions" Contents of ``INTERFACE_SOURCES`` may use "generator expressions"
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)`

View File

@ -68,16 +68,6 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
tei != this->Exports.end(); ++tei) tei != this->Exports.end(); ++tei)
{ {
cmTarget* te = *tei; cmTarget* te = *tei;
if (te->GetProperty("INTERFACE_SOURCES"))
{
std::ostringstream e;
e << "Target \""
<< te->GetName()
<< "\" has a populated INTERFACE_SOURCES property. This is not "
"currently supported.";
cmSystemTools::Error(e.str().c_str());
return false;
}
this->GenerateImportTargetCode(os, te); this->GenerateImportTargetCode(os, te);
te->AppendBuildInterfaceIncludes(); te->AppendBuildInterfaceIncludes();
@ -87,6 +77,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te, this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
cmGeneratorExpression::BuildInterface, cmGeneratorExpression::BuildInterface,
properties, missingTargets); properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_SOURCES", te,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te, this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
cmGeneratorExpression::BuildInterface, cmGeneratorExpression::BuildInterface,
properties, missingTargets); properties, missingTargets);

View File

@ -224,7 +224,7 @@ static bool isSubDirectory(const char* a, const char* b)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool checkInterfaceDirs(const std::string &prepro, static bool checkInterfaceDirs(const std::string &prepro,
cmTarget *target) cmTarget *target, const std::string& prop)
{ {
const char* installDir = const char* installDir =
target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
@ -249,6 +249,8 @@ static bool checkInterfaceDirs(const std::string &prepro,
cmake::MessageType messageType = cmake::FATAL_ERROR; cmake::MessageType messageType = cmake::FATAL_ERROR;
std::ostringstream e; std::ostringstream e;
if (genexPos != std::string::npos) if (genexPos != std::string::npos)
{
if (prop == "INTERFACE_INCLUDE_DIRECTORIES")
{ {
switch (target->GetPolicyStatusCMP0041()) switch (target->GetPolicyStatusCMP0041())
{ {
@ -266,14 +268,19 @@ static bool checkInterfaceDirs(const std::string &prepro,
break; // Issue fatal message. break; // Issue fatal message.
} }
} }
else
{
hadFatalError = true;
}
}
if (cmHasLiteralPrefix(li->c_str(), "${_IMPORT_PREFIX}")) if (cmHasLiteralPrefix(li->c_str(), "${_IMPORT_PREFIX}"))
{ {
continue; continue;
} }
if (!cmSystemTools::FileIsFullPath(li->c_str())) if (!cmSystemTools::FileIsFullPath(li->c_str()))
{ {
e << "Target \"" << target->GetName() << "\" " e << "Target \"" << target->GetName() << "\" " << prop <<
"INTERFACE_INCLUDE_DIRECTORIES property contains relative path:\n" " property contains relative path:\n"
" \"" << *li << "\""; " \"" << *li << "\"";
target->GetMakefile()->IssueMessage(messageType, e.str()); target->GetMakefile()->IssueMessage(messageType, e.str());
} }
@ -289,6 +296,8 @@ static bool checkInterfaceDirs(const std::string &prepro,
(!inBinary || isSubDirectory(installDir, topBinaryDir)) && (!inBinary || isSubDirectory(installDir, topBinaryDir)) &&
(!inSource || isSubDirectory(installDir, topSourceDir)); (!inSource || isSubDirectory(installDir, topSourceDir));
if (prop == "INTERFACE_INCLUDE_DIRECTORIES")
{
if (!shouldContinue) if (!shouldContinue)
{ {
switch(target->GetPolicyStatusCMP0052()) switch(target->GetPolicyStatusCMP0052())
@ -317,6 +326,7 @@ static bool checkInterfaceDirs(const std::string &prepro,
break; break;
} }
} }
}
if (shouldContinue) if (shouldContinue)
{ {
continue; continue;
@ -324,8 +334,8 @@ static bool checkInterfaceDirs(const std::string &prepro,
} }
if (inBinary) if (inBinary)
{ {
e << "Target \"" << target->GetName() << "\" " e << "Target \"" << target->GetName() << "\" " << prop <<
"INTERFACE_INCLUDE_DIRECTORIES property contains path:\n" " property contains path:\n"
" \"" << *li << "\"\nwhich is prefixed in the build directory."; " \"" << *li << "\"\nwhich is prefixed in the build directory.";
target->GetMakefile()->IssueMessage(messageType, e.str()); target->GetMakefile()->IssueMessage(messageType, e.str());
} }
@ -333,8 +343,8 @@ static bool checkInterfaceDirs(const std::string &prepro,
{ {
if (inSource) if (inSource)
{ {
e << "Target \"" << target->GetName() << "\" " e << "Target \"" << target->GetName() << "\" " << prop <<
"INTERFACE_INCLUDE_DIRECTORIES property contains path:\n" " property contains path:\n"
" \"" << *li << "\"\nwhich is prefixed in the source directory."; " \"" << *li << "\"\nwhich is prefixed in the source directory.";
target->GetMakefile()->IssueMessage(messageType, e.str()); target->GetMakefile()->IssueMessage(messageType, e.str());
} }
@ -364,6 +374,46 @@ static void prefixItems(std::string &exportDirs)
} }
} }
//----------------------------------------------------------------------------
void cmExportFileGenerator::PopulateSourcesInterface(
cmTargetExport *tei,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets)
{
cmTarget *target = tei->Target;
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char *propName = "INTERFACE_SOURCES";
const char *input = target->GetProperty(propName);
if (!input)
{
return;
}
if (!*input)
{
properties[propName] = "";
return;
}
std::string prepro = cmGeneratorExpression::Preprocess(input,
preprocessRule,
true);
if (!prepro.empty())
{
this->ResolveTargetsInGeneratorExpressions(prepro, target,
missingTargets);
if (!checkInterfaceDirs(prepro, target, propName))
{
return;
}
properties[propName] = prepro;
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
cmTargetExport *tei, cmTargetExport *tei,
@ -424,7 +474,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
this->ResolveTargetsInGeneratorExpressions(prepro, target, this->ResolveTargetsInGeneratorExpressions(prepro, target,
missingTargets); missingTargets);
if (!checkInterfaceDirs(prepro, target)) if (!checkInterfaceDirs(prepro, target, propName))
{ {
return; return;
} }

View File

@ -139,6 +139,11 @@ protected:
cmGeneratorExpression::PreprocessContext preprocessRule, cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap &properties, ImportPropertyMap &properties,
std::vector<std::string> &missingTargets); std::vector<std::string> &missingTargets);
void PopulateSourcesInterface(
cmTargetExport *target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets);
void SetImportLinkInterface(const std::string& config, void SetImportLinkInterface(const std::string& config,
std::string const& suffix, std::string const& suffix,

View File

@ -123,6 +123,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
bool require2_8_12 = false; bool require2_8_12 = false;
bool require3_0_0 = false; bool require3_0_0 = false;
bool require3_1_0 = false;
bool requiresConfigFiles = false; bool requiresConfigFiles = false;
// Create all the imported targets. // Create all the imported targets.
for(std::vector<cmTargetExport*>::const_iterator for(std::vector<cmTargetExport*>::const_iterator
@ -131,17 +132,6 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
{ {
cmTarget* te = (*tei)->Target; cmTarget* te = (*tei)->Target;
if (te->GetProperty("INTERFACE_SOURCES"))
{
std::ostringstream e;
e << "Target \""
<< te->GetName()
<< "\" has a populated INTERFACE_SOURCES property. This is not "
"currently supported.";
cmSystemTools::Error(e.str().c_str());
return false;
}
requiresConfigFiles = requiresConfigFiles requiresConfigFiles = requiresConfigFiles
|| te->GetType() != cmTarget::INTERFACE_LIBRARY; || te->GetType() != cmTarget::INTERFACE_LIBRARY;
@ -152,6 +142,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateIncludeDirectoriesInterface(*tei, this->PopulateIncludeDirectoriesInterface(*tei,
cmGeneratorExpression::InstallInterface, cmGeneratorExpression::InstallInterface,
properties, missingTargets); properties, missingTargets);
this->PopulateSourcesInterface(*tei,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
te, te,
cmGeneratorExpression::InstallInterface, cmGeneratorExpression::InstallInterface,
@ -190,6 +183,13 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
{ {
require3_0_0 = true; require3_0_0 = true;
} }
if(te->GetProperty("INTERFACE_SOURCES"))
{
// We can only generate INTERFACE_SOURCES in CMake 3.3, but CMake 3.1
// can consume them.
require3_1_0 = true;
}
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
te, properties); te, properties);
this->PopulateCompatibleInterfaceProperties(te, properties); this->PopulateCompatibleInterfaceProperties(te, properties);
@ -197,7 +197,11 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateInterfaceProperties(te, os, properties); this->GenerateInterfaceProperties(te, os, properties);
} }
if (require3_0_0) if (require3_1_0)
{
this->GenerateRequiredCMakeVersion(os, "3.1.0");
}
else if (require3_0_0)
{ {
this->GenerateRequiredCMakeVersion(os, "3.0.0"); this->GenerateRequiredCMakeVersion(os, "3.0.0");
} }

View File

@ -29,7 +29,17 @@ target_compile_features(use_auto_type INTERFACE cxx_auto_type)
add_library(use_c_restrict INTERFACE) add_library(use_c_restrict INTERFACE)
target_compile_features(use_c_restrict INTERFACE c_restrict) target_compile_features(use_c_restrict INTERFACE c_restrict)
install(TARGETS headeronly sharediface use_auto_type use_c_restrict add_library(source_target INTERFACE)
target_sources(source_target INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/source_target.cpp>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/src/source_target_for_install.cpp>
)
install(FILES
source_target_for_install.cpp
DESTINATION src
)
install(TARGETS headeronly sharediface use_auto_type use_c_restrict source_target
EXPORT expInterface EXPORT expInterface
) )
install(TARGETS sharedlib install(TARGETS sharedlib

View File

@ -0,0 +1,13 @@
#ifndef USE_FROM_BUILD_DIR
#error Expected define USE_FROM_BUILD_DIR
#endif
#ifdef USE_FROM_INSTALL_DIR
#error Unexpected define USE_FROM_INSTALL_DIR
#endif
int source_symbol()
{
return 42;
}

View File

@ -0,0 +1,13 @@
#ifdef USE_FROM_BUILD_DIR
#error Unexpected define USE_FROM_BUILD_DIR
#endif
#ifndef USE_FROM_INSTALL_DIR
#error Expected define USE_FROM_INSTALL_DIR
#endif
int source_symbol()
{
return 42;
}

View File

@ -82,6 +82,14 @@ endmacro()
do_try_compile(bld) do_try_compile(bld)
add_executable(source_target_test_bld source_target_test.cpp)
target_link_libraries(source_target_test_bld bld::source_target)
target_compile_definitions(source_target_test_bld PRIVATE USE_FROM_BUILD_DIR)
add_executable(source_target_test_exp source_target_test.cpp)
target_link_libraries(source_target_test_exp exp::source_target)
target_compile_definitions(source_target_test_exp PRIVATE USE_FROM_INSTALL_DIR)
add_executable(headeronlytest_exp headeronlytest.cpp) add_executable(headeronlytest_exp headeronlytest.cpp)
target_link_libraries(headeronlytest_exp exp::headeronly) target_link_libraries(headeronlytest_exp exp::headeronly)

View File

@ -0,0 +1,7 @@
extern int source_symbol();
int main()
{
return source_symbol() - 42;
}

View File

@ -192,6 +192,9 @@ add_RunCMake_test(ExternalProject)
set(IfacePaths_INCLUDE_DIRECTORIES_ARGS -DTEST_PROP=INCLUDE_DIRECTORIES) set(IfacePaths_INCLUDE_DIRECTORIES_ARGS -DTEST_PROP=INCLUDE_DIRECTORIES)
add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths) add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths)
set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES)
add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths)
if(RPMBUILD) if(RPMBUILD)
add_RunCMake_test(CPackRPM) add_RunCMake_test(CPackRPM)
endif() endif()

View File

@ -0,0 +1,6 @@
CMake Error in CMakeLists.txt:
Target "testTarget" INTERFACE_SOURCES property contains path:
".*Tests/RunCMake/IfacePaths_SOURCES/prefix/BinInInstallPrefix-build/empty.cpp"
which is prefixed in the build directory.

View File

@ -0,0 +1,6 @@
CMake Error in CMakeLists.txt:
Target "testTarget" INTERFACE_SOURCES property contains path:
".*Tests/RunCMake/IfacePaths_SOURCES/BinaryDirectoryInInterface-build/empty.cpp"
which is prefixed in the build directory.

View File

@ -2,7 +2,11 @@
enable_language(CXX) enable_language(CXX)
add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/foo") if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foo")
else()
set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/empty.cpp")
endif()
install(TARGETS testTarget EXPORT testTargets install(TARGETS testTarget EXPORT testTargets
DESTINATION lib DESTINATION lib

View File

@ -1,6 +1,11 @@
enable_language(CXX) enable_language(CXX)
add_library(testTarget empty.cpp) add_library(testTarget empty.cpp)
target_include_directories(testTarget INTERFACE "${CMAKE_INSTALL_PREFIX}/dir")
if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/dir")
else()
set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_INSTALL_PREFIX}/empty.cpp")
endif()
install(TARGETS testTarget EXPORT testTargets install(TARGETS testTarget EXPORT testTargets
DESTINATION lib DESTINATION lib

View File

@ -0,0 +1,6 @@
CMake Error in CMakeLists.txt:
Target "testTarget" INTERFACE_SOURCES property contains path:
".*Tests/RunCMake/IfacePaths_SOURCES/InstallInBinDir-build/empty.cpp"
which is prefixed in the build directory.

View File

@ -0,0 +1,6 @@
CMake Error in CMakeLists.txt:
Target "testTarget" INTERFACE_SOURCES property contains path:
".*Tests/RunCMake/IfacePaths_SOURCES/copy/empty.cpp"
which is prefixed in the source directory.

View File

@ -0,0 +1,4 @@
CMake Error in CMakeLists.txt:
Target "testTarget" contains relative path in its INTERFACE_SOURCES:
"empty.cpp"

View File

@ -2,7 +2,12 @@
enable_language(CXX) enable_language(CXX)
add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<1:foo>")
if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<1:foo>")
else()
set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "$<1:empty.cpp>")
endif()
add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
target_link_libraries(userTarget testTarget) target_link_libraries(userTarget testTarget)

View File

@ -0,0 +1,4 @@
CMake Error in CMakeLists.txt:
Target "testTarget" INTERFACE_SOURCES property contains relative path:
"empty.cpp"

View File

@ -2,8 +2,11 @@
enable_language(CXX) enable_language(CXX)
add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo") if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo")
else()
set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "empty.cpp")
endif()
install(TARGETS testTarget EXPORT testTargets install(TARGETS testTarget EXPORT testTargets
DESTINATION lib DESTINATION lib
) )

View File

@ -0,0 +1,6 @@
CMake Error in CMakeLists.txt:
Target "testTarget" INTERFACE_SOURCES property contains path:
".*Tests/RunCMake/IfacePaths/empty.cpp"
which is prefixed in the source directory.

View File

@ -2,7 +2,11 @@
enable_language(CXX) enable_language(CXX)
add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/foo") if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/foo")
else()
set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
endif()
install(TARGETS testTarget EXPORT testTargets install(TARGETS testTarget EXPORT testTargets
DESTINATION lib DESTINATION lib

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,6 @@
CMake Error in CMakeLists.txt:
Target "testTarget" INTERFACE_SOURCES property contains path:
".*Tests/RunCMake/IfacePaths_SOURCES/prefix/src/empty.cpp"
which is prefixed in the source directory.

View File

@ -1,19 +1,34 @@
enable_language(CXX) enable_language(CXX)
add_library(foo empty.cpp) add_library(foo empty.cpp)
set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<0:>/include/subdir) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<0:>/include/subdir)
set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_PREFIX>/include/subdir) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_PREFIX>/include/subdir)
set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<0:>/include/subdir/empty.cpp)
set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_PREFIX>/include/subdir/empty.cpp)
set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/subdir>) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/subdir>)
set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/subdir>) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/subdir>)
set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/$<0:>>) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/$<0:>>)
set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<0:>/include>) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<0:>/include>)
set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/subdir/empty.cpp>)
set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:include/subdir/empty.cpp>)
set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:include/subdir/empty.cpp$<0:>>)
set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:$<0:>/include/subdir/empty.cpp>)
# target_include_directories(foo INTERFACE include/subdir) # Does and should warn. INSTALL_INTERFACE must not list src dir paths. # target_include_directories(foo INTERFACE include/subdir) # Does and should warn. INSTALL_INTERFACE must not list src dir paths.
target_include_directories(foo INTERFACE $<0:>/include/subdir) # Does not and should not should warn, because it starts with a genex. target_include_directories(foo INTERFACE $<0:>/include/subdir) # Does not and should not should warn, because it starts with a genex.
target_include_directories(foo INTERFACE $<INSTALL_PREFIX>/include/subdir) target_include_directories(foo INTERFACE $<INSTALL_PREFIX>/include/subdir)
target_sources(foo INTERFACE $<0:>/include/subdir/empty.cpp)
target_sources(foo INTERFACE $<INSTALL_PREFIX>/include/subdir/empty.cpp)
target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/subdir>) target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/subdir>)
target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/$<0:>>) target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/$<0:>>)
target_sources(foo INTERFACE $<INSTALL_INTERFACE:include/subdir/empty.cpp>)
target_sources(foo INTERFACE $<INSTALL_INTERFACE:include/subdir/empty.cpp$<0:>>)
install(FILES include/subdir/empty.cpp
DESTINATION include/subdir
)
install(TARGETS foo EXPORT FooTargets DESTINATION lib) install(TARGETS foo EXPORT FooTargets DESTINATION lib)
install(EXPORT FooTargets DESTINATION lib/cmake) install(EXPORT FooTargets DESTINATION lib/cmake)

View File

@ -1 +0,0 @@
CMake Error: Target "iface" has a populated INTERFACE_SOURCES property. This is not currently supported.

View File

@ -1 +0,0 @@
CMake Error: Target "iface" has a populated INTERFACE_SOURCES property. This is not currently supported.

View File

@ -1,6 +0,0 @@
add_library(iface INTERFACE)
target_sources(iface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp")
install(TARGETS iface EXPORT exp)
install(EXPORT exp DESTINATION cmake)

View File

@ -10,4 +10,3 @@ endif()
run_cmake(CMP0026-LOCATION) run_cmake(CMP0026-LOCATION)
run_cmake(RelativePathInInterface) run_cmake(RelativePathInInterface)
run_cmake(ExportBuild) run_cmake(ExportBuild)
run_cmake(ExportInstall)