When using the boost MPL library, one can set a define to increase
the limit of how many variadic elements should be supported. The
default for BOOST_MPL_LIMIT_VECTOR_SIZE is 20:
http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/limit-vector-size.html
If the foo library requires that to be set to 30, and the independent
bar library requires it to be set to 40, consumers of both need to set
it to 40.
add_library(foo INTERFACE)
set_property(TARGET foo PROPERTY INTERFACE_boost_mpl_vector_size 30)
set_property(TARGET foo PROPERTY COMPATIBLE_INTERFACE_NUMBER_MAX boost_mpl_vector_size)
target_compile_definitions(foo INTERFACE BOOST_MPL_LIMIT_VECTOR_SIZE=$<TARGET_PROPERTY:boost_mpl_vector_size>)
add_library(bar INTERFACE)
set_property(TARGET bar PROPERTY INTERFACE_boost_mpl_vector_size 40)
# Technically the next two lines are redundant, but as foo and bar are
# independent, they both set these interfaces.
set_property(TARGET bar PROPERTY COMPATIBLE_INTERFACE_NUMBER_MAX boost_mpl_vector_size)
target_compile_definitions(bar INTERFACE BOOST_MPL_LIMIT_VECTOR_SIZE=$<TARGET_PROPERTY:boost_mpl_vector_size>)
add_executable(user)
target_link_libraries(user foo bar)
Because the TARGET_PROPERTY reads the boost_mpl_vector_size property
from the HEAD of the dependency graph (the user target), and because
that property appears in the COMPATIBLE_INTERFACE_NUMBER_MAX of
the dependencies of the user target, the maximum value for it is
chosen for the compile definition, ie, 40.
There are also use-cases for choosing the minimum value of a number.
In Qt, deprecated API can be disabled by version. Setting the
definition QT_DISABLE_DEPRECATED_BEFORE=0 disables no deprecated
API. Setting it to 0x501000 disables API which was deprecated before
Qt 5.1 etc.
If two dependencies require the use of API which was deprecated in
different Qt versions, then COMPATIBLE_INTERFACE_NUMBER_MIN can be
used to ensure that both can compile.
The result is that the depends of the target are created.
So,
add_library(somelib foo.cpp)
add_library(anotherlib EXCLUDE_FROM_ALL foo.cpp)
add_library(extra EXCLUDE_FROM_ALL foo.cpp)
target_link_libraries(anotherlib extra)
add_library(iface INTERFACE)
target_link_libraries(iface INTERFACE anotherlib)
Executing 'make iface' will result in the anotherlib and extra targets
being made.
Adding a regular executable to the INTERFACE of an INTERFACE_LIBRARY
will not result in the executable being built with 'make iface' because
of the logic in cmComputeTargetDepends::AddTargetDepend.
So far, this is implemented only for the Makefile generator. Other
generators will follow if this feature is possible for them.
Make INTERFACE_LIBRARY targets part of the all target by default.
Test this by building the all target and making the expected library
EXCLUDE_FROM_ALL.
The final location and name of a build-target is not determined
until generate-time. However, reading the LOCATION property from
a target is currently allowed at configure time. Apart from creating
possibly-erroneous results, this has an impact on the implementation
of cmake itself, and prevents some major cleanups from being made.
Disallow reading LOCATION from build-targets with a policy. Port some
existing uses of it in CMake itself to use the TARGET_FILE generator
expression.
This target type only contains INTERFACE_* properties, so it can be
used as a structural node. The target-specific commands enforce
that they may only be used with the INTERFACE keyword when used
with INTERFACE_LIBRARY targets. The old-style target properties
matching LINK_INTERFACE_LIBRARIES_<CONFIG> are always ignored for
this target type.
The name of the INTERFACE_LIBRARY must match a validity generator
expression. The validity is similar to that of an ALIAS target,
but with the additional restriction that it may not contain
double colons. Double colons will carry the meaning of IMPORTED
or ALIAS targets in CMake 2.8.13.
An ALIAS target may be created for an INTERFACE library.
At this point it can not be exported and does not appear in the
buildsystem and project files are not created for them. That may
be added as a feature in a later commit.
The generators need some changes to handle the INTERFACE_LIBRARY
targets returned by cmComputeLinkInterface::GetItems. The Ninja
generator does not use that API, so it doesn't require changes
related to that.
Add a new signature to help populate INTERFACE_LINK_LIBRARIES and
LINK_LIBRARIES cleanly in a single call. Add policy CMP0023 to control
whether the keyword signatures can be mixed with uses of the plain
signatures on the same target.
9cf3547 Add the INTERFACE_SYSTEM_INCLUDE_DIRECTORIES target property.
1925cff Add a SYSTEM parameter to target_include_directories (#14180)
286f227 Extend the cmTargetPropCommandBase interface property handling.
83498d4 Store system include directories in the cmTarget.
f1fcbe3 Add Target API to determine if an include is a system include.
2679a34 Remove unused variable.
Unlike other target properties, this does not have a corresponding
non-INTERFACE variant.
This allows propagation of system attribute on include directories
from link dependents.
Drop the "vsProjectFile" argument from cmTarget::TraceDependencies. It
appears to be the modern equivalent to a hunk added in commit ba68f771
(...added new custom command support, 2003-06-03):
+ name = libName;
+ name += ".dsp.cmake";
+ srcFilesToProcess.push(name);
but was broken by refactoring at some point. The current behavior tries
to trace dependencies on a source file named the same as a target, which
makes no sense. Furthermore, in code of the form
add_executable(foo foo.c)
add_custom_command(OUTPUT "${somewhere}/foo" ... DEPENDS foo)
the "vsProjectFile" value "foo" matches source "${somewhere}/foo.rule"
generated to hold the custom command and causes the command to be added
to the "foo" target incorrectly.
Simply drop the incorrect source file trace and supporting logic.
d7dd010 Add target property debugging for COMPILE_DEFINITIONS
1841215 Refactor cmTarget::GetCompileDefinitions to use an out-vector, not a string.
afc9243 Add an overload of cmIDEOptions::AddDefines taking a vector of strings.
d95651e Overload cmLocalGenerator::AppendDefines to add a list.
Use constructs similar to those for COMPILE_OPTIONS. This is a little
different because there is a command to remove_definitions(), so
we can't populate the equivalent target property until generate-time
in cmGlobalGenerator.
Use preprocessor loops and add a unit test for the appropriate
policies. All policies whose value is recorded at target creation
time should be part of this list.
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.
Entries from the cmMakefile are processed and maintained similarly
to other include directories. The include_directories(SYSTEM)
signature affects all following targets, and all prior targets
in the same makefile.
dc1d025 OS X: Add test for rpaths on Mac.
8576b3f OS X: Add support for @rpath in export files.
00d71bd Xcode: Add rpath support in Xcode generator.
94e7fef OS X: Add RPATH support for Mac.
RPATH support is activated on targets that have the MACOSX_RPATH
property turned on.
For install time, it is also useful to set INSTALL_RPATH to help
find dependent libraries with an @rpath in their install name.
Also adding detection of rpath conflicts when using frameworks.
Make handling of directory separators consistent between
non-bundle and bundle code.
Remove xcode specific flag from cmTarget when getting install_name.
Add (more) consistent convenience functions in cmTarget to get
directories inside of bundles and frameworks to add files to.
This refactor also fixes bug #12263 where frameworks
had the wrong install name when SKIP_BUILD_RPATH.
Also make install_name for frameworks consistent between Makefile
and Xcode generator.
This allows for example, the buildsystem to use names like 'boost_any'
instead of the overly generic 'any', and still be able to generate
IMPORTED targets called 'boost::any'.
Maintain a target's internal list of usage requirement include
directories whenever the LINK_LIBRARIES property is set by either
target_link_libraries or set_property.
The API for retrieving per-config COMPILE_DEFINITIONS has long
existed because of the COMPILE_DEFINITIONS_<CONFIG> style
properties. Ensure that the provided configuration being generated
is also used to evaluate the generator expressions
in cmTarget::GetCompileDefinitions.
Both the generic COMPILE_DEFINITIONS and the config-specific
variant need to be evaluated with the requested configuration. This
has the side-effect that the COMPILE_DEFINITIONS does not need to
be additionally evaluated with no configuration, so the callers can
be cleaned up a bit too.
As of commit 1da75022 (Don't include generator expressions in
old-style link handling., 2012-12-23), such entries are not
included in the LinkLibraries member. Generator expressions in
LinkLibraries are not processed anyway, so port to the new way
of getting link information.
After evaluating the INTERFACE_INCLUDE_DIRECTORIES, of a target in a
generator expression, also read the INTERFACE_INCLUDE_DIRECTORIES of
its link interface dependencies.
That means that code such as this will result in the 'user' target
using /bar/include and /foo/include:
add_library(foo ...)
target_include_directories(foo INTERFACE /foo/include)
add_library(bar ...)
target_include_directories(bar INTERFACE /bar/include)
target_link_libraries(bar LINK_PUBLIC foo)
add_executable(user ...)
target_include_directories(user PRIVATE
$<TARGET_PROPERTY:bar,INTERFACE_INCLUDE_DIRECTORIES>)
Also process the interface include directories from direct link
dependencies for in-build targets.
The situation is similar for the INTERFACE_COMPILE_DEFINITIONS. The
include directories related code is currently more complex because
we also need to store a backtrace at configure-time for the purpose
of debugging includes. The compile definitions related code will use
the same pattern in the future.
This is not a change in behavior, as existing code has the same effect,
but that existing code will be removed in follow-up commits.
This tracking was added during the development of commit 042ecf04
(Add API to calculate link-interface-dependent bool properties
or error., 2013-01-06), but was never used.
It was not necessary to use the content because what is really
useful in that logic is to determine if a property has been implied
to be null by appearing in a LINK_LIBRARIES genex.
I think the motivating usecase for developing the feature of
keeping track of the targets relevant to a property was that I
thought it would make it possible to allow requiring granular
compatibility of interface properties only for targets which
depended on the interface property. Eg:
add_library(foo ...)
add_library(bar ...)
add_executable(user ...)
# Read the INTERFACE_POSITION_INDEPENDENT_CODE from bar, but not
# from foo:
target_link_libraries(user foo $<$<TARGET_PROPERTY:POSTITION_INDEPENDENT_CODE>:bar>)
This obviously doesn't make sense. We require that INTERFACE
properties are consistent across all linked targets instead.
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.
6063fef Output include directories as LOG messages, not warnings.
aa66748 Specify the target whose includes are being listed.
d70204a Only output includes once after the start of 'generate-time' when debugging.
0d46e9a Store includes from the same include_directories call together.
During configure-time, GetIncludeDirectories may be called too, for example
if using the export() command. As the content can be different, it should
be output each time then.
1d74ba2 Test evaluation target via export for generator expressions
522bdac Export the INTERFACE_PIC property.
4ee872c Make the BUILD_INTERFACE of export()ed targets work.
1d47cd9 Add a test for the interfaces in targets exported from the build tree.
6c828f9 Move the exported check for file existence.
cfd4f0a Move the exported check for dependencies of targets
d8fe1fc Only generate one check per missing target.
f623d37 Don't write a comment in the export file without the code.
b279f2b Strip consecutive semicolons when preprocessing genex strings.
The Config and IMPORTED_ variants may also contain generator
expressions.
If 'the implementation is the interface', then the result of
evaluating the expressions at generate time is used to populate
the IMPORTED_LINK_INTERFACE_LIBRARIES property.
1) In the case of non-static libraries, this is fine because the
user still has the option to populate the LINK_INTERFACE_LIBRARIES
with generator expressions if that is what is wanted.
2) In the case of static libraries, this prevents a footgun,
enforcing that the interface and the implementation are really
the same.
Otherwise, the LINK_LIBRARIES could contain a generator
expression which is evaluated with a different context at build
time, and when used as an imported target. That would mean that the
result of evaluating the INTERFACE_LINK_LIBRARIES property for
a static library would not necessarily be the 'link implementation'.
For example:
add_library(libone STATIC libone.cpp)
add_library(libtwo STATIC libtwo.cpp)
add_library(libthree STATIC libthree.cpp)
target_link_libraries(libtwo
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>:libone>)
target_link_libraries(libthree libtwo)
If the LINK_LIBRARIES content was simply copied to the
IMPORTED_LINK_INTERFACE_LIBRARIES, then libthree links to libone, but
executables linking to libthree will not link to libone.
3) As the 'implementation is the interface' concept is to be
deprecated in the future anyway, this should be fine.
This new method checks that the property FOO on a target is consistent
with the INTERFACE_FOO properties of its dependees. If they are not the
consistent, an error is reported. 'Consistent' means that iff the
property is set, it must have the same boolean value as all other
related properties.