diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst index c81aaac46e..49dbaac35a 100644 --- a/Help/command/cmake_language.rst +++ b/Help/command/cmake_language.rst @@ -15,6 +15,7 @@ Synopsis cmake_language(`DEFER`_ ... CALL [...]) cmake_language(`SET_DEPENDENCY_PROVIDER`_ SUPPORTED_METHODS ...) cmake_language(`GET_MESSAGE_LOG_LEVEL`_ ) + cmake_language(`PRINT_TARGETS`_ ...) cmake_language(`EXIT`_ ) cmake_language(`TRACE`_ ...) @@ -511,6 +512,58 @@ Getting current message log level option takes precedence. If neither are set, the default logging level is returned. +Printing Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 4.5 + + .. signature:: + cmake_language(PRINT_TARGETS ...) + + Prints the names of all targets that currently exist, one per line, + annotated with their types (e.g. ``EXECUTABLE``, ``STATIC_LIBRARY``, + ``INTERFACE_LIBRARY``, ``UTILITY``). Imported targets are additionally + annotated with ``IMPORTED``. :ref:`Alias Targets` are not listed; their + aliased target is. + + The output is sorted by target name and printed as a single status message. + Each ```` may be one of: + + ``REGEX `` + Only list targets whose name matches the given + :ref:`regular expression `. If no target matches, + a warning is issued. + + ``IGNORE_CASE`` + Match the ``REGEX`` case-insensitively. Only valid with ``REGEX``. + + ``IMPORTED_ONLY`` + Only list :ref:`Imported Targets`. + + ``NO_IMPORTED`` + Exclude imported targets; only list targets built by this project. + + ``IMPORTED_ONLY`` and ``NO_IMPORTED`` are mutually exclusive. When neither + is given, both imported and non-imported targets are listed. + +Printing Targets Examples +""""""""""""""""""""""""" + +.. code-block:: cmake + + add_executable(app main.c) + add_library(util STATIC util.c) + find_package(Threads REQUIRED) # provides imported Threads::Threads + + cmake_language(PRINT_TARGETS REGEX "^(app|util)$" NO_IMPORTED) + +Gives:: + + -- Printing targets... + Non-imported targets matching REGEX '^(app|util)$' (case sensitive): + app (EXECUTABLE) + util (STATIC_LIBRARY) + Terminating Scripts ^^^^^^^^^^^^^^^^^^^ diff --git a/Help/release/dev/print_targets.rst b/Help/release/dev/print_targets.rst new file mode 100644 index 0000000000..274e5106ea --- /dev/null +++ b/Help/release/dev/print_targets.rst @@ -0,0 +1,6 @@ +print_targets +------------- + +* The :command:`cmake_language(PRINT_TARGETS)` command was added + to print the targets that currently exist in human-readable form + for debugging. diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx index 2a90065497..2a0b23725a 100644 --- a/Source/cmCMakeLanguageCommand.cxx +++ b/Source/cmCMakeLanguageCommand.cxx @@ -5,13 +5,19 @@ #include #include #include +#include +#include #include +#include #include +#include #include #include #include +#include "cmsys/RegularExpression.hxx" + #include "cmArgumentParser.h" #include "cmArgumentParserTypes.h" #include "cmDependencyProvider.h" @@ -25,9 +31,14 @@ #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmTarget.h" #include "cmValue.h" #include "cmake.h" +namespace cm { +enum class TargetType; +} + namespace { bool FatalError(cmExecutionStatus& status, std::string const& error) @@ -360,6 +371,157 @@ bool cmCMakeLanguageCommandGET_EXPERIMENTAL_FEATURE_ENABLED( return true; } + +struct PrintTargetsArgs : public ArgumentParser::ParseResult +{ + cm::optional Regex; + bool ImportedOnly = false; + bool NoImported = false; + bool IgnoreCase = false; + cm::optional MessagePrefix; +}; + +// Lists every target that currently exists, optionally filtered by a +// name REGEX and by imported state. "Currently exists" means anything +// CMake has defined up to this call: targets in the current directory, +// its ancestors, and any already-processed subdirectories. Walking the +// global generator's makefiles captures exactly that set; a name-keyed +// map sorts the output and dedupes imported targets, which are inherited +// into child makefiles and would otherwise be seen many times. +bool cmCMakeLanguageCommandPRINT_TARGETS( + std::vector const& args, cmExecutionStatus& status) +{ + cmMakefile& makefile = status.GetMakefile(); + std::vector expandedArgs; + makefile.ExpandArguments(args, expandedArgs); + + // Drop the leading "PRINT_TARGETS" subcommand keyword. + std::vector body(expandedArgs.begin() + 1, expandedArgs.end()); + + auto const ArgsParser = + cmArgumentParser() + .Bind("REGEX"_s, &PrintTargetsArgs::Regex) + .Bind("IMPORTED_ONLY"_s, &PrintTargetsArgs::ImportedOnly) + .Bind("NO_IMPORTED"_s, &PrintTargetsArgs::NoImported) + .Bind("IGNORE_CASE"_s, &PrintTargetsArgs::IgnoreCase) + .Bind("__MESSAGE_PREFIX"_s, &PrintTargetsArgs::MessagePrefix); + + std::vector unparsed; + auto parsedArgs = ArgsParser.Parse(body, &unparsed); + + if (!unparsed.empty()) { + return FatalError( + status, + cmStrCat( + "Unknown argument(s) given to cmake_language(PRINT_TARGETS) call: \"", + cmJoin(unparsed, "\" \""), "\".")); + } + if (parsedArgs.MaybeReportError(makefile)) { + cmSystemTools::SetFatalErrorOccurred(); + return true; + } + + if (parsedArgs.ImportedOnly && parsedArgs.NoImported) { + return FatalError(status, + "IMPORTED_ONLY and NO_IMPORTED keywords are mutually " + "exclusive in cmake_language(PRINT_TARGETS) call."); + } + + if (parsedArgs.IgnoreCase && !parsedArgs.Regex) { + return FatalError(status, + "IGNORE_CASE keyword in cmake_language(PRINT_TARGETS) " + "call is only valid with REGEX."); + } + + // Compile the optional REGEX up front so a bad pattern fails fast. With + // IGNORE_CASE the pattern and the candidate names are both lower-cased. + cm::optional regex; + if (parsedArgs.Regex) { + cmsys::RegularExpression re; + std::string const pat = parsedArgs.IgnoreCase + ? cmSystemTools::LowerCase(*parsedArgs.Regex) + : *parsedArgs.Regex; + if (!re.compile(pat)) { + return FatalError(status, + cmStrCat("REGEX regular expression \"", + *parsedArgs.Regex, "\" cannot compile.")); + } + regex = std::move(re); + } + + bool const includeNormal = !parsedArgs.ImportedOnly; + bool const includeImported = !parsedArgs.NoImported; + + struct TargetInfo + { + cm::TargetType Type; + bool Imported; + }; + std::map targets; + for (auto const& mf : makefile.GetGlobalGenerator()->GetMakefiles()) { + if (includeNormal) { + for (auto const& ti : mf->GetTargets()) { + cmTarget const& t = ti.second; + targets.insert({ t.GetName(), { t.GetType(), false } }); + } + } + if (includeImported) { + for (cmTarget const* t : mf->GetImportedTargets()) { + targets.insert({ t->GetName(), { t->GetType(), true } }); + } + } + } + + // Build the body first so the header is suppressed when a REGEX filters + // everything out (matches cmake_language(PRINT_VARIABLES) behavior). + std::string lines; + bool anyMatched = false; + for (auto const& t : targets) { + if (regex) { + std::string const subj = + parsedArgs.IgnoreCase ? cmSystemTools::LowerCase(t.first) : t.first; + if (!regex->find(subj)) { + continue; + } + } + lines += + cmStrCat(" ", t.first, " (", cmState::GetTargetTypeName(t.second.Type), + t.second.Imported ? ", IMPORTED" : "", ")\n"); + anyMatched = true; + } + + if (anyMatched) { + // The message opens with a banner line. The internal __MESSAGE_PREFIX + // keyword overrides it (used by wrappers to reproduce legacy output); it + // is not part of the public interface. + std::string const messagePrefix = + parsedArgs.MessagePrefix.value_or("Printing targets...\n"); + // The header reflects the imported-filter mode and any REGEX in effect. + char const* label = "All targets"; + if (parsedArgs.ImportedOnly) { + label = "Imported targets"; + } else if (parsedArgs.NoImported) { + label = "Non-imported targets"; + } + std::string out = cmStrCat(messagePrefix, " ", label); + if (parsedArgs.Regex) { + out += cmStrCat( + " matching REGEX '", *parsedArgs.Regex, "' (", + parsedArgs.IgnoreCase ? "case insensitive" : "case sensitive", ")"); + } + out += cmStrCat(":\n", lines); + makefile.DisplayStatus(out, -1); + } + + if (!anyMatched && parsedArgs.Regex) { + makefile.IssueMessage( + MessageType::WARNING, + cmStrCat("No targets matching REGEX '", *parsedArgs.Regex, "' (", + parsedArgs.IgnoreCase ? "case insensitive" : "case sensitive", + ") in cmake_language(PRINT_TARGETS ...).")); + } + return true; +} } bool cmCMakeLanguageCommand(std::vector const& args, @@ -539,6 +701,10 @@ bool cmCMakeLanguageCommand(std::vector const& args, status); } + if (expArgs[expArg] == "PRINT_TARGETS") { + return cmCMakeLanguageCommandPRINT_TARGETS(args, status); + } + if (expArgs[expArg] == "TRACE") { ++expArg; // Consume "TRACE". diff --git a/Tests/RunCMake/cmake_language/PrintTargets-stdout.txt b/Tests/RunCMake/cmake_language/PrintTargets-stdout.txt new file mode 100644 index 0000000000..f3cd56e53f --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargets-stdout.txt @@ -0,0 +1,14 @@ +.*--.* + +All targets matching REGEX '\^zz_print_targets_' \(case sensitive\): + +zz_print_targets_iface \(INTERFACE_LIBRARY\) + +zz_print_targets_imp \(STATIC_LIBRARY, IMPORTED\) + +zz_print_targets_lib \(STATIC_LIBRARY\) + +zz_print_targets_util \(UTILITY\) +.*--.* + +Non-imported targets matching REGEX '\^zz_print_targets_' \(case sensitive\): + +zz_print_targets_iface \(INTERFACE_LIBRARY\) + +zz_print_targets_lib \(STATIC_LIBRARY\) + +zz_print_targets_util \(UTILITY\) +.*--.* + +Imported targets matching REGEX '\^zz_print_targets_' \(case sensitive\): + +zz_print_targets_imp \(STATIC_LIBRARY, IMPORTED\) diff --git a/Tests/RunCMake/cmake_language/PrintTargets.cmake b/Tests/RunCMake/cmake_language/PrintTargets.cmake new file mode 100644 index 0000000000..a899955b35 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargets.cmake @@ -0,0 +1,16 @@ +enable_language(C) +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/zz_stub.c" "int zz_stub(void) { return 0; }\n") + +add_library(zz_print_targets_iface INTERFACE) +add_library(zz_print_targets_imp STATIC IMPORTED) +add_library(zz_print_targets_lib STATIC "${CMAKE_CURRENT_BINARY_DIR}/zz_stub.c") +add_custom_target(zz_print_targets_util) + +# Default: both imported and non-imported targets. +cmake_language(PRINT_TARGETS REGEX "^zz_print_targets_") + +# NO_IMPORTED drops the imported target. +cmake_language(PRINT_TARGETS REGEX "^zz_print_targets_" NO_IMPORTED) + +# IMPORTED_ONLY keeps only the imported target. +cmake_language(PRINT_TARGETS REGEX "^zz_print_targets_" IMPORTED_ONLY) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsAlias-stdout.txt b/Tests/RunCMake/cmake_language/PrintTargetsAlias-stdout.txt new file mode 100644 index 0000000000..fa607e9554 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsAlias-stdout.txt @@ -0,0 +1,3 @@ +.*--.* + +All targets matching REGEX '\^zz_' \(case sensitive\): + +zz_real \(INTERFACE_LIBRARY\) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsAlias.cmake b/Tests/RunCMake/cmake_language/PrintTargetsAlias.cmake new file mode 100644 index 0000000000..8b7aafb9f9 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsAlias.cmake @@ -0,0 +1,4 @@ +# Aliases are not listed; the aliased (real) target is. +add_library(zz_real INTERFACE) +add_library(zz_alias ALIAS zz_real) +cmake_language(PRINT_TARGETS REGEX "^zz_") diff --git a/Tests/RunCMake/cmake_language/PrintTargetsEmptyMatch-stderr.txt b/Tests/RunCMake/cmake_language/PrintTargetsEmptyMatch-stderr.txt new file mode 100644 index 0000000000..0790f60e1b --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsEmptyMatch-stderr.txt @@ -0,0 +1,3 @@ +CMake Warning at PrintTargetsEmptyMatch\.cmake:[0-9]+ \(cmake_language\): + No targets matching REGEX '\^zz_no_match_' \(case sensitive\) in + cmake_language\(PRINT_TARGETS \.\.\.\)\. diff --git a/Tests/RunCMake/cmake_language/PrintTargetsEmptyMatch.cmake b/Tests/RunCMake/cmake_language/PrintTargetsEmptyMatch.cmake new file mode 100644 index 0000000000..334b4263be --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsEmptyMatch.cmake @@ -0,0 +1,4 @@ +add_library(zz_present INTERFACE) + +# A REGEX matching no target prints no header, just a warning. +cmake_language(PRINT_TARGETS REGEX "^zz_no_match_") diff --git a/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase-stderr.txt b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase-stderr.txt new file mode 100644 index 0000000000..a70e518d25 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase-stderr.txt @@ -0,0 +1,3 @@ +CMake Warning at PrintTargetsIgnoreCase\.cmake:[0-9]+ \(cmake_language\): + No targets matching REGEX 'ZZ_IC_LOWER' \(case sensitive\) in + cmake_language\(PRINT_TARGETS \.\.\.\)\. diff --git a/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase-stdout.txt b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase-stdout.txt new file mode 100644 index 0000000000..63442c3e64 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase-stdout.txt @@ -0,0 +1,3 @@ +.*--.* + +All targets matching REGEX 'ZZ_IC_LOWER' \(case insensitive\): + +zz_ic_lower \(INTERFACE_LIBRARY\) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase.cmake b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase.cmake new file mode 100644 index 0000000000..1a4e01a906 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCase.cmake @@ -0,0 +1,7 @@ +add_library(zz_ic_lower INTERFACE) + +# Case-sensitive: an uppercase pattern does not match the lowercase target. +cmake_language(PRINT_TARGETS REGEX "ZZ_IC_LOWER") + +# IGNORE_CASE: the same pattern now matches. +cmake_language(PRINT_TARGETS REGEX "ZZ_IC_LOWER" IGNORE_CASE) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex-result.txt b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex-stderr.txt b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex-stderr.txt new file mode 100644 index 0000000000..f351b496e4 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex-stderr.txt @@ -0,0 +1,3 @@ +CMake Error at PrintTargetsIgnoreCaseRequiresRegex\.cmake:[0-9]+ \(cmake_language\): + cmake_language IGNORE_CASE keyword in cmake_language\(PRINT_TARGETS\) call is + only valid with REGEX\. diff --git a/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex.cmake b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex.cmake new file mode 100644 index 0000000000..1e94e80ac8 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsIgnoreCaseRequiresRegex.cmake @@ -0,0 +1,2 @@ +# IGNORE_CASE is only meaningful with REGEX. +cmake_language(PRINT_TARGETS IGNORE_CASE) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsMessagePrefix-stdout.txt b/Tests/RunCMake/cmake_language/PrintTargetsMessagePrefix-stdout.txt new file mode 100644 index 0000000000..a8c6aad2f2 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsMessagePrefix-stdout.txt @@ -0,0 +1,7 @@ +-- Printing targets\.\.\. + All targets matching REGEX '\^zz_mp_' \(case sensitive\): + zz_mp_lib \(INTERFACE_LIBRARY\) + +-- CUSTOM_BANNER + All targets matching REGEX '\^zz_mp_' \(case sensitive\): + zz_mp_lib \(INTERFACE_LIBRARY\) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsMessagePrefix.cmake b/Tests/RunCMake/cmake_language/PrintTargetsMessagePrefix.cmake new file mode 100644 index 0000000000..e058577789 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsMessagePrefix.cmake @@ -0,0 +1,7 @@ +add_library(zz_mp_lib INTERFACE) + +# Default banner opens the message. +cmake_language(PRINT_TARGETS REGEX "^zz_mp_") + +# The internal __MESSAGE_PREFIX keyword overrides the default banner. +cmake_language(PRINT_TARGETS REGEX "^zz_mp_" __MESSAGE_PREFIX "CUSTOM_BANNER\n") diff --git a/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive-result.txt b/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive-stderr.txt b/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive-stderr.txt new file mode 100644 index 0000000000..75e1609377 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive-stderr.txt @@ -0,0 +1,3 @@ +CMake Error at PrintTargetsMutuallyExclusive\.cmake:[0-9]+ \(cmake_language\): + +cmake_language IMPORTED_ONLY and NO_IMPORTED keywords are mutually + +exclusive in cmake_language\(PRINT_TARGETS\) call\. diff --git a/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive.cmake b/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive.cmake new file mode 100644 index 0000000000..61731ba4ff --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsMutuallyExclusive.cmake @@ -0,0 +1 @@ +cmake_language(PRINT_TARGETS IMPORTED_ONLY NO_IMPORTED) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsNoRegex-stdout.txt b/Tests/RunCMake/cmake_language/PrintTargetsNoRegex-stdout.txt new file mode 100644 index 0000000000..d436cda1e2 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsNoRegex-stdout.txt @@ -0,0 +1,3 @@ +.*--.* + +All targets: +.* +mytarget \(INTERFACE_LIBRARY\) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsNoRegex.cmake b/Tests/RunCMake/cmake_language/PrintTargetsNoRegex.cmake new file mode 100644 index 0000000000..b677052369 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsNoRegex.cmake @@ -0,0 +1,3 @@ +add_library(mytarget INTERFACE) + +cmake_language(PRINT_TARGETS) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsRegexError-result.txt b/Tests/RunCMake/cmake_language/PrintTargetsRegexError-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsRegexError-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_language/PrintTargetsRegexError-stderr.txt b/Tests/RunCMake/cmake_language/PrintTargetsRegexError-stderr.txt new file mode 100644 index 0000000000..af850113b0 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsRegexError-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at PrintTargetsRegexError\.cmake:[0-9]+ \(cmake_language\): + cmake_language REGEX regular expression "\[" cannot compile\. diff --git a/Tests/RunCMake/cmake_language/PrintTargetsRegexError.cmake b/Tests/RunCMake/cmake_language/PrintTargetsRegexError.cmake new file mode 100644 index 0000000000..a897033120 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsRegexError.cmake @@ -0,0 +1 @@ +cmake_language(PRINT_TARGETS REGEX "[") diff --git a/Tests/RunCMake/cmake_language/PrintTargetsScope-stdout.txt b/Tests/RunCMake/cmake_language/PrintTargetsScope-stdout.txt new file mode 100644 index 0000000000..9d59305253 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsScope-stdout.txt @@ -0,0 +1,13 @@ +.*--.* + +All targets matching REGEX '\^zz_' \(case sensitive\): + +zz_parent \(INTERFACE_LIBRARY\) + +.*--.* + +All targets matching REGEX '\^zz_' \(case sensitive\): + +zz_child \(INTERFACE_LIBRARY\) + +zz_parent \(INTERFACE_LIBRARY\) + +.*--.* + +All targets matching REGEX '\^zz_' \(case sensitive\): + +zz_child \(INTERFACE_LIBRARY\) + +zz_parent \(INTERFACE_LIBRARY\) diff --git a/Tests/RunCMake/cmake_language/PrintTargetsScope.cmake b/Tests/RunCMake/cmake_language/PrintTargetsScope.cmake new file mode 100644 index 0000000000..fcfe10345e --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsScope.cmake @@ -0,0 +1,9 @@ +add_library(zz_parent INTERFACE) + +# Before the subdirectory: only the parent target exists. +cmake_language(PRINT_TARGETS REGEX "^zz_") + +add_subdirectory(PrintTargetsScope) + +# After: the child's target is visible too. +cmake_language(PRINT_TARGETS REGEX "^zz_") diff --git a/Tests/RunCMake/cmake_language/PrintTargetsScope/CMakeLists.txt b/Tests/RunCMake/cmake_language/PrintTargetsScope/CMakeLists.txt new file mode 100644 index 0000000000..c1f907c827 --- /dev/null +++ b/Tests/RunCMake/cmake_language/PrintTargetsScope/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(zz_child INTERFACE) + +# The child sees its own target and the ancestor's. +cmake_language(PRINT_TARGETS REGEX "^zz_") diff --git a/Tests/RunCMake/cmake_language/RunCMakeTest.cmake b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake index 807d39ed61..7acfac8fa1 100644 --- a/Tests/RunCMake/cmake_language/RunCMakeTest.cmake +++ b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake @@ -182,3 +182,18 @@ block() set(RunCMake_TEST_OPTIONS --trace-expand --trace-source=trace_expand_cli_wins.cmake) run_cmake(trace_expand_cli_wins) endblock() + +# cmake_language(PRINT_TARGETS) +run_cmake(PrintTargets) +run_cmake(PrintTargetsMessagePrefix) +run_cmake(PrintTargetsMutuallyExclusive) +block() + set(RunCMake_TEST_NOT_EXPECT_stdout "zz_alias") + run_cmake(PrintTargetsAlias) +endblock() +run_cmake(PrintTargetsScope) +run_cmake(PrintTargetsEmptyMatch) +run_cmake(PrintTargetsRegexError) +run_cmake(PrintTargetsNoRegex) +run_cmake(PrintTargetsIgnoreCase) +run_cmake(PrintTargetsIgnoreCaseRequiresRegex)