Browse Source

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 years ago
parent
commit
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
   Content of ``...`` converted to a C identifier.  The conversion follows the
   same behavior as :command:`string(MAKE_C_IDENTIFIER)`.
   same behavior as :command:`string(MAKE_C_IDENTIFIER)`.
 ``$<TARGET_OBJECTS:objLib>``
 ``$<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:...>``
 ``$<SHELL_PATH:...>``
   Content of ``...`` converted to shell path style. For example, slashes are
   Content of ``...`` converted to shell path style. For example, slashes are
   converted to backslashes in Windows shells and drive letters are converted
   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());
       reportError(context, content->GetOriginalExpression(), e.str());
       return std::string();
       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;
       std::ostringstream e;
       e << "Objects of target \"" << tgtName
       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());
       reportError(context, content->GetOriginalExpression(), e.str());
       return std::string();
       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"
       -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
     DEPENDS objlib
     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()
 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_custom_command(TARGET UseABinternal POST_BUILD COMMAND ${CMAKE_COMMAND} -P UseABinternalDep.cmake)
 add_dependencies(UseABinternal UseABinternalDep)
 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)
 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>
     \$<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\):
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
   CMakeLists.txt:[0-9]+ \(include\)

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

@@ -1,11 +1,8 @@
 enable_language(CXX)
 enable_language(CXX)
 
 
 file(GENERATE
 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"
   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>
     \$<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\):
 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>)
 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 .)
   run_cmake_command(${name}-build ${CMAKE_COMMAND} --build .)
 endfunction ()
 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(LinkObjLHSShared)
 run_object_lib_build(LinkObjLHSStatic)
 run_object_lib_build(LinkObjLHSStatic)
 run_object_lib_build(LinkObjRHSShared)
 run_object_lib_build(LinkObjRHSShared)
@@ -54,6 +58,7 @@ run_cmake(PostBuild)
 run_cmake(PreBuild)
 run_cmake(PreBuild)
 run_cmake(PreLink)
 run_cmake(PreLink)
 
 
+
 function(run_Dependencies)
 function(run_Dependencies)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Dependencies-build)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Dependencies-build)
   set(RunCMake_TEST_NO_CLEAN 1)
   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:
   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\):
 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>)