[libc] Extend add_object rule to handle helper object libraries.

The rule is now called add_object_library.

Reviewers: abrachet

Differential Revision: https://reviews.llvm.org/D76826
This commit is contained in:
Siva Chandra Reddy 2020-03-25 09:44:06 -07:00
parent 255e634bf7
commit 51b899c846
5 changed files with 77 additions and 47 deletions

View File

@ -94,32 +94,35 @@ function(add_gen_header target_name)
) )
endfunction(add_gen_header) 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: # Usage:
# add_object( # add_object_library(
# <target_name> # <target_name>
# SRC <source file to compile> # HDRS <list of header files>
# SRCS <list of source files>
# DEPENDS <list of dependencies> # DEPENDS <list of dependencies>
# COMPILE_OPTIONS <optional list of special compile options for this target> # 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( cmake_parse_arguments(
"ADD_OBJECT" "ADD_OBJECT"
"" # No option arguments "" # No option arguments
"SRC" # Single value arguments "" # Single value arguments
"COMPILE_OPTIONS;DEPENDS" # Multivalue arguments "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
${ARGN} ${ARGN}
) )
if(NOT ADD_OBJECT_SRC) if(NOT ADD_OBJECT_SRCS)
message(FATAL_ERROR "'add_object' rules requires a SRC to be specified.") message(FATAL_ERROR "'add_object_library' rule requires SRCS to be specified.")
endif() endif()
add_library( add_library(
${target_name} ${target_name}
OBJECT OBJECT
${ADD_OBJECT_SRC} ${ADD_OBJECT_SRCS}
${ADD_OBJECT_HDRS}
) )
target_include_directories( target_include_directories(
${target_name} ${target_name}
@ -132,19 +135,33 @@ function(add_object target_name)
PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS} PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS}
) )
endif() endif()
set(all_object_files $<TARGET_OBJECTS:${target_name}>)
if(ADD_OBJECT_DEPENDS) if(ADD_OBJECT_DEPENDS)
add_dependencies( add_dependencies(
${target_name} ${target_name}
${ADD_OBJECT_DEPENDS} ${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() endif()
list(REMOVE_DUPLICATES all_object_files)
set_target_properties( set_target_properties(
${target_name} ${target_name}
PROPERTIES PROPERTIES
"TARGET_TYPE" ${SINGLE_OBJECT_TARGET_TYPE} "TARGET_TYPE" ${OBJECT_LIBRARY_TARGET_TYPE}
"OBJECT_FILE" $<TARGET_OBJECTS:${target_name}> "OBJECT_FILES" "${all_object_files}"
) )
endfunction(add_object) endfunction(add_object_library)
set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ") set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
@ -165,7 +182,7 @@ function(add_entrypoint_object target_name)
"ADD_ENTRYPOINT_OBJ" "ADD_ENTRYPOINT_OBJ"
"REDIRECTED" # Optional argument "REDIRECTED" # Optional argument
"NAME" # Single value arguments "NAME" # Single value arguments
"SRCS;HDRS;SPECIAL_OBJECTS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
${ARGN} ${ARGN}
) )
if(NOT ADD_ENTRYPOINT_OBJ_SRCS) if(NOT ADD_ENTRYPOINT_OBJ_SRCS)
@ -203,12 +220,34 @@ function(add_entrypoint_object target_name)
${target_name}_objects ${target_name}_objects
support_common_h support_common_h
) )
set(dep_objects "")
if(ADD_ENTRYPOINT_OBJ_DEPENDS) if(ADD_ENTRYPOINT_OBJ_DEPENDS)
add_dependencies( add_dependencies(
${target_name}_objects ${target_name}_objects
${ADD_ENTRYPOINT_OBJ_DEPENDS} ${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() endif()
list(REMOVE_DUPLICATES dep_objects)
if(ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS) if(ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS)
target_compile_options( target_compile_options(
${target_name}_objects ${target_name}_objects
@ -220,16 +259,6 @@ function(add_entrypoint_object target_name)
set(object_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.o") set(object_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.o")
set(input_objects $<TARGET_OBJECTS:${target_name}_objects>) 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( add_custom_command(
OUTPUT ${object_file_raw} OUTPUT ${object_file_raw}
DEPENDS ${input_objects} DEPENDS ${input_objects}
@ -253,12 +282,16 @@ function(add_entrypoint_object target_name)
ALL ALL
DEPENDS ${object_file} 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( set_target_properties(
${target_name} ${target_name}
PROPERTIES PROPERTIES
"TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE} "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
"OBJECT_FILE" ${object_file} "OBJECT_FILES" "${all_objects}"
"OBJECT_FILE_RAW" ${object_file_raw} "OBJECT_FILES_RAW" "${all_objects_raw}"
) )
endfunction(add_entrypoint_object) endfunction(add_entrypoint_object)
@ -282,13 +315,13 @@ function(add_entrypoint_library target_name)
set(obj_list "") set(obj_list "")
foreach(dep IN LISTS ENTRYPOINT_LIBRARY_DEPENDS) foreach(dep IN LISTS ENTRYPOINT_LIBRARY_DEPENDS)
get_target_property(dep_type ${dep} "TARGET_TYPE") get_target_property(dep_type ${dep} "TARGET_TYPE")
string(COMPARE EQUAL ${dep_type} ${ENTRYPOINT_OBJ_TARGET_TYPE} dep_is_entrypoint) if(NOT (${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}))
if(NOT dep_is_entrypoint)
message(FATAL_ERROR "Dependency '${dep}' of 'add_entrypoint_collection' is not an 'add_entrypoint_object' target.") message(FATAL_ERROR "Dependency '${dep}' of 'add_entrypoint_collection' is not an 'add_entrypoint_object' target.")
endif() endif()
get_target_property(target_obj_file ${dep} "OBJECT_FILE") get_target_property(target_obj_files ${dep} "OBJECT_FILES")
list(APPEND obj_list "${target_obj_file}") list(APPEND obj_list "${target_obj_files}")
endforeach(dep) endforeach(dep)
list(REMOVE_DUPLICATES obj_list)
set(library_file "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${target_name}${CMAKE_STATIC_LIBRARY_SUFFIX}") set(library_file "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${target_name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
add_custom_command( add_custom_command(
@ -396,17 +429,17 @@ function(add_libc_unittest target_name)
set(library_deps "") set(library_deps "")
foreach(dep IN LISTS LIBC_UNITTEST_DEPENDS) foreach(dep IN LISTS LIBC_UNITTEST_DEPENDS)
get_target_property(dep_type ${dep} "TARGET_TYPE") get_target_property(dep_type ${dep} "TARGET_TYPE")
if (dep_type) if(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})
string(COMPARE EQUAL ${dep_type} ${ENTRYPOINT_OBJ_TARGET_TYPE} dep_is_entrypoint) get_target_property(obj_files ${dep} "OBJECT_FILES_RAW")
if(dep_is_entrypoint) list(APPEND library_deps ${obj_files})
get_target_property(obj_file ${dep} "OBJECT_FILE_RAW") elseif(${dep_type} STREQUAL ${OBJECT_LIBRARY_TARGET_TYPE})
list(APPEND library_deps ${obj_file}) get_target_property(obj_files ${dep} "OBJECT_FILES")
continue() list(APPEND library_deps ${obj_files})
endif()
endif() endif()
# TODO: Check if the dep is a normal CMake library target. If yes, then add it # TODO: Check if the dep is a normal CMake library target. If yes, then add it
# to the list of library_deps. # to the list of library_deps.
endforeach(dep) endforeach(dep)
list(REMOVE_DUPLICATES library_deps)
add_executable( add_executable(
${target_name} ${target_name}
@ -488,7 +521,7 @@ function(add_libc_fuzzer target_name)
if (dep_type) if (dep_type)
string(COMPARE EQUAL ${dep_type} ${ENTRYPOINT_OBJ_TARGET_TYPE} dep_is_entrypoint) string(COMPARE EQUAL ${dep_type} ${ENTRYPOINT_OBJ_TARGET_TYPE} dep_is_entrypoint)
if(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}) list(APPEND library_deps ${obj_file})
continue() continue()
endif() endif()

View File

@ -6,9 +6,9 @@ function(add_loader_object name)
"DEPENDS;COMPILE_OPTIONS" # Multi value arguments "DEPENDS;COMPILE_OPTIONS" # Multi value arguments
${ARGN} ${ARGN}
) )
add_object( add_object_library(
${name}_object ${name}_object
SRC ${ADD_LOADER_OBJECT_SRC} SRCS ${ADD_LOADER_OBJECT_SRC}
DEPENDS ${ADD_LOADER_OBJECT_DEPENDS} DEPENDS ${ADD_LOADER_OBJECT_DEPENDS}
COMPILE_OPTIONS ${ADD_LOADER_OBJECT_COMPILE_OPTIONS} COMPILE_OPTIONS ${ADD_LOADER_OBJECT_COMPILE_OPTIONS}
) )
@ -27,7 +27,7 @@ function(add_loader_object name)
${name} ${name}
PROPERTIES PROPERTIES
"TARGET_TYPE" "LOADER_OBJECT" "TARGET_TYPE" "LOADER_OBJECT"
"OBJECT_FILE" ${objfile} "OBJECT_FILES" ${objfile}
) )
endfunction() endfunction()

View File

@ -12,9 +12,9 @@ add_entrypoint_object(
signal_h signal_h
) )
add_object( add_object_library(
__restore __restore
SRC SRCS
__restore.cpp __restore.cpp
COMPILE_OPTIONS COMPILE_OPTIONS
-fomit-frame-pointer -fomit-frame-pointer
@ -41,8 +41,6 @@ add_entrypoint_object(
sys_syscall_h sys_syscall_h
linux_syscall_h linux_syscall_h
signal_h signal_h
SPECIAL_OBJECTS
__restore
) )
add_entrypoint_object( add_entrypoint_object(

View File

@ -32,7 +32,7 @@ function(add_loader_test target_name)
if(ADD_LOADER_TEST_DEPENDS) if(ADD_LOADER_TEST_DEPENDS)
add_dependencies(${target_name} ${ADD_LOADER_TEST_DEPENDS}) add_dependencies(${target_name} ${ADD_LOADER_TEST_DEPENDS})
foreach(dep IN LISTS 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) if(NOT objfile)
message( message(
FATAL_ERROR FATAL_ERROR

View File

@ -23,7 +23,6 @@ add_libc_unittest(
signal_h signal_h
errno_h errno_h
__errno_location __errno_location
__restore
) )
add_libc_unittest( add_libc_unittest(