Browse Source

target_sources: Support custom targets

Fixes: #21034
Asit Dhal 5 years ago
parent
commit
1a3d125de8

+ 4 - 2
Help/command/target_sources.rst

@@ -15,7 +15,8 @@ Specifies sources to use when building a target and/or its dependents.
 Relative source file paths are interpreted as being relative to the current
 source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`).  The
 named ``<target>`` must have been created by a command such as
-:command:`add_executable` or :command:`add_library` and must not be an
+:command:`add_executable` or :command:`add_library` or
+:command:`add_custom_target` and must not be an
 :ref:`ALIAS target <Alias Targets>`.
 
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
@@ -27,7 +28,8 @@ items will populate the :prop_tgt:`SOURCES` property of
 when building dependents.  (:ref:`IMPORTED targets <Imported Targets>`
 only support ``INTERFACE`` items because they are not build targets.)
 The following arguments specify sources.  Repeated calls for the same
-``<target>`` append items in the order called.
+``<target>`` append items in the order called. The targets created by
+:command:`add_custom_target` can only have ``PRIVATE`` scope.
 
 Arguments to ``target_sources`` may use "generator expressions"
 with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`

+ 4 - 0
Help/release/dev/target-sources-supports-custom-target.rst

@@ -0,0 +1,4 @@
+target-sources-supports-custom-target
+-------------------------------------
+
+* The :command:`target_sources` now supports custom targets.

+ 25 - 9
Source/cmTargetPropCommandBase.cxx

@@ -45,15 +45,26 @@ bool cmTargetPropCommandBase::HandleArguments(
     this->HandleMissingTarget(args[0]);
     return false;
   }
-  if ((this->Target->GetType() != cmStateEnums::EXECUTABLE) &&
-      (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::UNKNOWN_LIBRARY)) {
-    this->SetError("called with non-compilable target type");
-    return false;
+  const bool isRegularTarget =
+    (this->Target->GetType() == cmStateEnums::EXECUTABLE) ||
+    (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::UNKNOWN_LIBRARY);
+  const bool isCustomTarget = this->Target->GetType() == cmStateEnums::UTILITY;
+
+  if (prop == "SOURCES") {
+    if (!isRegularTarget && !isCustomTarget) {
+      this->SetError("called with non-compilable target type");
+      return false;
+    }
+  } else {
+    if (!isRegularTarget) {
+      this->SetError("called with non-compilable target type");
+      return false;
+    }
   }
 
   bool system = false;
@@ -131,6 +142,11 @@ bool cmTargetPropCommandBase::ProcessContentArgs(
       this->SetError("may only set INTERFACE properties on IMPORTED targets");
       return false;
     }
+    if (this->Target->GetType() == cmStateEnums::UTILITY &&
+        scope != "PRIVATE") {
+      this->SetError("may only set PRIVATE properties on custom targets");
+      return false;
+    }
   }
   return this->PopulateTargetProperies(scope, content, prepend, system);
 }

+ 16 - 0
Tests/RunCMake/TargetSources/AddCustomTargetCheckProperty.cmake

@@ -0,0 +1,16 @@
+add_custom_target(target1 ALL)
+target_sources(target1 PRIVATE main.cpp)
+get_property(actualProp1 TARGET target1 PROPERTY SOURCES)
+set(desiredProp1 main.cpp)
+if(NOT desiredProp1 STREQUAL actualProp1)
+  message("source property not set. desired: \"${desiredProp1}\" actual: \"${actualProp1}\"")
+endif()
+
+add_custom_target(target2 ALL SOURCES main.cpp)
+target_sources(target2 PRIVATE empty_1.cpp empty_2.cpp)
+target_sources(target2 PRIVATE empty_3.cpp)
+get_property(actualProp2 TARGET target2 PROPERTY SOURCES)
+set(desiredProp2 main.cpp empty_1.cpp empty_2.cpp empty_3.cpp)
+if (NOT desiredProp2 STREQUAL actualProp2)
+  message("source property not set. desired: \"${desiredProp2}\" actual: \"${actualProp2}\"")
+endif()

+ 2 - 0
Tests/RunCMake/TargetSources/AddCustomTargetGenx.cmake

@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target PRIVATE $<IF:1,${CMAKE_CURRENT_LIST_DIR}/main.cpp,${CMAKE_CURRENT_LIST_DIR}/empty_1.cpp>)

+ 1 - 0
Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources-result.txt

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

+ 4 - 0
Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at AddCustomTargetInterfaceSources.cmake:2 \(target_sources\):
+  target_sources may only set PRIVATE properties on custom targets
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources.cmake

@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target INTERFACE main.cpp)

+ 2 - 0
Tests/RunCMake/TargetSources/AddCustomTargetPrivateSources.cmake

@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target PRIVATE main.cpp)

+ 1 - 0
Tests/RunCMake/TargetSources/AddCustomTargetPublicSources-result.txt

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

+ 4 - 0
Tests/RunCMake/TargetSources/AddCustomTargetPublicSources-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at AddCustomTargetPublicSources.cmake:2 \(target_sources\):
+  target_sources may only set PRIVATE properties on custom targets
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/TargetSources/AddCustomTargetPublicSources.cmake

@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target PUBLIC main.cpp)

+ 1 - 0
Tests/RunCMake/TargetSources/AddCustomTargetSources-result.txt

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

+ 4 - 0
Tests/RunCMake/TargetSources/AddCustomTargetSources-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at AddCustomTargetSources.cmake:2 \(target_sources\):
+  target_sources called with invalid arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/TargetSources/AddCustomTargetSources.cmake

@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target main.cpp)

+ 6 - 0
Tests/RunCMake/TargetSources/RunCMakeTest.cmake

@@ -14,3 +14,9 @@ run_cmake(RelativePathInSubdirInterface)
 run_cmake(RelativePathInSubdirPrivate)
 run_cmake(RelativePathInSubdirInclude)
 run_cmake(ExportBuild)
+run_cmake(AddCustomTargetPublicSources)
+run_cmake(AddCustomTargetPrivateSources)
+run_cmake(AddCustomTargetInterfaceSources)
+run_cmake(AddCustomTargetSources)
+run_cmake(AddCustomTargetCheckProperty)
+run_cmake(AddCustomTargetGenx)