Commit d0a76ea0 authored by Stephen Kelly's avatar Stephen Kelly

Introduce the INTERFACE_LINK_LIBRARIES property.

This property replaces the properties which
match (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?, and is enabled
for IMPORTED targets, and for non-IMPORTED targets only with a policy.

For static libraries, the INTERFACE_LINK_LIBRARIES property is
also used as the source of transitive usage requirements content.
Static libraries still require users to link to all entries in
their LINK_LIBRARIES, but usage requirements such as INCLUDE_DIRECTORIES
COMPILE_DEFINITIONS and COMPILE_OPTIONS can be restricted to only
certain interface libraries.

Because the INTERFACE_LINK_LIBRARIES property is populated unconditionally,
we need to compare the evaluated result of it with the link implementation
to determine whether to issue the policy warning for static libraries. For
shared libraries, the policy warning is issued if the contents of
the INTERFACE_LINK_LIBRARIES property differs from the contents of the
relevant config-specific old LINK_INTERFACE_LIBRARIES property.
parent ddde61c0
......@@ -174,7 +174,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt)
|| strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
|| strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
|| strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 25) == 0
|| strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0);
|| strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0)
|| strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
}
//----------------------------------------------------------------------------
......
......@@ -544,6 +544,28 @@ cmPolicies::cmPolicies()
"The NEW behavior for this policy is to issue a FATAL_ERROR if "
"INCLUDE_DIRECTORIES contains a relative path.",
2,8,11,20130516, cmPolicies::WARN);
this->DefinePolicy(
CMP0022, "CMP0022",
"INTERFACE_LINK_LIBRARIES defines the link interface.",
"CMake 2.8.11 constructed the 'link interface' of a target from "
"properties matching (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?. "
"The modern way to specify config-sensitive content is to use generator "
"expressions and the IMPORTED_ prefix makes uniform processing of the "
"link interface with generator expressions impossible. The "
"INTERFACE_LINK_LIBRARIES target property was introduced as a "
"replacement in CMake 2.8.12. This new property is named consistently "
"with the INTERFACE_COMPILE_DEFINITIONS, INTERFACE_INCLUDE_DIRECTORIES "
"and INTERFACE_COMPILE_OPTIONS properties. For in-build targets, CMake "
"will use the INTERFACE_LINK_LIBRARIES property as the source of the "
"link interface only if policy CMP0022 is NEW. "
"\n"
"The OLD behavior for this policy is to ignore the "
"INTERFACE_LINK_LIBRARIES property for in-build targets. "
"The NEW behavior for this policy is to use the INTERFACE_LINK_LIBRARIES "
"property for in-build targets, and ignore the old properties matching "
"(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?.",
2,8,11,20130516, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
......
......@@ -72,6 +72,7 @@ public:
CMP0020, ///< Automatically link Qt executables to qtmain target
CMP0021, ///< Fatal error on relative paths in INCLUDE_DIRECTORIES
/// target property
CMP0022, ///< INTERFACE_LINK_LIBRARIES defines the link interface
/** \brief Always the last entry.
*
......
This diff is collapsed.
......@@ -111,6 +111,10 @@ public:
cmPolicies::PolicyStatus GetPolicyStatusCMP0021() const
{ return this->PolicyStatusCMP0021; }
/** Get the status of policy CMP0022 when the target was created. */
cmPolicies::PolicyStatus GetPolicyStatusCMP0022() const
{ return this->PolicyStatusCMP0022; }
/**
* Get the list of the custom commands for this target
*/
......@@ -695,6 +699,7 @@ private:
cmPolicies::PolicyStatus PolicyStatusCMP0008;
cmPolicies::PolicyStatus PolicyStatusCMP0020;
cmPolicies::PolicyStatus PolicyStatusCMP0021;
cmPolicies::PolicyStatus PolicyStatusCMP0022;
// Internal representation details.
friend class cmTargetInternals;
......
......@@ -2528,6 +2528,16 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--test-command IncludeDirectories)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
add_test(InterfaceLinkLibraries ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/InterfaceLinkLibraries"
"${CMake_BINARY_DIR}/Tests/InterfaceLinkLibraries"
--build-two-config
${build_generator_args}
--build-project InterfaceLinkLibraries
--test-command InterfaceLinkLibraries)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InterfaceLinkLibraries")
if(CMAKE_USE_KWSTYLE AND KWSTYLE_EXECUTABLE)
# The "make StyleCheck" command line as a test. If the test fails, look
# for lines like "Error #0 (624) Line length exceed 88 (max=79)" in the
......
cmake_minimum_required (VERSION 2.8)
cmake_policy(SET CMP0022 NEW)
project(InterfaceLinkLibraries)
add_library(foo_shared SHARED foo_vs6_1.cpp)
target_compile_definitions(foo_shared INTERFACE FOO_LIBRARY)
add_library(bar_shared SHARED bar_vs6_1.cpp)
target_compile_definitions(bar_shared INTERFACE BAR_LIBRARY)
set_property(TARGET bar_shared APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared)
add_executable(shared_test main_vs6_1.cpp)
set_property(TARGET shared_test APPEND PROPERTY LINK_LIBRARIES bar_shared)
add_library(foo_static STATIC foo_vs6_2.cpp)
target_compile_definitions(foo_static INTERFACE FOO_LIBRARY)
add_library(bar_static STATIC bar_vs6_2.cpp)
target_compile_definitions(bar_static INTERFACE BAR_LIBRARY)
set_property(TARGET bar_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_static)
add_executable(static_test main_vs6_2.cpp)
set_property(TARGET static_test APPEND PROPERTY LINK_LIBRARIES bar_static)
add_library(foo_shared_private SHARED foo_vs6_3.cpp)
target_compile_definitions(foo_shared_private INTERFACE FOO_LIBRARY)
add_library(bang_shared_private SHARED bang_vs6_1.cpp)
target_compile_definitions(bang_shared_private INTERFACE BANG_LIBRARY)
add_library(bar_shared_private SHARED bar_vs6_3.cpp)
target_compile_definitions(bar_shared_private INTERFACE BAR_LIBRARY)
target_compile_definitions(bar_shared_private PRIVATE BAR_USE_BANG)
set_property(TARGET bar_shared_private APPEND PROPERTY LINK_LIBRARIES bang_shared_private)
set_property(TARGET bar_shared_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared_private)
add_executable(shared_private_test main_vs6_3.cpp)
set_property(TARGET shared_private_test APPEND PROPERTY LINK_LIBRARIES bar_shared_private)
add_library(foo_static_private STATIC foo_vs6_4.cpp)
target_compile_definitions(foo_static_private INTERFACE FOO_LIBRARY)
add_library(bang_static_private STATIC bang_vs6_2.cpp)
target_compile_definitions(bang_static_private INTERFACE BANG_LIBRARY)
add_library(bar_static_private STATIC bar_vs6_4.cpp)
target_compile_definitions(bar_static_private INTERFACE BAR_LIBRARY)
target_compile_definitions(bar_static_private PRIVATE BAR_USE_BANG)
set_property(TARGET bar_static_private APPEND PROPERTY LINK_LIBRARIES bang_static_private)
set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:bang_static_private> foo_static_private)
add_executable(InterfaceLinkLibraries main_vs6_4.cpp)
set_property(TARGET InterfaceLinkLibraries APPEND PROPERTY LINK_LIBRARIES bar_static_private)
#ifdef FOO_LIBRARY
#error Unexpected FOO_LIBRARY
#endif
#ifdef BAR_LIBRARY
#error Unexpected BAR_LIBRARY
#endif
#include "bang.h"
int bang()
{
return 0;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int bang();
#ifdef FOO_LIBRARY
#error Unexpected FOO_LIBRARY
#endif
#ifdef BAR_USE_BANG
# ifndef BANG_LIBRARY
# error Expected BANG_LIBRARY
# endif
# include "bang.h"
#else
# ifdef BANG_LIBRARY
# error Unexpected BANG_LIBRARY
# endif
#endif
#include "bar.h"
int bar()
{
#ifdef BAR_USE_BANG
return bang();
#else
return 0;
#endif
}
#include "foo.h"
#ifdef _WIN32
__declspec(dllexport)
#endif
int bar();
#ifdef BAR_LIBRARY
#error Unexpected BAR_LIBRARY
#endif
#ifdef BANG_LIBRARY
#error Unexpected BANG_LIBRARY
#endif
#include "foo.h"
int foo()
{
return 0;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int foo();
#ifndef FOO_LIBRARY
#error Expected FOO_LIBRARY
#endif
#ifndef BAR_LIBRARY
#error Expected BAR_LIBRARY
#endif
#ifdef BANG_LIBRARY
#error Unexpected BANG_LIBRARY
#endif
#include "bar.h"
int main(void)
{
return foo() + bar();
}
project(CMP0022-NOWARN-static)
add_library(foo STATIC empty_vs6_1.cpp)
add_library(bar STATIC empty_vs6_2.cpp)
add_library(bat STATIC empty_vs6_3.cpp)
target_link_libraries(foo bar)
target_link_libraries(bar bat)
CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
interface. Run "cmake --help-policy CMP0022" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
Static library target "bar" has a INTERFACE_LINK_LIBRARIES property. This
should be preferred as the source of the link interface for this library.
Ignoring the property and using the link implementation as the link
interface instead.
This warning is for project developers. Use -Wno-dev to suppress it.$
project(CMP0022-WARN)
add_library(foo STATIC empty_vs6_1.cpp)
add_library(bar STATIC empty_vs6_2.cpp)
add_library(bat STATIC empty_vs6_3.cpp)
set_property(TARGET bar PROPERTY INTERFACE_LINK_LIBRARIES foo)
set_property(TARGET bar PROPERTY LINK_LIBRARIES bat)
add_library(user empty.cpp)
target_link_libraries(user bar)
CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
interface. Run "cmake --help-policy CMP0022" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
Target "bar" has a INTERFACE_LINK_LIBRARIES property which differs from its
LINK_INTERFACE_LIBRARIES properties.
This warning is for project developers. Use -Wno-dev to suppress it.$
project(CMP0022-WARN)
add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp)
add_library(bat SHARED empty_vs6_3.cpp)
set_property(TARGET bar PROPERTY INTERFACE_LINK_LIBRARIES foo)
set_property(TARGET bar PROPERTY LINK_INTERFACE_LIBRARIES bat)
add_library(user empty.cpp)
target_link_libraries(user bar)
cmake_minimum_required(VERSION 2.8.11)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
include(RunCMake)
run_cmake(CMP0022-WARN)
run_cmake(CMP0022-WARN-static)
run_cmake(CMP0022-NOWARN-static)
#ifdef _WIN32
__declspec(dllexport)
#endif
int empty()
{
return 0;
}
......@@ -52,6 +52,7 @@ if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3)
endif()
add_RunCMake_test(CMP0019)
add_RunCMake_test(CMP0022)
add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment