浏览代码

Relax the usage of TARGET_OBJECTS generator expression

The geneator expression can now be used with static, shared, and
module libraries and executables.
Robert Maynard 6 年之前
父节点
当前提交
ce078dda79

+ 1 - 2
Help/manual/cmake-generator-expressions.7.rst

@@ -461,8 +461,7 @@ Output-Related Expressions
   Content of ``...`` converted to a C identifier.  The conversion follows the
   same behavior as :command:`string(MAKE_C_IDENTIFIER)`.
 ``$<TARGET_OBJECTS:objLib>``
-  List of objects resulting from build of ``objLib``. ``objLib`` must be an
-  object of type ``OBJECT_LIBRARY``.
+  List of objects resulting from build of ``objLib``.
 ``$<SHELL_PATH:...>``
   Content of ``...`` converted to shell path style. For example, slashes are
   converted to backslashes in Windows shells and drive letters are converted

+ 5 - 0
Help/release/dev/relax-TARGET_OBJECTS-generator-expression.rst

@@ -0,0 +1,5 @@
+relax-TARGET_OBJECTS-generator-expression
+-----------------------------------------
+
+* The ``TARGET_OBJECTS`` :manual:`generator expression <cmake-generator-expressions(7)>`
+  is now supported on ``SHARED``, ``STATIC``, ``MODULE`` libraries and executables.

+ 8 - 2
Source/cmGeneratorExpressionNode.cxx

@@ -1525,10 +1525,16 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
       reportError(context, content->GetOriginalExpression(), e.str());
       return std::string();
     }
-    if (gt->GetType() != cmStateEnums::OBJECT_LIBRARY) {
+    cmStateEnums::TargetType type = gt->GetType();
+    if (type != cmStateEnums::EXECUTABLE &&
+        type != cmStateEnums::STATIC_LIBRARY &&
+        type != cmStateEnums::SHARED_LIBRARY &&
+        type != cmStateEnums::MODULE_LIBRARY &&
+        type != cmStateEnums::OBJECT_LIBRARY) {
       std::ostringstream e;
       e << "Objects of target \"" << tgtName
-        << "\" referenced but is not an OBJECT library.";
+        << "\" referenced but is not an allowed library types (EXECUTABLE, "
+        << "STATIC, SHARED, MODULE, OBJECT).";
       reportError(context, content->GetOriginalExpression(), e.str());
       return std::string();
     }

+ 45 - 0
Tests/GeneratorExpression/CMakeLists.txt

@@ -374,4 +374,49 @@ if(NOT CMAKE_GENERATOR STREQUAL Xcode OR NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;
       -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
     DEPENDS objlib
   )
+
+
+  add_library(sharedlib SHARED objlib1.c objlib2.c)
+  file(GENERATE
+    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/sharedlib_files_$<CONFIGURATION>"
+    CONTENT "$<JOIN:$<TARGET_OBJECTS:sharedlib>,\n>\n"
+  )
+
+  add_custom_target(check_sharedlib_objs ALL
+    COMMAND ${CMAKE_COMMAND}
+      "-DOBJLIB_LISTFILE=${CMAKE_CURRENT_BINARY_DIR}/sharedlib_files_$<CONFIGURATION>"
+      -DEXPECTED_NUM_OBJECTFILES=2
+      -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+    DEPENDS sharedlib
+  )
+
+
+  add_library(staticlib STATIC objlib1.c objlib2.c)
+  file(GENERATE
+    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/staticlib_files_$<CONFIGURATION>"
+    CONTENT "$<JOIN:$<TARGET_OBJECTS:staticlib>,\n>\n"
+  )
+
+  add_custom_target(check_staticlib_objs ALL
+    COMMAND ${CMAKE_COMMAND}
+      "-DOBJLIB_LISTFILE=${CMAKE_CURRENT_BINARY_DIR}/staticlib_files_$<CONFIGURATION>"
+      -DEXPECTED_NUM_OBJECTFILES=2
+      -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+    DEPENDS staticlib
+  )
+
+
+  add_executable(execobjs objlib1.c objlib2.c echo.c)
+  file(GENERATE
+    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/execobjs_files_$<CONFIGURATION>"
+    CONTENT "$<JOIN:$<TARGET_OBJECTS:execobjs>,\n>\n"
+  )
+
+  add_custom_target(check_exec_objs ALL
+    COMMAND ${CMAKE_COMMAND}
+      "-DOBJLIB_LISTFILE=${CMAKE_CURRENT_BINARY_DIR}/execobjs_files_$<CONFIGURATION>"
+      -DEXPECTED_NUM_OBJECTFILES=3
+      -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+    DEPENDS execobjs
+  )
 endif()

+ 10 - 0
Tests/ObjectLibrary/CMakeLists.txt

@@ -62,4 +62,14 @@ add_custom_target(UseABinternalDep COMMAND ${CMAKE_COMMAND} -E touch UseABintern
 add_custom_command(TARGET UseABinternal POST_BUILD COMMAND ${CMAKE_COMMAND} -P UseABinternalDep.cmake)
 add_dependencies(UseABinternal UseABinternalDep)
 
+# Test a static library with sources from a different static library
+add_library(UseCstaticObjs STATIC $<TARGET_OBJECTS:Cstatic> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:Bexport>)
+
+# Test a shared library with sources from a different shared library
+add_library(UseCsharedObjs SHARED $<TARGET_OBJECTS:Cshared> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:Bexport>)
+
+# Test a shared executable with sources from a different shared library
+add_executable(UseABstaticObjs $<TARGET_OBJECTS:UseABstatic>)
+target_link_libraries(UseABstaticObjs ABstatic)
+
 add_subdirectory(ExportLanguages)

+ 2 - 1
Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt

@@ -3,6 +3,7 @@ CMake Error at OutputNameMatchesObjects.cmake:[0-9]+ \(file\):
 
     \$<TARGET_OBJECTS:foo>
 
-  Objects of target "foo" referenced but is not an OBJECT library.
+  Objects of target "foo" referenced but is not an allowed library types
+  \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\).
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)

