Add includes and compile definitions with target_link_libraries.
This establishes that linking is used to propagate usage-requirements between targets in CMake code. The use of the target_link_libraries command as the API for this is chosen because introducing a new command would introduce confusion due to multiple commands which differ only in a subtle way.
This commit is contained in:
parent
0b92602b81
commit
77cecb778f
|
@ -514,6 +514,9 @@ public:
|
|||
|
||||
const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
|
||||
const char *config);
|
||||
|
||||
std::string GetDebugGeneratorExpressions(const std::string &value,
|
||||
cmTarget::LinkLibraryType llt);
|
||||
private:
|
||||
/**
|
||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||
|
@ -659,9 +662,6 @@ private:
|
|||
|
||||
void ProcessSourceExpression(std::string const& expr);
|
||||
|
||||
std::string GetDebugGeneratorExpressions(const std::string &value,
|
||||
cmTarget::LinkLibraryType llt);
|
||||
|
||||
// The cmMakefile instance that owns this target. This should
|
||||
// always be set.
|
||||
cmMakefile* Makefile;
|
||||
|
|
|
@ -249,11 +249,52 @@ cmTargetLinkLibrariesCommand
|
|||
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string compileProperty(cmTarget *tgt, const std::string &lib,
|
||||
bool isGenex,
|
||||
const std::string &property,
|
||||
cmTarget::LinkLibraryType llt)
|
||||
{
|
||||
std::string value = !isGenex ? "$<LINKED:" + lib + ">"
|
||||
: "$<$<TARGET_DEFINED:" + lib + ">:" +
|
||||
"$<TARGET_PROPERTY:" + lib +
|
||||
",INTERFACE_" + property + ">"
|
||||
">";
|
||||
|
||||
return tgt->GetDebugGeneratorExpressions(value, llt);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool isGeneratorExpression(const std::string &lib)
|
||||
{
|
||||
const std::string::size_type openpos = lib.find("$<");
|
||||
return (openpos != std::string::npos)
|
||||
&& (lib.find(">", openpos) != std::string::npos);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
||||
cmTarget::LinkLibraryType llt)
|
||||
{
|
||||
const bool isGenex = isGeneratorExpression(lib);
|
||||
|
||||
cmsys::RegularExpression targetNameValidator;
|
||||
targetNameValidator.compile("^[A-Za-z0-9_.:-]+$");
|
||||
const bool potentialTargetName = targetNameValidator.find(lib);
|
||||
|
||||
if (potentialTargetName || isGenex)
|
||||
{
|
||||
this->Target->AppendProperty("INCLUDE_DIRECTORIES",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"INCLUDE_DIRECTORIES", llt).c_str());
|
||||
this->Target->AppendProperty("COMPILE_DEFINITIONS",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"COMPILE_DEFINITIONS", llt).c_str());
|
||||
}
|
||||
|
||||
// Handle normal case first.
|
||||
if(this->CurrentProcessingState != ProcessingLinkInterface)
|
||||
{
|
||||
|
@ -266,6 +307,18 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
|||
}
|
||||
}
|
||||
|
||||
if (potentialTargetName || isGenex)
|
||||
{
|
||||
this->Target->AppendProperty("INTERFACE_COMPILE_DEFINITIONS",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"COMPILE_DEFINITIONS", llt).c_str());
|
||||
this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"INCLUDE_DIRECTORIES", llt).c_str());
|
||||
}
|
||||
|
||||
// Get the list of configurations considered to be DEBUG.
|
||||
std::vector<std::string> const& debugConfigs =
|
||||
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
|
||||
|
|
|
@ -97,6 +97,15 @@ public:
|
|||
"Calls to other signatures of this command may set the property "
|
||||
"making any libraries linked exclusively by this signature private."
|
||||
"\n"
|
||||
"Target usage requirements are also consumed by this command. If the "
|
||||
"<target> is linked to another target which has "
|
||||
"a populated INTERFACE_INCLUDE_DIRECTORIES, the content of it is "
|
||||
"appended to the INCLUDE_DIRECTORIES of <target>. Similarly, the "
|
||||
"INTERFACE_COMPILE_DEFINITONS of a dependee are added to the "
|
||||
"COMPILE_DEFINITONS of <target>, and the "
|
||||
"INTERFACE_POSITION_INDEPENDENT_CODE property is used to determine the "
|
||||
"POSITION_INDEPENDENT_CODE property of <target>."
|
||||
"\n"
|
||||
" target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
|
||||
" [[debug|optimized|general] <lib>] ...)\n"
|
||||
"The LINK_INTERFACE_LIBRARIES mode appends the libraries "
|
||||
|
|
|
@ -62,10 +62,6 @@ assert_property(targetA LINK_INTERFACE_LIBRARIES "")
|
|||
|
||||
add_subdirectory(subdir)
|
||||
target_link_libraries(targetA subdirlib)
|
||||
set_property(TARGET targetA APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:subdirlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
target_link_libraries(targetA depB depC)
|
||||
|
||||
|
@ -87,3 +83,24 @@ set_property(TARGET depD APPEND PROPERTY
|
|||
|
||||
add_executable(targetB targetB.cpp)
|
||||
target_link_libraries(targetB depD)
|
||||
|
||||
macro(create_header _name)
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "//${_name}.h\n")
|
||||
endmacro()
|
||||
|
||||
create_header(foo)
|
||||
create_header(bar)
|
||||
|
||||
add_library(depG SHARED depG.cpp)
|
||||
generate_export_header(depG)
|
||||
target_include_directories(depG INTERFACE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/foo"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/bar"
|
||||
)
|
||||
target_compile_definitions(depG INTERFACE
|
||||
TEST_DEF
|
||||
)
|
||||
|
||||
add_executable(targetC targetC.cpp)
|
||||
target_link_libraries(targetC depG)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "depG.h"
|
||||
|
||||
int DepG::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "depg_export.h"
|
||||
|
||||
struct DEPG_EXPORT DepG
|
||||
{
|
||||
int foo();
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
#include "depG.h"
|
||||
|
||||
#include "foo.h"
|
||||
#include "bar.h"
|
||||
|
||||
#ifndef TEST_DEF
|
||||
#error Expected TEST_DEF definition
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
DepG g;
|
||||
|
||||
return g.foo();
|
||||
}
|
|
@ -90,23 +90,7 @@ set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
|
|||
# Test exporting dependent libraries into different exports
|
||||
add_library(testLibRequired testLibRequired.c)
|
||||
add_library(testLibDepends testLibDepends.c)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
target_link_libraries(testLibDepends testLibRequired)
|
||||
target_link_libraries(testLibDepends LINK_PUBLIC testLibRequired)
|
||||
|
||||
macro(add_include_lib _libName)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "// no content\n")
|
||||
|
@ -239,6 +223,25 @@ install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DES
|
|||
install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
|
||||
install(EXPORT DependsExp FILE testLibDependsTargets.cmake DESTINATION lib/cmake/testLibDepends)
|
||||
|
||||
file(WRITE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfig.cmake"
|
||||
"
|
||||
if(\${CMAKE_FIND_PACKAGE_NAME}_FIND_VERSION VERSION_LESS 2.3 AND NOT \${CMAKE_FIND_PACKAGE_NAME}_INTERFACES)
|
||||
set(\${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES 1)
|
||||
endif()
|
||||
include(\"\${CMAKE_CURRENT_LIST_DIR}/testLibRequiredTargets.cmake\")
|
||||
set(\${CMAKE_FIND_PACKAGE_NAME}_INCLUDE_DIRS \"${CMAKE_CURRENT_BINARY_DIR}\" \"${CMAKE_CURRENT_SOURCE_DIR}\" )
|
||||
"
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file( testLibRequiredConfigVersion.cmake VERSION 2.5 COMPATIBILITY AnyNewerVersion)
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfigVersion.cmake"
|
||||
DESTINATION lib/cmake/testLibRequired
|
||||
)
|
||||
|
||||
# Install and export from install tree.
|
||||
install(
|
||||
|
|
|
@ -159,18 +159,11 @@ endif()
|
|||
|
||||
add_executable(deps_iface deps_iface.c)
|
||||
target_link_libraries(deps_iface testLibDepends)
|
||||
target_include_directories(deps_iface PRIVATE $<TARGET_PROPERTY:testLibDepends,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
target_compile_definitions(deps_iface PRIVATE $<TARGET_PROPERTY:testLibDepends,INTERFACE_COMPILE_DEFINITIONS>)
|
||||
|
||||
add_executable(deps_shared_iface deps_shared_iface.cpp)
|
||||
target_link_libraries(deps_shared_iface testSharedLibDepends)
|
||||
target_include_directories(deps_shared_iface
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_compile_definitions(deps_shared_iface
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_COMPILE_DEFINITIONS>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
|
||||
|
@ -200,13 +193,8 @@ endif()
|
|||
|
||||
add_executable(deps_shared_iface2 deps_shared_iface.cpp)
|
||||
target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
|
||||
target_include_directories(deps_shared_iface2
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:bld_testSharedLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:bld_subdirlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_compile_definitions(deps_shared_iface2
|
||||
PRIVATE $<TARGET_PROPERTY:bld_testSharedLibDepends,INTERFACE_COMPILE_DEFINITIONS> TEST_SUBDIR_LIB
|
||||
PRIVATE TEST_SUBDIR_LIB
|
||||
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
|
||||
|
|
|
@ -17,3 +17,8 @@ add_executable(imp_testTransExe1 imp_testTransExe1.c)
|
|||
target_link_libraries(imp_testTransExe1 imp_lib1)
|
||||
add_executable(imp_testTransExe1b imp_testTransExe1.c)
|
||||
target_link_libraries(imp_testTransExe1b imp_lib1b)
|
||||
|
||||
# Test package INTERFACE controls
|
||||
add_subdirectory(package_old_old)
|
||||
add_subdirectory(package_new_old)
|
||||
add_subdirectory(package_new_new)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
find_package(testLibRequired 2.5 REQUIRED)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"
|
||||
#include \"testSharedLibRequired.h\"
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if (NOT prop)
|
||||
message(SEND_ERROR "Interface of Req::testSharedLibRequired should not be empty")
|
||||
endif()
|
||||
|
||||
add_executable(new_new_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
target_link_libraries(new_new_test Req::testSharedLibRequired)
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
find_package(testLibRequired 2.5 REQUIRED)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"
|
||||
#include \"testSharedLibRequired.h\"
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if ("${prop}" STREQUAL "")
|
||||
message(SEND_ERROR "Interface of Req::testSharedLibRequired should not be empty")
|
||||
endif()
|
||||
|
||||
add_executable(new_old_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
target_link_libraries(new_old_test Req::testSharedLibRequired)
|
||||
include_directories(${testLibRequired_INCLUDE_DIRS})
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
find_package(testLibRequired 2.1 REQUIRED)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"
|
||||
#include \"testSharedLibRequired.h\"
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if (prop)
|
||||
message(SEND_ERROR "Interface of Req::testSharedLibRequired should be empty, but is ${prop}")
|
||||
endif()
|
||||
|
||||
add_executable(old_old_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
target_link_libraries(old_old_test Req::testSharedLibRequired)
|
||||
include_directories(${testLibRequired_INCLUDE_DIRS})
|
|
@ -12,29 +12,10 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|||
add_executable(Qt4Targets WIN32 main.cpp)
|
||||
target_link_libraries(Qt4Targets Qt4::QtGui)
|
||||
|
||||
set_property(TARGET Qt4Targets APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_property(TARGET Qt4Targets APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS
|
||||
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
if (TARGET Qt4::QAxServer)
|
||||
add_executable(activeqtexe WIN32 activeqtexe.cpp)
|
||||
set_property(TARGET activeqtexe PROPERTY QT4_NO_LINK_QTMAIN ON)
|
||||
target_link_libraries(activeqtexe Qt4::QAxServer Qt4::QtGui)
|
||||
set_property(TARGET activeqtexe APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:Qt4::QAxServer,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_property(TARGET activeqtexe APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS
|
||||
$<TARGET_PROPERTY:Qt4::QAxServer,INTERFACE_COMPILE_DEFINITIONS>
|
||||
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
Loading…
Reference in New Issue