mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-21 06:10:16 +08:00
install: Allow installing targets created in another directory
Previously, `install(TARGETS)` would only accept targets created in the same directory scope. Relax this restriction by searching the global scope when determining whether or not a target exists. Fixes: #14444
This commit is contained in:
@@ -280,6 +280,14 @@ targets that link to the object libraries in their implementation.
|
|||||||
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
||||||
set to ``TRUE`` has undefined behavior.
|
set to ``TRUE`` has undefined behavior.
|
||||||
|
|
||||||
|
:command:`install(TARGETS)` can install targets that were created in
|
||||||
|
other directories. When using such cross-directory install rules, running
|
||||||
|
``make install`` (or similar) from a subdirectory will not guarantee that
|
||||||
|
targets from other directories are up-to-date. You can use
|
||||||
|
:command:`target_link_libraries` or :command:`add_dependencies`
|
||||||
|
to ensure that such out-of-directory targets are built before the
|
||||||
|
subdirectory-specific install rules are run.
|
||||||
|
|
||||||
The install destination given to the target install ``DESTINATION`` may
|
The install destination given to the target install ``DESTINATION`` may
|
||||||
use "generator expressions" with the syntax ``$<...>``. See the
|
use "generator expressions" with the syntax ``$<...>``. See the
|
||||||
:manual:`cmake-generator-expressions(7)` manual for available expressions.
|
:manual:`cmake-generator-expressions(7)` manual for available expressions.
|
||||||
|
5
Help/release/dev/subdirectory-installing.rst
Normal file
5
Help/release/dev/subdirectory-installing.rst
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
subdirectory-installing
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* The :command:`install(TARGETS)` command may now be used
|
||||||
|
to install targets created outside the current directory.
|
@@ -362,7 +362,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Lookup this target in the current directory.
|
// Lookup this target in the current directory.
|
||||||
if (cmTarget* target = this->Makefile->FindLocalNonAliasTarget(tgt)) {
|
cmTarget* target = this->Makefile->FindLocalNonAliasTarget(tgt);
|
||||||
|
if (!target) {
|
||||||
|
// If no local target has been found, find it in the global scope.
|
||||||
|
target = this->Makefile->GetGlobalGenerator()->FindTarget(tgt, true);
|
||||||
|
}
|
||||||
|
if (target) {
|
||||||
// Found the target. Check its type.
|
// Found the target. Check its type.
|
||||||
if (target->GetType() != cmStateEnums::EXECUTABLE &&
|
if (target->GetType() != cmStateEnums::EXECUTABLE &&
|
||||||
target->GetType() != cmStateEnums::STATIC_LIBRARY &&
|
target->GetType() != cmStateEnums::STATIC_LIBRARY &&
|
||||||
@@ -381,8 +386,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
} else {
|
} else {
|
||||||
// Did not find the target.
|
// Did not find the target.
|
||||||
std::ostringstream e;
|
std::ostringstream e;
|
||||||
e << "TARGETS given target \"" << tgt
|
e << "TARGETS given target \"" << tgt << "\" which does not exist.";
|
||||||
<< "\" which does not exist in this directory.";
|
|
||||||
this->SetError(e.str());
|
this->SetError(e.str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -440,7 +440,13 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
|
|||||||
|
|
||||||
void cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
|
void cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
|
||||||
{
|
{
|
||||||
|
// Lookup this target in the current directory.
|
||||||
this->Target = lg->FindLocalNonAliasGeneratorTarget(this->TargetName);
|
this->Target = lg->FindLocalNonAliasGeneratorTarget(this->TargetName);
|
||||||
|
if (!this->Target) {
|
||||||
|
// If no local target has been found, find it in the global scope.
|
||||||
|
this->Target =
|
||||||
|
lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmInstallTargetGenerator::AddTweak(std::ostream& os, Indent indent,
|
void cmInstallTargetGenerator::AddTweak(std::ostream& os, Indent indent,
|
||||||
|
@@ -72,6 +72,8 @@ if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR NOT "$ENV{CMAKE_OSX_ARCHITECTURES}
|
|||||||
run_install_test(FILES-TARGET_OBJECTS)
|
run_install_test(FILES-TARGET_OBJECTS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
run_install_test(TARGETS-InstallFromSubDir)
|
||||||
|
|
||||||
set(run_install_test_components 1)
|
set(run_install_test_components 1)
|
||||||
run_install_test(FILES-EXCLUDE_FROM_ALL)
|
run_install_test(FILES-EXCLUDE_FROM_ALL)
|
||||||
run_install_test(TARGETS-EXCLUDE_FROM_ALL)
|
run_install_test(TARGETS-EXCLUDE_FROM_ALL)
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
check_installed([[^bin;bin/myexe(\.exe)?;bin/subexe(\.exe)?$]])
|
4
Tests/RunCMake/install/TARGETS-InstallFromSubDir.cmake
Normal file
4
Tests/RunCMake/install/TARGETS-InstallFromSubDir.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
enable_language(C)
|
||||||
|
add_executable(myexe main.c)
|
||||||
|
add_subdirectory(TARGETS-InstallFromSubDir)
|
||||||
|
install(TARGETS myexe subexe DESTINATION bin)
|
@@ -0,0 +1 @@
|
|||||||
|
add_executable(subexe ../main.c)
|
Reference in New Issue
Block a user