Browse Source

target_link_libraries: Allow use with targets in other directories

Previously the command did not allow naming targets on the LHS that
were not created in the calling directory.  Lift this restriction to
enable more flexible use by projects.

Fixes: #17943
Patrick Stotko 7 years ago
parent
commit
c9349cc1b9

+ 1 - 0
Copyright.txt

@@ -78,6 +78,7 @@ The following individuals and institutions are among the Contributors:
 * Nikita Krupen'ko <[email protected]>
 * NVIDIA Corporation <www.nvidia.com>
 * OpenGamma Ltd. <opengamma.com>
+* Patrick Stotko <[email protected]>
 * Per Øyvind Karlsen <[email protected]>
 * Peter Collingbourne <[email protected]>
 * Petr Gotthard <[email protected]>

+ 1 - 1
Help/command/target_link_libraries.rst

@@ -18,7 +18,7 @@ All of them have the general form::
 
   target_link_libraries(<target> ... <item>... ...)
 
-The named ``<target>`` must have been created in the current directory by
+The named ``<target>`` must have been created by
 a command such as :command:`add_executable` or :command:`add_library` and
 must not be an :ref:`ALIAS target <Alias Targets>`.
 Repeated calls for the same ``<target>`` append items in the order called.

+ 5 - 0
Help/release/dev/subdirectory-linking.rst

@@ -0,0 +1,5 @@
+subdirectory-linking
+--------------------
+
+* The :command:`target_link_libraries` command may now be called
+  to modify targets created outside the current directory.

+ 9 - 2
Source/cmTargetLinkLibrariesCommand.cxx

@@ -364,7 +364,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
   if (this->CurrentProcessingState != ProcessingKeywordLinkInterface &&
       this->CurrentProcessingState != ProcessingPlainLinkInterface) {
 
-    // Assure that the target on the LHS was created in the current directory.
+    // Find target on the LHS locally
     cmTarget* t =
       this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
     if (!t) {
@@ -377,11 +377,18 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
         }
       }
     }
+
+    // If no local target has been found, find it in the global scope
+    if (!t) {
+      t = this->Makefile->GetGlobalGenerator()->FindTarget(
+        this->Target->GetName(), true);
+    }
+
     if (!t) {
       std::ostringstream e;
       e << "Attempt to add link library \"" << lib << "\" to target \""
         << this->Target->GetName()
-        << "\" which is not built in this directory.";
+        << "\" which does not exist or is an alias target.";
       this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
       return false;
     }

+ 3 - 0
Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake

@@ -8,7 +8,10 @@ run_cmake(ImportedTarget)
 run_cmake(ImportedTargetFailure)
 run_cmake(MixedSignature)
 run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)
+run_cmake(SubDirImportedTarget)
 run_cmake(SubDirTarget)
+run_cmake(SubDirTarget-UNKNOWN-IMPORTED)
+run_cmake(SubDirTarget-UNKNOWN-IMPORTED-GLOBAL)
 run_cmake(SharedDepNotTarget)
 run_cmake(StaticPrivateDepNotExported)
 run_cmake(StaticPrivateDepNotTarget)

+ 4 - 0
Tests/RunCMake/target_link_libraries/SubDirImportedTarget-stdout.txt

@@ -0,0 +1,4 @@
+-- mainexeUnknownImportedGlobal: mainlib;sublib
+-- mainlibUnknownImportedGlobal: mainlib;sublib
+-- subexeUnknownImportedGlobal: mainlib;sublib
+-- sublibUnknownImportedGlobal: mainlib;sublib

+ 17 - 0
Tests/RunCMake/target_link_libraries/SubDirImportedTarget.cmake

@@ -0,0 +1,17 @@
+enable_language(C)
+
+add_executable(mainexeUnknownImportedGlobal IMPORTED GLOBAL)
+add_library(mainlibUnknownImportedGlobal UNKNOWN IMPORTED GLOBAL)
+add_library(mainlib empty.c)
+
+add_subdirectory(SubDirImportedTarget)
+
+target_link_libraries(subexeUnknownImportedGlobal INTERFACE mainlib)
+target_link_libraries(subexeUnknownImportedGlobal INTERFACE sublib)
+get_property(subexeUnknownImportedGlobal_libs TARGET subexeUnknownImportedGlobal PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "subexeUnknownImportedGlobal: ${subexeUnknownImportedGlobal_libs}")
+
+target_link_libraries(sublibUnknownImportedGlobal INTERFACE mainlib)
+target_link_libraries(sublibUnknownImportedGlobal INTERFACE sublib)
+get_property(sublibUnknownImportedGlobal_libs TARGET sublibUnknownImportedGlobal PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "sublibUnknownImportedGlobal: ${sublibUnknownImportedGlobal_libs}")

+ 13 - 0
Tests/RunCMake/target_link_libraries/SubDirImportedTarget/CMakeLists.txt

