ALIAS: Add support for set_property and set_target_properties commands

Currently, getting properties from an ALIAS target retrieves the property
from the target which the alias references while setting properties results
in an error. This relaxes set_property and set_target_properties to
accept ALIAS targets and act on the referenced target, mirroring the get
behavior.

An error is raised when setting ALIAS_GLOBAL or ALIASED_TARGET on an ALIAS
target.

Closes: #19445
This commit is contained in:
Arha Gatram
2026-06-24 10:35:20 -07:00
parent c5fcc275c8
commit a121419908
19 changed files with 83 additions and 28 deletions

View File

@@ -112,11 +112,16 @@ Alias Executables
``ALIAS`` targets can be used as targets to read properties
from, executables for custom commands and custom targets. They can also be
tested for existence with the regular :command:`if(TARGET)` subcommand.
The ``<name>`` may not be used to modify properties of ``<target>``, that
is, it may not be used as the operand of :command:`set_property`,
:command:`set_target_properties`, :command:`target_link_libraries` etc.
An ``ALIAS`` target may not be installed or exported.
.. versionchanged:: 4.5
The ``<name>`` may be used as the operand of :command:`set_property` and
:command:`set_target_properties` to modify properties of ``<target>``. It
may not be used with the commands :command:`target_link_libraries`,
:command:`target_compile_definitions` etc. CMake 4.4 and earlier did not
allow the ``<name>`` to modify properties of ``<target>`` with
:command:`set_property` and :command:`set_target_properties`.
See Also
^^^^^^^^

View File

@@ -317,12 +317,17 @@ Alias Libraries
``ALIAS`` targets can be used as linkable targets and as targets to
read properties from. They can also be tested for existence with the
regular :command:`if(TARGET)` subcommand. The ``<name>`` may not be used
to modify properties of ``<target>``, that is, it may not be used as the
operand of :command:`set_property`, :command:`set_target_properties`,
:command:`target_link_libraries` etc. An ``ALIAS`` target may not be
regular :command:`if(TARGET)` subcommand. An ``ALIAS`` target may not be
installed or exported.
.. versionchanged:: 4.5
The ``<name>`` may be used as the operand of :command:`set_property` and
:command:`set_target_properties` to modify properties of ``<target>``. It
may not be used with the commands :command:`target_link_libraries`,
:command:`target_compile_definitions` etc. CMake 4.4 and earlier did not
allow the ``<name>`` to modify properties of ``<target>`` with
:command:`set_property` and :command:`set_target_properties`.
See Also
^^^^^^^^

View File

@@ -40,7 +40,9 @@ It must be one of the following:
Scope may name zero or more existing targets.
See also the :command:`set_target_properties` command.
:ref:`Alias Targets` do not support setting target properties.
.. versionchanged:: 4.5
If ``<target>`` is an :ref:`Alias Target <Alias Targets>`, properties are
set on the target which the alias references.
``FILE_SET``
.. versionadded:: 4.3

View File

@@ -15,7 +15,9 @@ set next. You can use any prop value pair you want and extract it
later with the :command:`get_property` or :command:`get_target_property`
command.
:ref:`Alias Targets` do not support setting target properties.
.. versionchanged:: 4.5
If ``<targets>`` contains :ref:`Alias Targets`, properties are set on the
corresponding target referenced by each alias.
See Also
^^^^^^^^

View File

@@ -1429,9 +1429,16 @@ target, which may be an :prop_tgt:`IMPORTED` target from a package, or an
target_link_libraries(exe1 Upstream::lib1)
``ALIAS`` targets are not mutable, installable or exportable. They are
entirely local to the buildsystem description. A name can be tested for
whether it is an ``ALIAS`` name by reading the :prop_tgt:`ALIASED_TARGET`
property from it:
entirely local to the buildsystem description.
.. versionchanged:: 4.5
``ALIAS`` targets may be used as the operand for :command:`set_property` and
similar commands used to modify properties of targets. The commands operate
on the target which the alias references. CMake 4.4 and earlier did not
allow modifying targets via an ``ALIAS``.
A name can be tested for whether it is an ``ALIAS`` name by reading the
:prop_tgt:`ALIASED_TARGET` property from it:
.. code-block:: cmake

View File

@@ -0,0 +1,6 @@
alias-transparency
------------------
* The :command:`set_property` and :command:`set_target_properties` commands
now accept :ref:`Alias Targets`. Properties are set on the target which
the alias references.

