)
endfunction(add_gen_header)
-set(SINGLE_OBJECT_TARGET_TYPE "LIBC_SINGLE_OBJECT")
+set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY")
-# Function to generate single object file.
+# Rule which is essentially a wrapper over add_library to compile a set of
+# sources to object files.
# Usage:
-# add_object(
+# add_object_library(
# <target_name>
-# SRC <source file to compile>
+# HDRS <list of header files>
+# SRCS <list of source files>
# DEPENDS <list of dependencies>
# COMPILE_OPTIONS <optional list of special compile options for this target>
-function(add_object target_name)
+function(add_object_library target_name)
cmake_parse_arguments(
"ADD_OBJECT"
"" # No option arguments
- "SRC" # Single value arguments
- "COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
+ "" # Single value arguments
+ "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
${ARGN}
)
- if(NOT ADD_OBJECT_SRC)
- message(FATAL_ERROR "'add_object' rules requires a SRC to be specified.")
+ if(NOT ADD_OBJECT_SRCS)
+ message(FATAL_ERROR "'add_object_library' rule requires SRCS to be specified.")
endif()
add_library(
${target_name}
OBJECT
- ${ADD_OBJECT_SRC}
+ ${ADD_OBJECT_SRCS}
+ ${ADD_OBJECT_HDRS}
)
target_include_directories(
${target_name}
PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS}
)
endif()
+
+ set(all_object_files $<TARGET_OBJECTS:${target_name}>)
if(ADD_OBJECT_DEPENDS)
add_dependencies(
${target_name}
${ADD_OBJECT_DEPENDS}
)
+ 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 ${OBJECT_LIBRARY_TARGET_TYPE})))
+ continue()
+ endif()
+ # If a dependency is also a object file library, we will collect the list of
+ # object files from it.
+ get_target_property(obj_files ${obj_target} "OBJECT_FILES")
+ list(APPEND all_object_files ${obj_files})
+ endforeach(obj_target)
endif()
+ list(REMOVE_DUPLICATES all_object_files)
+
set_target_properties(
${target_name}
PROPERTIES
- "TARGET_TYPE" ${SINGLE_OBJECT_TARGET_TYPE}
- "OBJECT_FILE" $<TARGET_OBJECTS:${target_name}>
+ "TARGET_TYPE" ${OBJECT_LIBRARY_TARGET_TYPE}
+ "OBJECT_FILES" "${all_object_files}"
)
-endfunction(add_object)
+endfunction(add_object_library)
set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
"ADD_ENTRYPOINT_OBJ"
"REDIRECTED" # Optional argument
"NAME" # Single value arguments
- "SRCS;HDRS;SPECIAL_OBJECTS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
+ "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
${ARGN}
)
if(NOT ADD_ENTRYPOINT_OBJ_SRCS)
${target_name}_objects
support_common_h
)
+ set(dep_objects "")
if(ADD_ENTRYPOINT_OBJ_DEPENDS)
add_dependencies(
${target_name}_objects
${ADD_ENTRYPOINT_OBJ_DEPENDS}
)
+ foreach(dep_target IN LISTS ADD_ENTRYPOINT_OBJ_DEPENDS)
+ if(NOT TARGET ${dep_target})
+ # Not all targets will be visible. So, we will ignore those which aren't
+ # visible yet.
+ continue()
+ endif()
+ get_target_property(obj_type ${dep_target} "TARGET_TYPE")
+ if((NOT obj_type) OR (NOT (${obj_type} STREQUAL ${OBJECT_LIBRARY_TARGET_TYPE})))
+ # Even from among the visible targets, we will collect object files
+ # only from add_object_library targets.
+ continue()
+ endif()
+ # Calling get_target_property requires that the target be visible at this
+ # point. For object library dependencies, this is a reasonable requirement.
+ # We can revisit this in future if we need cases which break under this
+ # requirement.
+ get_target_property(obj_files ${dep_target} "OBJECT_FILES")
+ list(APPEND dep_objects ${obj_files})
+ endforeach(dep_target)
endif()
+ list(REMOVE_DUPLICATES dep_objects)
+
if(ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS)
target_compile_options(
${target_name}_objects
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 ${input_objects}
ALL
DEPENDS ${object_file}
)
+ set(all_objects ${object_file})
+ list(APPEND all_objects ${dep_objects})
+ set(all_objects_raw ${object_file_raw})
+ list(APPEND all_objects_raw ${dep_objects})
set_target_properties(
${target_name}
PROPERTIES
"TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
- "OBJECT_FILE" ${object_file}
- "OBJECT_FILE_RAW" ${object_file_raw}
+ "OBJECT_FILES" "${all_objects}"
+ "OBJECT_FILES_RAW" "${all_objects_raw}"
)
endfunction(add_entrypoint_object)
set(obj_list "")
foreach(dep IN LISTS ENTRYPOINT_LIBRARY_DEPENDS)
get_target_property(dep_type ${dep} "TARGET_TYPE")
- string(COMPARE EQUAL ${dep_type} ${ENTRYPOINT_OBJ_TARGET_TYPE} dep_is_entrypoint)
- if(NOT dep_is_entrypoint)
+ if(NOT (${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}))
message(FATAL_ERROR "Dependency '${dep}' of 'add_entrypoint_collection' is not an 'add_entrypoint_object' target.")
endif()
- get_target_property(target_obj_file ${dep} "OBJECT_FILE")
- list(APPEND obj_list "${target_obj_file}")
+ get_target_property(target_obj_files ${dep} "OBJECT_FILES")
+ list(APPEND obj_list "${target_obj_files}")
endforeach(dep)
+ list(REMOVE_DUPLICATES obj_list)
set(library_file "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${target_name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
add_custom_command(
set(library_deps "")
foreach(dep IN LISTS LIBC_UNITTEST_DEPENDS)
get_target_property(dep_type ${dep} "TARGET_TYPE")
- if (dep_type)
- string(COMPARE EQUAL ${dep_type} ${ENTRYPOINT_OBJ_TARGET_TYPE} dep_is_entrypoint)
- if(dep_is_entrypoint)
- get_target_property(obj_file ${dep} "OBJECT_FILE_RAW")
- list(APPEND library_deps ${obj_file})
- continue()
- endif()
+ if(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})
+ get_target_property(obj_files ${dep} "OBJECT_FILES_RAW")
+ list(APPEND library_deps ${obj_files})
+ elseif(${dep_type} STREQUAL ${OBJECT_LIBRARY_TARGET_TYPE})
+ get_target_property(obj_files ${dep} "OBJECT_FILES")
+ list(APPEND library_deps ${obj_files})
endif()
# TODO: Check if the dep is a normal CMake library target. If yes, then add it
# to the list of library_deps.
endforeach(dep)
+ list(REMOVE_DUPLICATES library_deps)
add_executable(
${target_name}
if (dep_type)
string(COMPARE EQUAL ${dep_type} ${ENTRYPOINT_OBJ_TARGET_TYPE} dep_is_entrypoint)
if(dep_is_entrypoint)
- get_target_property(obj_file ${dep} "OBJECT_FILE_RAW")
+ get_target_property(obj_file ${dep} "OBJECT_FILES_RAW")
list(APPEND library_deps ${obj_file})
continue()
endif()