find_package: Add support for default GLOBAL imported targets
Allow find package to promote scope of imported targets by specifying an argument to `find_package` or by specifying a CMake variable. * Add support for CMAKE_GLOBAL_IMPORT_SCOPE variable * Add support for GLOBAL argument to find_package Additionally add testing for above features.stage/master/nightly/2022/03/11^2
parent
3a37fda6a2
commit
2f1ffa003c
|
@ -79,7 +79,8 @@ Basic Signature
|
|||
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
|
||||
[REQUIRED] [[COMPONENTS] [components...]]
|
||||
[OPTIONAL_COMPONENTS components...]
|
||||
[NO_POLICY_SCOPE])
|
||||
[NO_POLICY_SCOPE]
|
||||
[GLOBAL])
|
||||
|
||||
The basic signature is supported by both Module and Config modes.
|
||||
The ``MODULE`` keyword implies that only Module mode can be used to find
|
||||
|
@ -115,6 +116,11 @@ define what occurs in such cases. Common arrangements include assuming it
|
|||
should find all components, no components or some well-defined subset of the
|
||||
available components.
|
||||
|
||||
Specifying the ``GLOBAL`` keyword will promote all imported targets to
|
||||
a global scope in the importing project. Alternatively this functionality
|
||||
can be enabled by setting the variable
|
||||
:variable:`CMAKE_FIND_PACKAGE_TARGETS_GLOBAL`
|
||||
|
||||
.. _FIND_PACKAGE_VERSION_FORMAT:
|
||||
|
||||
The ``[version]`` argument requests a version with which the package found
|
||||
|
|
|
@ -198,6 +198,7 @@ Variables that Change Behavior
|
|||
/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
|
||||
/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG
|
||||
/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
|
||||
/variable/CMAKE_FIND_PACKAGE_TARGETS_GLOBAL
|
||||
/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
|
||||
/variable/CMAKE_FIND_ROOT_PATH
|
||||
/variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
find_package-global-imported
|
||||
----------------------------
|
||||
|
||||
* The :command:`find_package` command gained a `GLOBAL` option that
|
||||
allows for the promotion of imported targets to global scope fur the
|
||||
duration of the :command:`find_package` call.
|
||||
|
||||
* Adds support for :variable:`CMAKE_FIND_PACKAGE_TARGETS_GLOBAL` to
|
||||
toggle behavior of the :command:`find_package` command's new GLOBAL option
|
|
@ -0,0 +1,10 @@
|
|||
CMAKE_FIND_PACKAGE_TARGETS_GLOBAL
|
||||
---------------------------------
|
||||
|
||||
Setting to ``TRUE`` promotes all :prop_tgt:`IMPORTED` targets discoverd
|
||||
by :command:`find_package` to a ``GLOBAL`` scope.
|
||||
|
||||
|
||||
Setting this to ``TRUE`` is akin to specifying ``GLOBAL``
|
||||
as an argument to :command:`find_package`.
|
||||
Default value is ``OFF``.
|
|
@ -54,6 +54,10 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args,
|
|||
}
|
||||
}
|
||||
|
||||
if (importTarget && !importGlobal) {
|
||||
importGlobal = mf.IsImportedTargetGlobalScope();
|
||||
}
|
||||
|
||||
bool nameOk = cmGeneratorExpression::IsValidTargetName(exename) &&
|
||||
!cmGlobalGenerator::IsReservedTarget(exename);
|
||||
|
||||
|
|
|
@ -131,6 +131,10 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
|
|||
}
|
||||
}
|
||||
|
||||
if (importTarget && !importGlobal) {
|
||||
importGlobal = mf.IsImportedTargetGlobalScope();
|
||||
}
|
||||
|
||||
if (type == cmStateEnums::INTERFACE_LIBRARY) {
|
||||
if (importGlobal && !importTarget) {
|
||||
status.SetError(
|
||||
|
|
|
@ -262,6 +262,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||
} else if (args[i] == "EXACT") {
|
||||
this->VersionExact = true;
|
||||
doing = DoingNone;
|
||||
} else if (args[i] == "GLOBAL") {
|
||||
this->GlobalScope = true;
|
||||
doing = DoingNone;
|
||||
} else if (args[i] == "MODULE") {
|
||||
moduleArgs.insert(i);
|
||||
doing = DoingNone;
|
||||
|
@ -364,6 +367,12 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||
}
|
||||
}
|
||||
|
||||
if (!this->GlobalScope) {
|
||||
cmValue value(
|
||||
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_TARGETS_GLOBAL"));
|
||||
this->GlobalScope = value.IsOn();
|
||||
}
|
||||
|
||||
std::vector<std::string> doubledComponents;
|
||||
std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
|
||||
optionalComponents.begin(), optionalComponents.end(),
|
||||
|
@ -1200,6 +1209,11 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
|
|||
PolicyScopeRule psr)
|
||||
{
|
||||
const bool noPolicyScope = !this->PolicyScope || psr == NoPolicyScope;
|
||||
|
||||
using ITScope = cmMakefile::ImportedTargetScope;
|
||||
ITScope scope = this->GlobalScope ? ITScope::Global : ITScope::Local;
|
||||
cmMakefile::SetGlobalTargetImportScope globScope(this->Makefile, scope);
|
||||
|
||||
if (this->Makefile->ReadDependentFile(f, noPolicyScope)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -199,6 +199,7 @@ private:
|
|||
bool UseLibx32Paths = false;
|
||||
bool UseRealPath = false;
|
||||
bool PolicyScope = true;
|
||||
bool GlobalScope = false;
|
||||
std::string LibraryArchitecture;
|
||||
std::vector<std::string> Names;
|
||||
std::vector<std::string> Configs;
|
||||
|
|
|
@ -458,6 +458,11 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
|
|||
return result;
|
||||
}
|
||||
|
||||
bool cmMakefile::IsImportedTargetGlobalScope() const
|
||||
{
|
||||
return this->CurrentImportedTargetScope == ImportedTargetScope::Global;
|
||||
}
|
||||
|
||||
class cmMakefile::IncludeScope
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -860,6 +860,44 @@ public:
|
|||
void PushLoopBlockBarrier();
|
||||
void PopLoopBlockBarrier();
|
||||
|
||||
bool IsImportedTargetGlobalScope() const;
|
||||
|
||||
enum class ImportedTargetScope
|
||||
{
|
||||
Local,
|
||||
Global,
|
||||
};
|
||||
|
||||
/** Helper class to manage whether imported packages
|
||||
* should be globally scoped based off the find package command
|
||||
*/
|
||||
class SetGlobalTargetImportScope
|
||||
{
|
||||
public:
|
||||
SetGlobalTargetImportScope(cmMakefile* mk, ImportedTargetScope const scope)
|
||||
: Makefile(mk)
|
||||
{
|
||||
if (scope == ImportedTargetScope::Global &&
|
||||
!this->Makefile->IsImportedTargetGlobalScope()) {
|
||||
this->Makefile->CurrentImportedTargetScope = scope;
|
||||
this->Set = true;
|
||||
} else {
|
||||
this->Set = false;
|
||||
}
|
||||
}
|
||||
~SetGlobalTargetImportScope()
|
||||
{
|
||||
if (this->Set) {
|
||||
this->Makefile->CurrentImportedTargetScope =
|
||||
ImportedTargetScope::Local;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
cmMakefile* Makefile;
|
||||
bool Set;
|
||||
};
|
||||
|
||||
/** Helper class to push and pop scopes automatically. */
|
||||
class ScopePushPop
|
||||
{
|
||||
|
@ -1124,4 +1162,5 @@ private:
|
|||
std::set<std::string> WarnedCMP0074;
|
||||
bool IsSourceFileTryCompile;
|
||||
mutable bool SuppressSideEffects;
|
||||
ImportedTargetScope CurrentImportedTargetScope;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
-- IMPORTED TARGET imported_local_target has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_global_target has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_local_ex has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_global_ex has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET Foo1 has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET Foo2 has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_var_local_target has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_var_global_target has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_var_local_ex has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_var_global_ex has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_global_lib has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_explicit_global_ex has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_local_lib has GLOBAL scope: FALSE
|
||||
-- IMPORTED TARGET imported_implied_local_ex has GLOBAL scope: FALSE
|
||||
-- IMPORTED TARGET imported_no_var_local_target has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_no_var_global_target has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_no_var_local_ex has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET imported_no_var_global_ex has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET not_imported_not_global has GLOBAL scope: FALSE
|
||||
-- IMPORTED TARGET PackName has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET PackNameExe has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET PackName1 has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET PackNameExe1 has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET local_lib_glob has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET local_exe_glob has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET local_lib has GLOBAL scope: FALSE
|
||||
-- IMPORTED TARGET local_exe has GLOBAL scope: FALSE
|
||||
-- IMPORTED TARGET LT1 has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET LT2 has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET LT3 has GLOBAL scope: TRUE
|
||||
-- IMPORTED TARGET LT4 has GLOBAL scope: TRUE
|
|
@ -0,0 +1,57 @@
|
|||
function (assess_target_property target)
|
||||
get_target_property(target_val "${target}" IMPORTED_GLOBAL)
|
||||
message(STATUS "IMPORTED TARGET ${target} has GLOBAL scope: ${target_val}")
|
||||
endfunction ()
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
|
||||
|
||||
find_package(GlobalTarget GLOBAL REQUIRED)
|
||||
assess_target_property(imported_local_target)
|
||||
assess_target_property(imported_global_target)
|
||||
assess_target_property(imported_local_ex)
|
||||
assess_target_property(imported_global_ex)
|
||||
assess_target_property(Foo1)
|
||||
assess_target_property(Foo2)
|
||||
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE)
|
||||
find_package(GlobalVarTarget)
|
||||
assess_target_property(imported_var_local_target)
|
||||
assess_target_property(imported_var_global_target)
|
||||
assess_target_property(imported_var_local_ex)
|
||||
assess_target_property(imported_var_global_ex)
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL OFF)
|
||||
|
||||
find_package(LocalTarget)
|
||||
assess_target_property(imported_global_lib)
|
||||
assess_target_property(imported_explicit_global_ex)
|
||||
assess_target_property(imported_local_lib)
|
||||
assess_target_property(imported_implied_local_ex)
|
||||
|
||||
find_package(GlobalTargetNoVar GLOBAL)
|
||||
assess_target_property(imported_no_var_local_target)
|
||||
assess_target_property(imported_no_var_global_target)
|
||||
assess_target_property(imported_no_var_local_ex)
|
||||
assess_target_property(imported_no_var_global_ex)
|
||||
assess_target_property(not_imported_not_global)
|
||||
|
||||
set(Baz_DIR "${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot")
|
||||
find_package(Baz GLOBAL REQUIRED)
|
||||
assess_target_property(PackName)
|
||||
assess_target_property(PackNameExe)
|
||||
assess_target_property(PackName1)
|
||||
assess_target_property(PackNameExe1)
|
||||
|
||||
set(Biz_DIR "${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot")
|
||||
find_package(Biz REQUIRED)
|
||||
assess_target_property(local_lib_glob)
|
||||
assess_target_property(local_exe_glob)
|
||||
assess_target_property(local_lib)
|
||||
assess_target_property(local_exe)
|
||||
|
||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE)
|
||||
set(Simple_DIR "${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot")
|
||||
find_package(Simple REQUIRED)
|
||||
assess_target_property(LT1)
|
||||
assess_target_property(LT2)
|
||||
assess_target_property(LT3)
|
||||
assess_target_property(LT4)
|
|
@ -0,0 +1,3 @@
|
|||
include(CMakeFindDependencyMacro)
|
||||
|
||||
find_dependency(PackName PATHS ${CMAKE_CURRENT_LIST_DIR})
|
|
@ -0,0 +1,3 @@
|
|||
include(CMakeFindDependencyMacro)
|
||||
|
||||
find_dependency(LocalPack PATHS ${CMAKE_CURRENT_LIST_DIR})
|
|
@ -0,0 +1,7 @@
|
|||
add_library(imported_global_target SHARED IMPORTED GLOBAL)
|
||||
add_executable(imported_global_ex IMPORTED GLOBAL)
|
||||
|
||||
add_library(imported_local_target SHARED IMPORTED)
|
||||
add_executable(imported_local_ex IMPORTED)
|
||||
|
||||
find_package(SimpleTarget)
|
|
@ -0,0 +1,7 @@
|
|||
add_library(imported_no_var_global_target SHARED IMPORTED GLOBAL)
|
||||
add_executable(imported_no_var_global_ex IMPORTED GLOBAL)
|
||||
|
||||
add_library(imported_no_var_local_target SHARED IMPORTED)
|
||||
add_executable(imported_no_var_local_ex IMPORTED)
|
||||
|
||||
add_library(not_imported_not_global INTERFACE)
|
|
@ -0,0 +1,5 @@
|
|||
add_library(imported_var_global_target SHARED IMPORTED GLOBAL)
|
||||
add_executable(imported_var_global_ex IMPORTED GLOBAL)
|
||||
|
||||
add_library(imported_var_local_target SHARED IMPORTED)
|
||||
add_executable(imported_var_local_ex IMPORTED)
|
|
@ -0,0 +1,5 @@
|
|||
add_library(imported_global_lib SHARED IMPORTED GLOBAL)
|
||||
add_executable(imported_explicit_global_ex IMPORTED GLOBAL)
|
||||
|
||||
add_library(imported_local_lib SHARED IMPORTED)
|
||||
add_executable(imported_implied_local_ex IMPORTED)
|
|
@ -0,0 +1,2 @@
|
|||
add_library(Foo1 SHARED IMPORTED)
|
||||
add_executable(Foo2 IMPORTED)
|
|
@ -0,0 +1,5 @@
|
|||
add_library(LT1 INTERFACE IMPORTED)
|
||||
add_executable(LT2 IMPORTED)
|
||||
|
||||
add_library(LT3 INTERFACE IMPORTED GLOBAL)
|
||||
add_executable(LT4 IMPORTED GLOBAL)
|
|
@ -0,0 +1,5 @@
|
|||
add_library(local_lib_glob SHARED IMPORTED GLOBAL)
|
||||
add_executable(local_exe_glob IMPORTED GLOBAL)
|
||||
|
||||
add_library(local_lib SHARED IMPORTED)
|
||||
add_executable(local_exe IMPORTED)
|
|
@ -0,0 +1,5 @@
|
|||
add_library(PackName INTERFACE IMPORTED GLOBAL)
|
||||
add_executable(PackNameExe IMPORTED GLOBAL)
|
||||
|
||||
add_library(PackName1 INTERFACE IMPORTED)
|
||||
add_executable(PackNameExe1 IMPORTED)
|
|
@ -0,0 +1,3 @@
|
|||
include(CMakeFindDependencyMacro)
|
||||
|
||||
find_dependency(LT PATHS ${CMAKE_CURRENT_LIST_DIR})
|
|
@ -6,6 +6,7 @@ run_cmake(ComponentRequiredAndOptional)
|
|||
run_cmake(FromPATHEnv)
|
||||
run_cmake_with_options(FromPATHEnvDebugPkg --debug-find-pkg=Resolved)
|
||||
run_cmake(FromPrefixPath)
|
||||
run_cmake(GlobalImportTarget)
|
||||
run_cmake(MissingNormal)
|
||||
run_cmake(MissingNormalForceRequired)
|
||||
run_cmake(MissingNormalRequired)
|
||||
|
|
Loading…
Reference in New Issue