Forráskód Böngészése

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.
John Parent 3 éve
szülő
commit
2f1ffa003c

+ 7 - 1
Help/command/find_package.rst

@@ -79,7 +79,8 @@ Basic Signature
   find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
   find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
                [REQUIRED] [[COMPONENTS] [components...]]
                [REQUIRED] [[COMPONENTS] [components...]]
                [OPTIONAL_COMPONENTS components...]
                [OPTIONAL_COMPONENTS components...]
-               [NO_POLICY_SCOPE])
+               [NO_POLICY_SCOPE]
+               [GLOBAL])
 
 
 The basic signature is supported by both Module and Config modes.
 The basic signature is supported by both Module and Config modes.
 The ``MODULE`` keyword implies that only Module mode can be used to find
 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
 should find all components, no components or some well-defined subset of the
 available components.
 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:
 .. _FIND_PACKAGE_VERSION_FORMAT:
 
 
 The ``[version]`` argument requests a version with which the package found
 The ``[version]`` argument requests a version with which the package found

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -198,6 +198,7 @@ Variables that Change Behavior
    /variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
    /variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
    /variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG
    /variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG
    /variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
    /variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
+   /variable/CMAKE_FIND_PACKAGE_TARGETS_GLOBAL
    /variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
    /variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
    /variable/CMAKE_FIND_ROOT_PATH
    /variable/CMAKE_FIND_ROOT_PATH
    /variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
    /variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE

+ 9 - 0
Help/release/dev/find_package-global-imported.rst

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

+ 10 - 0
Help/variable/CMAKE_FIND_PACKAGE_TARGETS_GLOBAL.rst

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

+ 4 - 0
Source/cmAddExecutableCommand.cxx

@@ -54,6 +54,10 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args,
     }
     }
   }
   }
 
 
+  if (importTarget && !importGlobal) {
+    importGlobal = mf.IsImportedTargetGlobalScope();
+  }
+
   bool nameOk = cmGeneratorExpression::IsValidTargetName(exename) &&
   bool nameOk = cmGeneratorExpression::IsValidTargetName(exename) &&
     !cmGlobalGenerator::IsReservedTarget(exename);
     !cmGlobalGenerator::IsReservedTarget(exename);
 
 

+ 4 - 0
Source/cmAddLibraryCommand.cxx

@@ -131,6 +131,10 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
     }
     }
   }
   }
 
 
+  if (importTarget && !importGlobal) {
+    importGlobal = mf.IsImportedTargetGlobalScope();
+  }
+
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
     if (importGlobal && !importTarget) {
     if (importGlobal && !importTarget) {
       status.SetError(
       status.SetError(

+ 14 - 0
Source/cmFindPackageCommand.cxx

@@ -262,6 +262,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
     } else if (args[i] == "EXACT") {
     } else if (args[i] == "EXACT") {
       this->VersionExact = true;
       this->VersionExact = true;
       doing = DoingNone;
       doing = DoingNone;
+    } else if (args[i] == "GLOBAL") {
+      this->GlobalScope = true;
+      doing = DoingNone;
     } else if (args[i] == "MODULE") {
     } else if (args[i] == "MODULE") {
       moduleArgs.insert(i);
       moduleArgs.insert(i);
       doing = DoingNone;
       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::vector<std::string> doubledComponents;
   std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
   std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
                         optionalComponents.begin(), optionalComponents.end(),
                         optionalComponents.begin(), optionalComponents.end(),
@@ -1200,6 +1209,11 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
                                         PolicyScopeRule psr)
                                         PolicyScopeRule psr)
 {
 {
   const bool noPolicyScope = !this->PolicyScope || psr == NoPolicyScope;
   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)) {
   if (this->Makefile->ReadDependentFile(f, noPolicyScope)) {
     return true;
     return true;
   }
   }

+ 1 - 0
Source/cmFindPackageCommand.h

@@ -199,6 +199,7 @@ private:
   bool UseLibx32Paths = false;
   bool UseLibx32Paths = false;
   bool UseRealPath = false;
   bool UseRealPath = false;
   bool PolicyScope = true;
   bool PolicyScope = true;
+  bool GlobalScope = false;
   std::string LibraryArchitecture;
   std::string LibraryArchitecture;
   std::vector<std::string> Names;
   std::vector<std::string> Names;
   std::vector<std::string> Configs;
   std::vector<std::string> Configs;

+ 5 - 0
Source/cmMakefile.cxx

@@ -458,6 +458,11 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
   return result;
   return result;
 }
 }
 
 
