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
John Parent 2022-03-10 12:43:50 -05:00
parent 3a37fda6a2
commit 2f1ffa003c
24 changed files with 233 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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``.

View File

@ -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);

View File

@ -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(

View File

@ -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;
}

View File

@ -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;

View File

@ -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:

View File

@ -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;
};

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,3 @@
include(CMakeFindDependencyMacro)
find_dependency(PackName PATHS ${CMAKE_CURRENT_LIST_DIR})

View File

@ -0,0 +1,3 @@
include(CMakeFindDependencyMacro)
find_dependency(LocalPack PATHS ${CMAKE_CURRENT_LIST_DIR})

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -0,0 +1,2 @@
add_library(Foo1 SHARED IMPORTED)
add_executable(Foo2 IMPORTED)

View File

@ -0,0 +1,5 @@
add_library(LT1 INTERFACE IMPORTED)
add_executable(LT2 IMPORTED)
add_library(LT3 INTERFACE IMPORTED GLOBAL)
add_executable(LT4 IMPORTED GLOBAL)

View File

@ -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)

View File

@ -0,0 +1,5 @@
add_library(PackName INTERFACE IMPORTED GLOBAL)
add_executable(PackNameExe IMPORTED GLOBAL)
add_library(PackName1 INTERFACE IMPORTED)
add_executable(PackNameExe1 IMPORTED)

View File

@ -0,0 +1,3 @@
include(CMakeFindDependencyMacro)
find_dependency(LT PATHS ${CMAKE_CURRENT_LIST_DIR})

View File

@ -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)