For each usage requirement (such as `INTERFACE_COMPILE_DEFINITIONS` or
`INTERFACE_INCLUDE_DIRECTORIES`), the value of the generator expression
`$<TARGET_PROPERTY:target,prop>` includes the values of the same
property from the transitive closure of link libraries of the target.
In cases that a target's transitive closure of dependencies does not
depend on the target being linked (the "head" target), we can memoize
whether or not a usage requirement property exists at all for that
target. When a usage requirement does not exist for a target, we
can skip evaluating it for every consuming target.
Fixes: #18964, #18965
For each build setting property (such as `COMPILE_DEFINITIONS` or
`INCLUDE_DIRECTORIES`), the value of `$<TARGET_PROPERTY:target,prop>`
includes the values of the corresponding `INTERFACE_*` usage requirement
property from the transitive closure of link libraries of the target.
Previously we computed this by constructing a generator expression
string like `$<TARGET_PROPERTY:lib,INTERFACE_COMPILE_DEFINITIONS>` and
recursively evaluating it with the generator expression engine. Avoid
the string construction and parsing by using the dedicated evaluation
method `cmGeneratorTarget::EvaluateInterfaceProperty`.
Issue: #18964, #18965
In large projects the generation process spends a lot of time evaluating
usage requirements through transitive interface properties on targets.
This can be seen in a contrived example with deep dependencies:
set(prev "")
foreach(i RANGE 1 500)
add_library(a${i} a.c)
target_compile_definitions(a${i} PUBLIC A${i})
target_link_libraries(a${i} PUBLIC ${prev})
set(prev a${i})
endforeach()
For each usage requirement (such as `INTERFACE_COMPILE_DEFINITIONS` or
`INTERFACE_INCLUDE_DIRECTORIES`), the value of the generator expression
`$<TARGET_PROPERTY:target,prop>` includes the values of the same
property from the transitive closure of link libraries of the target.
Previously we computed this by constructing a generator expression
string like `$<TARGET_PROPERTY:lib,INTERFACE_COMPILE_DEFINITIONS>` and
recursively evaluating it with the generator expression engine. Avoid
the string construction and parsing by creating and using a dedicated
evaluation method `cmGeneratorTarget::EvaluateInterfaceProperty` that
looks up the properties directly.
Issue: #18964, #18965
Evaluate usage requirement generator expressions fully before entering
the processing loops. This allows us to evaluate and collect all
entries up front and then have only one call to the loop over them.
This also allows `AddInterfaceEntries` to immediately evaluate the
generator expressions it synthesizes, which will enable later
optimization.
On AIX, plugins meant to be loaded into executables via `dlopen` must be
linked with access to a list of symbols exported from the executable in
order to use them (when not using runtime linking). The AIX linker
supports specifying this list as an "import file" passed on the command
line either via the `-bI:...` option or (with a leading `#! .` line) as
a normal input file like any other library file.
The linker import file plays the same role on AIX as import libraries do
on Windows. Teach CMake to enable its import library abstraction on AIX
for executables with the `ENABLE_EXPORTS` target property set. Teach
our internal `ExportImportList` script to optionally generate a leading
`#! .` line at the top of the generated export/import list. Update our
rule for linking an executable with exports to generate a public-facing
"import library" implemented as an AIX linker import file.
With this approach, our existing infrastructure for handling import
libraries on Windows will now work for AIX linker import files too:
* Plugins that link to their executable's symbols will be automatically
linked using the import file on the command line.
* The executable's import file will be (optionally) installed and
exported for use in linking externally-built plugins.
This will allow executables and their plugins to build even if we later
turn off runtime linking.
Issue: #19163
On AIX, symbols in executables must be exported in order to be visible
to modules (plugins) they load via `dlopen`. Prior to policy `CMP0065`,
CMake linked all executables with flags to export symbols, but the NEW
behavior for that policy is to do so only for executables that have the
`ENABLE_EXPORTS` target property set. In both cases, CMake has always
used the AIX linker option `-bexpall` option to export symbols from
executables.
This has worked fairly well with the XL compiler, but with the GNU
compiler it works only for C ABI symbols. The reason is that `-bexpall`
does not export symbols starting in `_` but the GNU C++ ABI mangles all
symbols with a leading `_`. Therefore we have only supported C ABI
plugins with the GNU compiler on AIX. Some projects have tried to work
around this by replacing `-bexpall` with `-bexpfull`, but the latter
often exports symbols that we do not want exported.
Avoid using `-bexpall` for executables by instead using by our own
internal `ExportImportList` script to compute symbol export lists from
the object files to be linked into an executable. Pass the explicitly
computed export list to the AIX linker's `-bE:...` option. We already
do this for shared object exports.
Issue: #19163
An old workaround for `std::allocator_traits<>::value_type` lints from
IWYU on `std::vector<>` usage breaks IWYU's handling of `<memory>`.
Convert the workaround to use the same approach we already use for a
workaround of `std::__decay_and_strip<>::::__type` lints. Then update
the `<memory>` inclusions to follow the now-correct IWYU lints.
Avoid creating unnecessary `cmCompileGeneratorExpression` instances.
Use runtime polymorphism to avoid the full genex infrastructure when a
property value does not contain a genex.
Issue: #18965
Rather than taking a number of out parameters for the various names,
create a structure that is reused for both `GetLibraryNames` and
`GetExecutableNames`. Replace uses according to the new interface.
Using `xcodebuild -enableAddressSanitizer YES ...` causes object files
to be placed in a different directory name. Xcode provides a
placeholder for this that we can use in `OTHER_LDFLAGS` to reference
object files for linking the dependents of object libraries. However,
CMake's features for installing and exporting object libraries depend on
knowing the real path with no placeholders. For these cases, use the
default object directory. Users will then have to choose between
sanitizers and the installation and export features, but both will work
individually.
Fixes: #16289
3e867ed400 cmake: inlined files dir constant and removed it from cmake.h
Acked-by: Kitware Robot <kwrobot@kitware.com>
Rejected-by: vvs31415 <vstakhovsky@fastmail.com>
Merge-request: !2655
1ed4d48dcf Autogen: Prepend instead of append `mocs_compilation.cpp` to the sources list
a42b700cc2 cmTarget,cmGeneratorTarget: Add optional `before` parameter to AddSource
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Peter Wu <peter@lekensteyn.nl>
Merge-request: !2815
The new optional `before` parameter in `cmTarget::AddSource` and
`cmGeneratorTarget::AddSource` allows to prepend a source file
to the sources list instead of appending it.
9040df31e2 Merge branch 'backport-fix-custom-target-with-csharp'
1acd1c2b50 CSharp: Fix regression in VS project type selection for custom target
a56edad6d6 CSharp: Fix regression in VS project type selection for custom target
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2549
A target created by `add_custom_target` should always be a `.vcxproj`
file even if it has `.cs` sources involved in custom commands and such.
The latter case was broken by refactoring in commit v3.12.0-rc1~160^2~7
(remove TargetIsCSharpOnly() and use methods from cmGeneratorTarget,
2018-03-19). The reason is that the `HasLanguage` method added by
commit v3.12.0-rc1~239^2~6 (cmGeneratorTarget: add HasLanguage() as
wrapper for GetLanguages(), 2018-03-19) does not check the target type
and so is not a suitable check for deciding the project file extension.
The `HasLanguage` method was an attempt at an abstraction that turns
out not to work very well. Replace it with a dedicated `IsCSharpOnly`
method that considers the target type, sources, and non-transitive
`LINKER_LANGUAGE`.
Fixes: #18515
In cmGeneratorTarget and cmLocalGenerator we offer several APIs to get
build settings like include directories, compile definitions, source
files, etc. Add corresponding APIs that include backtrace information.
Carry a backtrace on every link item, not just link implementation
items. For now the non-impl items will still have empty backtraces at
runtime, but this will allow us to introduce values over time.
375b420fdf CSharp: Fix regression in VS project type selection
8b21aa0af0 VS: Fix CSharp flag selection when linking to a static C++ library
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2427
A that target contains only `.cs` sources should be generated as a
`.csproj` project even if it links to non-CSharp static libraries.
The latter case was broken by refactoring in commit v3.12.0-rc1~160^2~7
(remove TargetIsCSharpOnly() and use methods from cmGeneratorTarget,
2018-03-19). The reason is that the `HasLanguage` method added by
commit v3.12.0-rc1~239^2~6 (cmGeneratorTarget: add HasLanguage() as
wrapper for GetLanguages(), 2018-03-19) enforces its "exclusive" check
on the combined set of source file languages and the link language.
To restore the original `TargetIsCSharpOnly` semantics, update
`HasLanguage` to enforce exclusiveness only on the list of sources.
Fixes: #18239