+bool cmMakefile::IsImportedTargetGlobalScope() const
+{
+  return this->CurrentImportedTargetScope == ImportedTargetScope::Global;
+}
+
 class cmMakefile::IncludeScope
 class cmMakefile::IncludeScope
 {
 {
 public:
 public:

+ 39 - 0
Source/cmMakefile.h

@@ -860,6 +860,44 @@ public:
   void PushLoopBlockBarrier();
   void PushLoopBlockBarrier();
   void PopLoopBlockBarrier();
   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.  */
   /** Helper class to push and pop scopes automatically.  */
   class ScopePushPop
   class ScopePushPop
   {
   {
@@ -1124,4 +1162,5 @@ private:
   std::set<std::string> WarnedCMP0074;
   std::set<std::string> WarnedCMP0074;
   bool IsSourceFileTryCompile;
   bool IsSourceFileTryCompile;
   mutable bool SuppressSideEffects;
   mutable bool SuppressSideEffects;
+  ImportedTargetScope CurrentImportedTargetScope;
 };
 };

+ 31 - 0
Tests/RunCMake/find_package/GlobalImportTarget-stdout.txt

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

+ 57 - 0
Tests/RunCMake/find_package/GlobalImportTarget.cmake

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

+ 3 - 0
Tests/RunCMake/find_package/PackageRoot/BazConfig.cmake

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

+ 3 - 0
Tests/RunCMake/find_package/PackageRoot/BizConfig.cmake

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

+ 7 - 0
Tests/RunCMake/find_package/PackageRoot/FindGlobalTarget.cmake

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

+ 7 - 0
Tests/RunCMake/find_package/PackageRoot/FindGlobalTargetNoVar.cmake

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

+ 5 - 0
Tests/RunCMake/find_package/PackageRoot/FindGlobalVarTarget.cmake

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

+ 5 - 0
Tests/RunCMake/find_package/PackageRoot/FindLocalTarget.cmake

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

+ 2 - 0
Tests/RunCMake/find_package/PackageRoot/FindSimpleTarget.cmake

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

+ 5 - 0
Tests/RunCMake/find_package/PackageRoot/LTConfig.cmake

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

+ 5 - 0
Tests/RunCMake/find_package/PackageRoot/LocalPackConfig.cmake

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

+ 5 - 0
Tests/RunCMake/find_package/PackageRoot/PackNameConfig.cmake

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

+ 3 - 0
Tests/RunCMake/find_package/PackageRoot/SimpleConfig.cmake

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

+ 1 - 0
Tests/RunCMake/find_package/RunCMakeTest.cmake

@@ -6,6 +6,7 @@ run_cmake(ComponentRequiredAndOptional)
 run_cmake(FromPATHEnv)
 run_cmake(FromPATHEnv)
 run_cmake_with_options(FromPATHEnvDebugPkg --debug-find-pkg=Resolved)
 run_cmake_with_options(FromPATHEnvDebugPkg --debug-find-pkg=Resolved)
 run_cmake(FromPrefixPath)
 run_cmake(FromPrefixPath)
+run_cmake(GlobalImportTarget)
 run_cmake(MissingNormal)
 run_cmake(MissingNormal)
 run_cmake(MissingNormalForceRequired)
 run_cmake(MissingNormalForceRequired)
 run_cmake(MissingNormalRequired)
 run_cmake(MissingNormalRequired)