View File

@@ -709,11 +709,14 @@ bool HandleTargetMode(cmExecutionStatus& status,
bool appendMode, bool remove)
{
for (std::string const& name : names) {
if (status.GetMakefile().IsAlias(name)) {
status.SetError("can not be used on an ALIAS target.");
return false;
// Better error message for alias properties set on an alias target.
if (propertyName == "ALIASED_TARGET" || propertyName == "ALIAS_GLOBAL") {
if (status.GetMakefile().IsAlias(name)) {
status.SetError(cmStrCat("can not set property ", propertyName,
" on an ALIAS target: ", name));
return false;
}
}
if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
if (target->IsSymbolic()) {
status.SetError("can not be used on a SYMBOLIC target.");

View File

@@ -35,10 +35,6 @@ bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
// loop over all the targets
for (std::string const& tname : cmStringRange{ args.begin(), propsIter }) {
if (mf.IsAlias(tname)) {
status.SetError("can not be used on an ALIAS target.");
return false;
}
if (cmTarget* target = mf.FindTargetToUse(tname)) {
if (target->IsSymbolic()) {
status.SetError("can not be used on a SYMBOLIC target.");
@@ -46,6 +42,14 @@ bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
}
// loop through all the props and set them
for (auto k = propsIter + 1; k != args.end(); k += 2) {
// Better error message for alias properties set on an alias target.
if (*k == "ALIASED_TARGET" || *k == "ALIAS_GLOBAL") {
if (mf.IsAlias(tname)) {
status.SetError(cmStrCat("can not set property ", *k,
" on an ALIAS target: ", tname));
return false;
}
}
target->SetProperty(*k, *(k + 1));
target->CheckProperty(*k, &mf);
}

View File

@@ -12,8 +12,10 @@ run_cmake(imported-global-target)
run_cmake(imported-target)
run_cmake(alias-target)
run_cmake(set_property)
run_cmake(set_property-ALIAS_GLOBAL)
run_cmake(get_property)
run_cmake(set_target_properties)
run_cmake(set_target_properties-ALIAS_GLOBAL)
run_cmake(target_link_libraries)
run_cmake(target_include_directories)
run_cmake(export)

View File

@@ -0,0 +1,2 @@
CMake Error at set_property-ALIAS_GLOBAL\.cmake:[0-9]+ \(set_property\):
set_property can not set property ALIAS_GLOBAL on an ALIAS target: alias

View File

@@ -0,0 +1,6 @@
enable_language(CXX)
add_library(foo empty.cpp)
add_library(alias ALIAS foo)
set_property(TARGET alias PROPERTY ALIAS_GLOBAL something)

View File

@@ -1,4 +0,0 @@
CMake Error at set_property\.cmake:8 \(set_property\):
set_property can not be used on an ALIAS target\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)

View File

@@ -6,3 +6,8 @@ add_library(foo empty.cpp)
add_library(alias ALIAS foo)
set_property(TARGET alias PROPERTY ANYTHING 1)
get_target_property(val foo ANYTHING)
if(NOT val STREQUAL "1")
message(SEND_ERROR "set_property(): Target property 'ANYTHING' set on ALIAS 'alias' has wrong value on aliased target 'foo': '${val}' instead of '1'.")
endif()

View File

@@ -0,0 +1,3 @@
CMake Error at set_target_properties-ALIAS_GLOBAL\.cmake:[0-9]+ \(set_target_properties\):
set_target_properties can not set property ALIAS_GLOBAL on an ALIAS target:
alias

View File

@@ -0,0 +1,6 @@
enable_language(CXX)
add_library(foo empty.cpp)
add_library(alias ALIAS foo)
set_target_properties(alias PROPERTIES ALIAS_GLOBAL something)

View File

@@ -1,4 +0,0 @@
CMake Error at set_target_properties\.cmake:8 \(set_target_properties\):
set_target_properties can not be used on an ALIAS target\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)

View File

@@ -6,3 +6,8 @@ add_library(foo empty.cpp)
add_library(alias ALIAS foo)
set_target_properties(alias PROPERTIES ANYTHING 1)
get_target_property(val foo ANYTHING)
if(NOT val STREQUAL "1")
message(SEND_ERROR "set_target_properties(): Target property 'ANYTHING' set on ALIAS 'alias' has wrong value on aliased target 'foo': '${val}' instead of '1'.")
endif()