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,6 +94,64 @@ ) endfunction(add_gen_header) +set(SINGLE_OBJECT_TARGET_TYPE "LIBC_SINGLE_OBJECT") + +function(add_object target_name) + cmake_parse_arguments( + "ADD_OBJECT" + "" # No option arguments + "SRC;NAME" # 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() + if(ADD_OBJECT_NAME) + set_target_properties( + ${target_name} + PROPERTIES + "LIBRARY_OUTPUT_NAME" ${ADD_OBJECT_NAME} + ) + endif() + + get_target_property( + object_file_basename + ${target_name} + "LIBRARY_OUTPUT_NAME" + ) + set_target_properties( + ${target_name} + PROPERTIES + "TARGET_TYPE" ${SINGLE_OBJECT_TARGET_TYPE} + "OBJECT_FILE" ${CMAKE_CURRENT_BINARY_DIR}/${object_file} + ) +endfunction(add_object) + set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ") # A rule for entrypoint object targets. @@ -105,14 +163,15 @@ # SRCS # HDRS # DEPENDS -# COMPILE_OPTIONS +# COMPILE_OPTIONS +# SPECIAL_OBJECTS # ) 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 +225,21 @@ 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 $) + 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 $ - COMMAND ${CMAKE_LINKER} -r $ -o ${object_file_raw} + DEPENDS ${input_objects} + COMMAND ${CMAKE_LINKER} -r ${input_objects} -o ${object_file_raw} ) set(alias_attributes "0,function,global")