diff options
author | Brad King <brad.king@kitware.com> | 2022-03-16 13:15:37 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2022-03-16 14:47:32 (GMT) |
commit | add64399c54859d26f9954fb06d616dbd00bffe7 (patch) | |
tree | 8d1008e2cec9417057c7371738d93fccc830b489 /Source | |
parent | 790c225208d389b332828014b55894e9f9c5d0e8 (diff) | |
download | CMake-add64399c54859d26f9954fb06d616dbd00bffe7.zip CMake-add64399c54859d26f9954fb06d616dbd00bffe7.tar.gz CMake-add64399c54859d26f9954fb06d616dbd00bffe7.tar.bz2 |
target_link_libraries: Restore LINK_ONLY for multiple static lib dependencies
Since commit c1e812ad4f (target_link_libraries: Improve tolerance of
unquoted generator expressions, 2022-02-15, v3.23.0-rc2~11^2) we
accumulate consecutive non-keyword arguments to recover an unquoted
generator expression as a single entry. When given multiple consecutive
non-genex library names, the grouping breaks our logic that expects each
entry is either a raw target name or a genex. Revise the logic to only
accumulate multiple arguments when they end inside a partial genex.
This bug caused `target_link_libraries` to stop wrapping static library
private dependencies in `$<LINK_ONLY:...>` for `INTERFACE_LINK_LIBRARIES`
when multiple consecutive library names are given. Add a test case
covering that behavior.
Fixes: #23302
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmTargetLinkLibrariesCommand.cxx | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 94fcdd9..e10d0b5 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -9,6 +9,7 @@ #include <utility> #include <cm/optional> +#include <cm/string_view> #include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" @@ -183,8 +184,11 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, // Accumulate consectuive non-keyword arguments into one entry in // order to handle unquoted generator expressions containing ';'. + std::size_t genexNesting = 0; cm::optional<std::string> currentEntry; auto processCurrentEntry = [&]() -> bool { + // FIXME: Warn about partial genex if genexNesting > 0? + genexNesting = 0; if (currentEntry) { assert(!haveLLT); if (!tll.HandleLibrary(currentProcessingState, *currentEntry, @@ -220,7 +224,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, // of debug and optimized that can be used. for (unsigned int i = 1; i < args.size(); ++i) { if (keywords.count(args[i])) { - // A keyword argument terminates any preceding accumulated entry. + // A keyword argument terminates any accumulated partial genex. if (!processCurrentEntry()) { return false; } @@ -321,12 +325,33 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, } llt = GENERAL_LibraryType; } else { + // Track the genex nesting level. + { + cm::string_view arg = args[i]; + for (std::string::size_type pos = 0; pos < arg.size(); ++pos) { + cm::string_view cur = arg.substr(pos); + if (cmHasLiteralPrefix(cur, "$<")) { + ++genexNesting; + ++pos; + } else if (genexNesting > 0 && cmHasLiteralPrefix(cur, ">")) { + --genexNesting; + } + } + } + // Accumulate this argument in the current entry. extendCurrentEntry(args[i]); + + // Process this entry if it does not end inside a genex. + if (genexNesting == 0) { + if (!processCurrentEntry()) { + return false; + } + } } } - // Process the last accumulated entry, if any. + // Process the last accumulated partial genex, if any. if (!processCurrentEntry()) { return false; } |