diff --git a/libc/cmake/modules/LLVMLibCRules.cmake b/libc/cmake/modules/LLVMLibCRules.cmake --- a/libc/cmake/modules/LLVMLibCRules.cmake +++ b/libc/cmake/modules/LLVMLibCRules.cmake @@ -94,32 +94,35 @@ ) 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( # -# SRC +# HDRS +# SRCS # DEPENDS # COMPILE_OPTIONS -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} @@ -132,19 +135,33 @@ PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS} ) endif() + + set(all_object_files $) 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_TYPE" ${OBJECT_LIBRARY_TARGET_TYPE} + "OBJECT_FILES" "${all_object_files}" ) -endfunction(add_object) +endfunction(add_object_library) set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ") @@ -165,7 +182,7 @@ "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) @@ -203,12 +220,34 @@ ${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 @@ -220,16 +259,6 @@ set(object_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.o") set(input_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 $) - endforeach(obj_target) - endif() - add_custom_command( OUTPUT ${object_file_raw} DEPENDS ${input_objects} @@ -253,12 +282,16 @@ 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) @@ -282,13 +315,13 @@ 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( @@ -396,17 +429,17 @@ 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} @@ -488,7 +521,7 @@ 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() diff --git a/libc/loader/linux/CMakeLists.txt b/libc/loader/linux/CMakeLists.txt --- a/libc/loader/linux/CMakeLists.txt +++ b/libc/loader/linux/CMakeLists.txt @@ -6,9 +6,9 @@ "DEPENDS;COMPILE_OPTIONS" # Multi value arguments ${ARGN} ) - add_object( + add_object_library( ${name}_object - SRC ${ADD_LOADER_OBJECT_SRC} + SRCS ${ADD_LOADER_OBJECT_SRC} DEPENDS ${ADD_LOADER_OBJECT_DEPENDS} COMPILE_OPTIONS ${ADD_LOADER_OBJECT_COMPILE_OPTIONS} ) @@ -27,7 +27,7 @@ ${name} PROPERTIES "TARGET_TYPE" "LOADER_OBJECT" - "OBJECT_FILE" ${objfile} + "OBJECT_FILES" ${objfile} ) endfunction() diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt --- a/libc/src/signal/linux/CMakeLists.txt +++ b/libc/src/signal/linux/CMakeLists.txt @@ -12,9 +12,9 @@ signal_h ) -add_object( +add_object_library( __restore - SRC + SRCS __restore.cpp COMPILE_OPTIONS -fomit-frame-pointer @@ -41,8 +41,6 @@ sys_syscall_h linux_syscall_h signal_h - SPECIAL_OBJECTS - __restore ) add_entrypoint_object( diff --git a/libc/test/loader/CMakeLists.txt b/libc/test/loader/CMakeLists.txt --- a/libc/test/loader/CMakeLists.txt +++ b/libc/test/loader/CMakeLists.txt @@ -32,7 +32,7 @@ if(ADD_LOADER_TEST_DEPENDS) add_dependencies(${target_name} ${ADD_LOADER_TEST_DEPENDS}) foreach(dep IN LISTS ADD_LOADER_TEST_DEPENDS) - get_target_property(objfile ${dep} "OBJECT_FILE") + get_target_property(objfile ${dep} "OBJECT_FILES") if(NOT objfile) message( FATAL_ERROR diff --git a/libc/test/src/signal/CMakeLists.txt b/libc/test/src/signal/CMakeLists.txt --- a/libc/test/src/signal/CMakeLists.txt +++ b/libc/test/src/signal/CMakeLists.txt @@ -23,7 +23,6 @@ signal_h errno_h __errno_location - __restore ) add_libc_unittest(