+ 2 - 5
Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake

@@ -1,11 +1,8 @@
 enable_language(CXX)
 
 file(GENERATE
-  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_OBJECTS:foo>>somefile.cpp"
+  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>/somefile.cpp"
   CONTENT "static const char content[] = \"$<TARGET_OBJECTS:foo>\";\n"
 )
 
-add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/input.txt"
-  COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" "${CMAKE_CURRENT_BINARY_DIR}")
-
-add_executable(foo empty.cpp "${CMAKE_CURRENT_BINARY_DIR}/1somefile.cpp" "${CMAKE_CURRENT_BINARY_DIR}/input.txt")
+add_library(foo INTERFACE )

+ 3 - 2
Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt

@@ -3,6 +3,7 @@ CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
 
     \$<TARGET_OBJECTS:NotObjLib>
 
-  Objects of target "NotObjLib" referenced but is not an OBJECT library.
+  Objects of target "NotObjLib" referenced but is not an allowed library
+  types \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\).
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)

+ 1 - 1
Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake

@@ -1,2 +1,2 @@
-add_library(NotObjLib STATIC a.c)
+add_library(NotObjLib INTERFACE)
 add_library(A STATIC a.c $<TARGET_OBJECTS:NotObjLib>)

+ 32 - 0
Tests/RunCMake/ObjectLibrary/CheckTargetObjects.cmake

@@ -0,0 +1,32 @@
+add_library(StaticLib STATIC a.c)
+
+add_custom_command(TARGET StaticLib POST_BUILD
+  VERBATIM
+  COMMAND ${CMAKE_COMMAND}
+    "-DTARGET_OBJECTS=$<TARGET_OBJECTS:StaticLib>"
+    -DEXPECTED_NUM_OBJECTFILES=2
+    -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+  )
+
+add_library(SharedLib SHARED a.c b.c)
+target_compile_definitions(SharedLib PRIVATE REQUIRED)
+
+add_custom_command(TARGET SharedLib POST_BUILD
+  VERBATIM
+  COMMAND ${CMAKE_COMMAND}
+    "-DTARGET_OBJECTS:STRING=$<TARGET_OBJECTS:SharedLib>"
+    -DEXPECTED_NUM_OBJECTFILES=2
+    -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+  )
+
+add_executable(ExecObjs a.c b.c exe.c)
+target_compile_definitions(ExecObjs PRIVATE REQUIRED)
+
+add_custom_target(check_exec_objs ALL
+  VERBATIM
+  COMMAND ${CMAKE_COMMAND}
+    "-DTARGET_OBJECTS=$<TARGET_OBJECTS:ExecObjs>"
+    -DEXPECTED_NUM_OBJECTFILES=3
+    -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+  DEPENDS ExecObjs
+  )

+ 5 - 0
Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake

@@ -37,6 +37,10 @@ function (run_object_lib_build2 name)
   run_cmake_command(${name}-build ${CMAKE_COMMAND} --build .)
 endfunction ()
 
+if(NOT (RunCMake_GENERATOR STREQUAL "Xcode" AND "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]"))
+  run_object_lib_build(CheckTargetObjects)
+endif()
+
 run_object_lib_build(LinkObjLHSShared)
 run_object_lib_build(LinkObjLHSStatic)
 run_object_lib_build(LinkObjRHSShared)
@@ -54,6 +58,7 @@ run_cmake(PostBuild)
 run_cmake(PreBuild)
 run_cmake(PreLink)
 
+
 function(run_Dependencies)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Dependencies-build)
   set(RunCMake_TEST_NO_CLEAN 1)

+ 17 - 0
Tests/RunCMake/ObjectLibrary/check_object_files.cmake

@@ -0,0 +1,17 @@
+
+if (NOT TARGET_OBJECTS)
+  message(SEND_ERROR "Object not passed as -DTARGET_OBJECTS")
+endif()
+
+foreach(objlib_file IN LISTS objects)
+  message(STATUS "objlib_file: =${objlib_file}=")
+
+  set(file_exists False)
+  if (EXISTS "${objlib_file}")
+    set(file_exists True)
+  endif()
+
+  if (NOT file_exists)
+    message(SEND_ERROR "File \"${objlib_file}\" does not exist!${tried}")
+  endif()
+endforeach()

+ 5 - 4
Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt

@@ -1,8 +1,9 @@
-CMake Error at NotObjlibTarget.cmake:3 \(file\):
+CMake Error at NotObjlibTarget.cmake:[0-9]+ \(file\):
   Error evaluating generator expression:
 
-    \$<TARGET_OBJECTS:StaticLib>
+    \$<TARGET_OBJECTS:IFaceLib>
 
-  Objects of target "StaticLib" referenced but is not an OBJECT library.
+  Objects of target "IFaceLib" referenced but is not an allowed library types
+  \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\).
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)

+ 2 - 2
Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake

@@ -1,3 +1,3 @@
-add_library(StaticLib empty.cpp)
+add_library(IFaceLib INTERFACE )
 
-file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_output CONTENT $<TARGET_OBJECTS:StaticLib>)
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_output CONTENT $<TARGET_OBJECTS:IFaceLib>)