@@ -0,0 +1,13 @@
+add_executable(subexeUnknownImportedGlobal IMPORTED GLOBAL)
+add_library(sublibUnknownImportedGlobal UNKNOWN IMPORTED GLOBAL)
+add_library(sublib ../empty.c)
+
+target_link_libraries(mainexeUnknownImportedGlobal INTERFACE mainlib)
+target_link_libraries(mainexeUnknownImportedGlobal INTERFACE sublib)
+get_property(mainexeUnknownImportedGlobal_libs TARGET mainexeUnknownImportedGlobal PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "mainexeUnknownImportedGlobal: ${mainexeUnknownImportedGlobal_libs}")
+
+target_link_libraries(mainlibUnknownImportedGlobal INTERFACE mainlib)
+target_link_libraries(mainlibUnknownImportedGlobal INTERFACE sublib)
+get_property(mainlibUnknownImportedGlobal_libs TARGET mainlibUnknownImportedGlobal PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "mainlibUnknownImportedGlobal: ${mainlibUnknownImportedGlobal_libs}")

+ 2 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget-UNKNOWN-IMPORTED-GLOBAL-stdout.txt

@@ -0,0 +1,2 @@
+-- mainexe: mainlibUnknownImportedGlobal;sublibUnknownImportedGlobal
+-- subexe: mainlibUnknownImportedGlobal;sublibUnknownImportedGlobal

+ 11 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget-UNKNOWN-IMPORTED-GLOBAL.cmake

@@ -0,0 +1,11 @@
+enable_language(C)
+
+add_executable(mainexe empty.c)
+add_library(mainlibUnknownImportedGlobal UNKNOWN IMPORTED GLOBAL)
+
+add_subdirectory(SubDirTarget-UNKNOWN-IMPORTED-GLOBAL)
+
+target_link_libraries(subexe mainlibUnknownImportedGlobal)
+target_link_libraries(subexe sublibUnknownImportedGlobal)
+get_property(subexe_libs TARGET subexe PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "subexe: ${subexe_libs}")

+ 7 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget-UNKNOWN-IMPORTED-GLOBAL/CMakeLists.txt

@@ -0,0 +1,7 @@
+add_executable(subexe ../empty.c)
+add_library(sublibUnknownImportedGlobal UNKNOWN IMPORTED GLOBAL)
+
+target_link_libraries(mainexe mainlibUnknownImportedGlobal)
+target_link_libraries(mainexe sublibUnknownImportedGlobal)
+get_property(mainexe_libs TARGET mainexe PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "mainexe: ${mainexe_libs}")

+ 2 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget-UNKNOWN-IMPORTED-stdout.txt

@@ -0,0 +1,2 @@
+-- mainexe: mainlibUnknownImported;sublibUnknownImported
+-- subexe: mainlibUnknownImported;sublibUnknownImported

+ 11 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget-UNKNOWN-IMPORTED.cmake

@@ -0,0 +1,11 @@
+enable_language(C)
+
+add_executable(mainexe empty.c)
+add_library(mainlibUnknownImported UNKNOWN IMPORTED)
+
+add_subdirectory(SubDirTarget-UNKNOWN-IMPORTED)
+
+target_link_libraries(subexe mainlibUnknownImported)
+target_link_libraries(subexe sublibUnknownImported)
+get_property(subexe_libs TARGET subexe PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "subexe: ${subexe_libs}")

+ 7 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget-UNKNOWN-IMPORTED/CMakeLists.txt

@@ -0,0 +1,7 @@
+add_executable(subexe ../empty.c)
+add_library(sublibUnknownImported UNKNOWN IMPORTED)
+
+target_link_libraries(mainexe mainlibUnknownImported)
+target_link_libraries(mainexe sublibUnknownImported)
+get_property(mainexe_libs TARGET mainexe PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "mainexe: ${mainexe_libs}")

+ 0 - 1
Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt

@@ -1 +0,0 @@
-1

+ 0 - 5
Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt

@@ -1,5 +0,0 @@
-^CMake Error at SubDirTarget.cmake:[0-9]+ \(target_link_libraries\):
-  Attempt to add link library "m" to target "subexe" which is not built in
-  this directory.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)$

+ 2 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget-stdout.txt

@@ -0,0 +1,2 @@
+-- mainexe: mainlib;sublib
+-- subexe: mainlib;sublib

+ 9 - 1
Tests/RunCMake/target_link_libraries/SubDirTarget.cmake

@@ -1,3 +1,11 @@
 enable_language(C)
+
+add_executable(mainexe empty.c)
+add_library(mainlib empty.c)
+
 add_subdirectory(SubDirTarget)
-target_link_libraries(subexe m)
+
+target_link_libraries(subexe mainlib)
+target_link_libraries(subexe sublib)
+get_property(subexe_libs TARGET subexe PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "subexe: ${subexe_libs}")

+ 6 - 0
Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt

@@ -1 +1,7 @@
 add_executable(subexe ../empty.c)
+add_library(sublib ../empty.c)
+
+target_link_libraries(mainexe mainlib)
+target_link_libraries(mainexe sublib)
+get_property(mainexe_libs TARGET mainexe PROPERTY INTERFACE_LINK_LIBRARIES)
+message(STATUS "mainexe: ${mainexe_libs}")