ALIAS: Add support for install and export commands

The install({TARGETS, EXPORT}) versions of the command now accept ALIAS
targets. The behavior is identical to what would happen if the name of
the target that the ALIAS references were put instead. The
export(TARGETS) command also has the same support and behavior for ALIAS
targets now.

Closes: #20979
This commit is contained in:
Arha Gatram
2026-06-22 14:40:56 -07:00
parent 4c0451ac95
commit 77156c92eb
15 changed files with 55 additions and 38 deletions

View File

@@ -112,13 +112,15 @@ 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.
An ``ALIAS`` target may not be installed or exported.
.. versionchanged:: 4.5
The ``<name>`` may be used as the operand of :command:`set_property`,
:command:`set_target_properties`, :command:`target_link_libraries`, etc. to
modify properties of ``<target>``. CMake 4.4 and earlier did not allow the
``<name>`` to modify properties of ``<target>``.
modify properties of ``<target>``. If an ``ALIAS`` executable is passed to
an :command:`install` or :command:`export` command, the executable that the
alias references is installed or exported. CMake 4.4 and earlier did not
allow using the ``<name>`` to modify properties of ``<target>``, or using
the ``<name>`` in :command:`install` and :command:`export` commands.
See Also
^^^^^^^^

View File

@@ -317,14 +317,16 @@ 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. An ``ALIAS`` target may not be
installed or exported.
regular :command:`if(TARGET)` subcommand.
.. versionchanged:: 4.5
The ``<name>`` may be used as the operand of :command:`set_property`,
:command:`set_target_properties`, :command:`target_link_libraries`, etc. to
modify properties of ``<target>``. CMake 4.4 and earlier did not allow the
``<name>`` to modify properties of ``<target>``.
modify properties of ``<target>``. If an ``ALIAS`` target is passed to an
:command:`install` or :command:`export` command, the target that the alias
references is installed or exported. CMake 4.4 and earlier did not allow
using the ``<name>`` to modify properties of ``<target>``, or using the
``<name>`` in :command:`install` and :command:`export` commands.
See Also
^^^^^^^^

View File

@@ -1433,9 +1433,11 @@ 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``.
similar commands used to modify properties of targets. The
:command:`install` and :command:`export` commands may also use an ``ALIAS``
target as the operand. The commands operate on the target which the alias
references. CMake 4.4 and earlier did not allow modifying, installing,
or exporting 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:

View File

@@ -0,0 +1,6 @@
alias-transparency-install
--------------------------
* The :command:`export` and :command:`install` commands now
accept :ref:`Alias Targets`. The commands operate on the underlying
aliased target.

View File

@@ -89,15 +89,10 @@ static void AddExportGenerator(
makefile.AddExportBuildFileGenerator(std::move(exportGenerator));
}
static bool ValidateExportableTarget(std::string const& name, cmMakefile& mf,
static bool ValidateExportableTarget(std::string const& name,
cmGlobalGenerator* gg,
cmExecutionStatus& status)
{
if (mf.IsAlias(name)) {
status.SetError(cmStrCat("given ALIAS target \"", name,
"\" which may not be exported."));
return false;
}
cmTarget const* target = gg->FindTarget(name);
if (!target) {
status.SetError(cmStrCat("given target \"", name,
@@ -187,7 +182,7 @@ static bool HandleTargetsMode(std::vector<std::string> const& args,
cmGlobalGenerator* gg = mf.GetGlobalGenerator();
for (std::string const& currentTarget : *arguments.Targets) {
if (!ValidateExportableTarget(currentTarget, mf, gg, status)) {
if (!ValidateExportableTarget(currentTarget, gg, status)) {
return false;
}
targets.emplace_back(currentTarget, std::string{});

View File

@@ -704,18 +704,12 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
for (std::string const& tgt : targetList) {
if (helper.Makefile->IsAlias(tgt)) {
status.SetError(
cmStrCat("TARGETS given target \"", tgt, "\" which is an alias."));
return false;
}
// Lookup this target in the current directory.
cmTarget* target = helper.Makefile->FindLocalNonAliasTarget(tgt);
if (!target) {
// If no local target has been found, find it in the global scope.
cmTarget* const globalTarget =
helper.Makefile->GetGlobalGenerator()->FindTarget(
tgt, { cm::TargetDomain::NATIVE });
helper.Makefile->GetGlobalGenerator()->FindTarget(tgt);
if (globalTarget && !globalTarget->IsImported()) {
target = globalTarget;
}
@@ -1369,11 +1363,6 @@ bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args,
}
for (std::string const& tgt : targetList) {
if (helper.Makefile->IsAlias(tgt)) {
status.SetError(cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given target \"",
tgt, "\" which is an alias."));
return false;
}
// Lookup this target in the current directory.
cmTarget* target = helper.Makefile->FindTargetToUse(tgt);
if (!target || !target->IsImported()) {

View File

@@ -27,6 +27,7 @@ run_cmake(target_link_options)
run_cmake(target_precompile_headers)
run_cmake(target_sources)
run_cmake(export)
run_cmake(export-alias-and-target)
run_cmake(install-export)
run_cmake(name-conflict)
run_cmake(add_dependencies)

View File

@@ -0,0 +1,2 @@
CMake Error in CMakeLists\.txt:
given target "foo" more than once\.

View File

@@ -0,0 +1,8 @@
enable_language(CXX)
add_library(foo empty.cpp)
add_library(alias ALIAS foo)
export(TARGETS foo alias FILE anotherFile.cmake)

View File

@@ -0,0 +1,9 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/someFile.cmake" content)
if(NOT "${content}" MATCHES "add_library\\(foo ")
set(RunCMake_TEST_FAILED "export(): Exported file does not define aliased target 'foo'.\n")
endif()
if("${content}" MATCHES "add_library\\(alias ")
set(RunCMake_TEST_FAILED "export(): Exported file lists 'alias' instead of the aliased target 'foo'.\n")
endif()

View File

@@ -1,4 +0,0 @@
CMake Error at export\.cmake:8 \(export\):
export given ALIAS target "alias" which may not be exported\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)

View File

@@ -0,0 +1,10 @@
string(MD5 _hash "lib/cmake")
file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/${_hash}/theTargets.cmake" content)
if(NOT "${content}" MATCHES "add_library\\(foo ")
set(RunCMake_TEST_FAILED "install(): Aliased target 'foo' was not registered in the export set.\n")
endif()
if("${content}" MATCHES "add_library\\(alias ")
set(RunCMake_TEST_FAILED "install(): 'alias' was registered in the export set instead of the aliased target 'foo'.\n")
endif()

View File

@@ -1,4 +0,0 @@
CMake Error at install-export\.cmake:8 \(install\):
install TARGETS given target "alias" which is an alias\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)