[libc] Add a new rule `add_object`.
authorSiva Chandra Reddy <sivachandra@google.com>
Tue, 17 Mar 2020 06:40:57 +0000 (23:40 -0700)
committerSiva Chandra Reddy <sivachandra@google.com>
Tue, 17 Mar 2020 19:33:36 +0000 (12:33 -0700)
This rule can help add targets to generate special object files like the
crt1.o on linux. Also, it can be used to add specially compiled object
stubs which are to be linked into the entrypoint objects.

Reviewers: abrachet

Differential Revision: https://reviews.llvm.org/D76271

libc/cmake/modules/LLVMLibCRules.cmake

index 2fdaa63..18e1d0a 100644 (file)
@@ -94,6 +94,58 @@ function(add_gen_header target_name)
   )
 endfunction(add_gen_header)
 
+set(SINGLE_OBJECT_TARGET_TYPE "LIBC_SINGLE_OBJECT")
+
+# Function to generate single object file.
+# Usage:
+#     add_object(
+#       <target_name>
+#       SRC <source file to compile>
+#       DEPENDS <list of dependencies>
+#       COMPILE_OPTIONS <optional list of special compile options for this target>
+function(add_object target_name)
+  cmake_parse_arguments(
+    "ADD_OBJECT"
+    "" # No option arguments
+    "SRC" # Single value arguments
+    "COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
+    ${ARGN}
+  )
+
+  if(NOT ADD_OBJECT_SRC)
+    message(FATAL_ERROR "'add_object' rules requires a SRC to be specified.")
+  endif()
+
+  add_library(
+    ${target_name}
+    OBJECT
+    ${ADD_OBJECT_SRC}
+  )
+  target_include_directories(
+    ${target_name}
+    PRIVATE
+      "${LIBC_BUILD_DIR}/include;${LIBC_SOURCE_DIR};${LIBC_BUILD_DIR}"
+  )
+  if(ADD_OBJECT_COMPILE_OPTIONS)
+    target_compile_options(
+      ${target_name}
+      PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS}
+    )
+  endif()
+  if(ADD_OBJECT_DEPENDS)
+    add_dependencies(
+      ${target_name}
+      ${ADD_OBJECT_DEPENDS}
+    )
+  endif()
+  set_target_properties(
+    ${target_name}
+    PROPERTIES
+      "TARGET_TYPE" ${SINGLE_OBJECT_TARGET_TYPE}
+      "OBJECT_FILE" $<TARGET_OBJECTS:${target_name}>
+  )
+endfunction(add_object)
+
 set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
 
 # A rule for entrypoint object targets.
@@ -105,14 +157,15 @@ set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
 #       SRCS <list of .cpp files>
 #       HDRS <list of .h files>
 #       DEPENDS <list of dependencies>
-#       COMPILE_OPTIONS <list of special compile options for this target>
+#       COMPILE_OPTIONS <optional list of special compile options for this target>
+#       SPECIAL_OBJECTS <optional list of special object targets added by the rule `add_object`>
 #     )
 function(add_entrypoint_object target_name)
   cmake_parse_arguments(
     "ADD_ENTRYPOINT_OBJ"
     "REDIRECTED" # Optional argument
     "NAME" # Single value arguments
-    "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS"  # Multi value arguments
+    "SRCS;HDRS;SPECIAL_OBJECTS;DEPENDS;COMPILE_OPTIONS"  # Multi value arguments
     ${ARGN}
   )
   if(NOT ADD_ENTRYPOINT_OBJ_SRCS)
@@ -166,10 +219,21 @@ function(add_entrypoint_object target_name)
   set(object_file_raw "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_raw.o")
   set(object_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.o")
 
+  set(input_objects $<TARGET_OBJECTS:${target_name}_objects>)
+  if(ADD_ENTRYPOINT_OBJ_SPECIAL_OBJECTS)
+    foreach(obj_target IN LISTS ADD_ENTRYPOINT_OBJ_SPECIAL_OBJECTS)
+      get_target_property(obj_type ${obj_target} "TARGET_TYPE")
+      if((NOT obj_type) OR (NOT (${obj_type} STREQUAL ${SINGLE_OBJECT_TARGET_TYPE})))
+        message(FATAL_ERROR "Unexpected target type for 'SPECIAL_OBJECT' - should be a target introduced by the `add_object` rule.")
+      endif()
+      list(APPEND input_objects $<TARGET_OBJECTS:${obj_target}>)
+    endforeach(obj_target)
+  endif()
+
   add_custom_command(
     OUTPUT ${object_file_raw}
-    DEPENDS $<TARGET_OBJECTS:${target_name}_objects>
-    COMMAND ${CMAKE_LINKER} -r $<TARGET_OBJECTS:${target_name}_objects> -o ${object_file_raw}
+    DEPENDS ${input_objects}
+    COMMAND ${CMAKE_LINKER} -r ${input_objects} -o ${object_file_raw}
   )
 
   set(alias_attributes "0,function,global")