Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTue Ly <lntue.h@gmail.com>2022-05-08 20:45:40 +0300
committerTue Ly <lntue@google.com>2022-06-01 07:54:07 +0300
commit800051487f13e5506502c0c4021a97a53b89bcde (patch)
tree575cf333eec3e87f02c877714f43866a0db1432e /libc/cmake/modules/LLVMLibCObjectRules.cmake
parent17296607a761086b2c0e6518ceaa16415dceb55b (diff)
[libc] Implement FLAGS option for generating all combinations for targets.
Add FLAGS option for add_header_library, add_object_library, add_entrypoint_object, and add_libc_unittest. In general, a flag is a string provided for supported functions under the multi-valued option `FLAGS`. It should be one of the following forms: FLAG_NAME FLAG_NAME__NO FLAG_NAME__ONLY A target will inherit all the flags of its upstream dependency. When we create a target `TARGET_NAME` with a flag using (add_header_library, add_object_library, ...), its behavior will depend on the flag form as follow: - FLAG_NAME: The following 2 targets will be generated: `TARGET_NAME` that has `FLAG_NAME` in its `FLAGS` property. `TARGET_NAME.__NO_FLAG_NAME` that depends on `DEP.__NO_FLAG_NAME` if `TARGET_NAME` depends on `DEP` and `DEP` has `FLAG_NAME` in its `FLAGS` property. - FLAG_NAME__ONLY: Only generate 1 target `TARGET_NAME` that has `FLAG_NAME` in its `FLAGS` property. - FLAG_NAME__NO: Only generate 1 target `TARGET_NAME.__NO_FLAG_NAME` that depends on `DEP.__NO_FLAG_NAME` if `DEP` is in its DEPENDS list and `DEP` has `FLAG_NAME` in its `FLAGS` property. To show all the targets generated, pass SHOW_INTERMEDIATE_OBJECTS=ON to cmake. To show all the targets' dependency and flags, pass `SHOW_INTERMEDIATE_OBJECTS=DEPS` to cmake. To completely disable a flag FLAG_NAME expansion, set the variable `SKIP_FLAG_EXPANSION_FLAG_NAME=TRUE`. Reviewed By: michaelrj, sivachandra Differential Revision: https://reviews.llvm.org/D125174
Diffstat (limited to 'libc/cmake/modules/LLVMLibCObjectRules.cmake')
-rw-r--r--libc/cmake/modules/LLVMLibCObjectRules.cmake301
1 files changed, 258 insertions, 43 deletions
diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake
index 8e2f489752a6..ae49e136615e 100644
--- a/libc/cmake/modules/LLVMLibCObjectRules.cmake
+++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake
@@ -1,7 +1,7 @@
set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY")
function(_get_common_compile_options output_var)
- set(compile_options ${LLVM_CXX_STD_default} ${LIBC_COMPILE_OPTIONS_DEFAULT} ${ARGN})
+ set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${ARGN})
if(NOT ${LIBC_TARGET_OS} STREQUAL "windows")
set(compile_options ${compile_options} -fpie -ffreestanding)
endif()
@@ -26,12 +26,13 @@ endfunction()
# SRCS <list of source files>
# DEPENDS <list of dependencies>
# COMPILE_OPTIONS <optional list of special compile options for this target>
-function(add_object_library target_name)
+# FLAGS <optional list of flags>
+function(create_object_library fq_target_name)
cmake_parse_arguments(
"ADD_OBJECT"
"" # No optional arguments
"CXX_STANDARD" # Single value arguments
- "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
+ "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS;FLAGS" # Multivalue arguments
${ARGN}
)
@@ -39,7 +40,6 @@ function(add_object_library target_name)
message(FATAL_ERROR "'add_object_library' rule requires SRCS to be specified.")
endif()
- get_fq_target_name(${target_name} fq_target_name)
add_library(
${fq_target_name}
EXCLUDE_FROM_ALL
@@ -58,24 +58,126 @@ function(add_object_library target_name)
target_compile_options(${fq_target_name} PRIVATE ${compile_options})
get_fq_deps_list(fq_deps_list ${ADD_OBJECT_DEPENDS})
+
+ if(SHOW_INTERMEDIATE_OBJECTS)
+ message(STATUS "Adding object library ${fq_target_name}")
+ if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS")
+ foreach(dep IN LISTS ADD_OBJECT_DEPENDS)
+ message(STATUS " ${fq_target_name} depends on ${dep}")
+ endforeach()
+ endif()
+ endif()
+
if(fq_deps_list)
add_dependencies(${fq_target_name} ${fq_deps_list})
endif()
- if(ADD_OBJECT_CXX_STANDARD)
- set_target_properties(
- ${fq_target_name}
- PROPERTIES
- CXX_STANDARD ${ADD_OBJECT_CXX_STANDARD}
- )
+ if(NOT ADD_OBJECT_CXX_STANDARD)
+ set(ADD_OBJECT_CXX_STANDARD ${CMAKE_CXX_STANDARD})
endif()
-
+
set_target_properties(
${fq_target_name}
PROPERTIES
- "TARGET_TYPE" ${OBJECT_LIBRARY_TARGET_TYPE}
- "OBJECT_FILES" "$<TARGET_OBJECTS:${fq_target_name}>"
- "DEPS" "${fq_deps_list}"
+ TARGET_TYPE ${OBJECT_LIBRARY_TARGET_TYPE}
+ OBJECT_FILES "$<TARGET_OBJECTS:${fq_target_name}>"
+ CXX_STANDARD ${ADD_OBJECT_CXX_STANDARD}
+ DEPS "${fq_deps_list}"
+ FLAGS "${ADD_OBJECT_FLAGS}"
+ )
+endfunction(create_object_library)
+
+# Internal function, used by `add_object_library`.
+function(expand_flags_for_object_library target_name flags)
+ cmake_parse_arguments(
+ "EXPAND_FLAGS"
+ "IGNORE_MARKER" # Optional arguments
+ "" # Single-value arguments
+ "DEPENDS;FLAGS" # Multi-value arguments
+ ${ARGN}
+ )
+
+ list(LENGTH flags nflags)
+ if(NOT ${nflags})
+ create_object_library(
+ ${target_name}
+ DEPENDS ${EXPAND_FLAGS_DEPENDS}
+ FLAGS ${EXPAND_FLAGS_FLAGS}
+ ${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
+ )
+ return()
+ endif()
+
+ list(POP_FRONT flags flag)
+ extract_flag_modifier(${flag} real_flag modifier)
+
+ if(NOT "${modifier}" STREQUAL "NO")
+ expand_flags_for_object_library(
+ ${target_name}
+ "${flags}"
+ DEPENDS "${EXPAND_FLAGS_DEPENDS}" IGNORE_MARKER
+ FLAGS "${EXPAND_FLAGS_FLAGS}" IGNORE_MARKER
+ "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}"
+ )
+ endif()
+
+ if("${real_flag}" STREQUAL "" OR "${modifier}" STREQUAL "ONLY")
+ return()
+ endif()
+
+ set(NEW_FLAGS ${EXPAND_FLAGS_FLAGS})
+ list(REMOVE_ITEM NEW_FLAGS ${flag})
+ get_fq_dep_list_without_flag(NEW_DEPS ${real_flag} ${EXPAND_FLAGS_DEPENDS})
+
+ # Only target with `flag` has `.__NO_flag` target, `flag__NO` and
+ # `flag__ONLY` do not.
+ if(NOT "${modifier}")
+ set(TARGET_NAME "${target_name}.__NO_${flag}")
+ else()
+ set(TARGET_NAME "${target_name}")
+ endif()
+
+ expand_flags_for_object_library(
+ ${TARGET_NAME}
+ "${flags}"
+ DEPENDS "${NEW_DEPS}" IGNORE_MARKER
+ FLAGS "${NEW_FLAGS}" IGNORE_MARKER
+ "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}"
+ )
+endfunction(expand_flags_for_object_library)
+
+function(add_object_library target_name)
+ cmake_parse_arguments(
+ "ADD_TO_EXPAND"
+ "" # Optional arguments
+ "" # Single value arguments
+ "DEPENDS;FLAGS" # Multi-value arguments
+ ${ARGN}
+ )
+
+ get_fq_target_name(${target_name} fq_target_name)
+
+ if(ADD_TO_EXPAND_DEPENDS AND ("${SHOW_INTERMEDIATE_OBJECTS}" STREQUAL "DEPS"))
+ message(STATUS "Gathering FLAGS from dependencies for ${fq_target_name}")
+ endif()
+
+ get_fq_deps_list(fq_deps_list ${ADD_TO_EXPAND_DEPENDS})
+ get_flags_from_dep_list(deps_flag_list ${fq_deps_list})
+
+ list(APPEND ADD_TO_EXPAND_FLAGS ${deps_flag_list})
+ remove_duplicated_flags("${ADD_TO_EXPAND_FLAGS}" flags)
+ list(SORT flags)
+
+ if(SHOW_INTERMEDIATE_OBJECTS AND flags)
+ message(STATUS "Object library ${fq_target_name} has FLAGS: ${flags}")
+ endif()
+
+ expand_flags_for_object_library(
+ ${fq_target_name}
+ "${flags}"
+ DEPENDS "${fq_deps_list}" IGNORE_MARKER
+ FLAGS "${flags}" IGNORE_MARKER
+ ${ADD_TO_EXPAND_UNPARSED_ARGUMENTS}
)
endfunction(add_object_library)
@@ -92,29 +194,24 @@ set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
# DEPENDS <list of dependencies>
# 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`>
+# FLAGS <optional list of flags>
# )
-function(add_entrypoint_object target_name)
+function(create_entrypoint_object fq_target_name)
cmake_parse_arguments(
"ADD_ENTRYPOINT_OBJ"
"ALIAS;REDIRECTED" # Optional argument
"NAME;CXX_STANDARD" # Single value arguments
- "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
+ "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;FLAGS" # Multi value arguments
${ARGN}
)
- get_fq_target_name(${target_name} fq_target_name)
- set(entrypoint_name ${target_name})
- if(ADD_ENTRYPOINT_OBJ_NAME)
- set(entrypoint_name ${ADD_ENTRYPOINT_OBJ_NAME})
- endif()
-
- list(FIND TARGET_ENTRYPOINT_NAME_LIST ${entrypoint_name} entrypoint_name_index)
+ list(FIND TARGET_ENTRYPOINT_NAME_LIST ${ADD_ENTRYPOINT_OBJ_NAME} entrypoint_name_index)
if(${entrypoint_name_index} EQUAL -1)
add_custom_target(${fq_target_name})
set_target_properties(
${fq_target_name}
PROPERTIES
- "ENTRYPOINT_NAME" ${entrypoint_name}
+ "ENTRYPOINT_NAME" ${ADD_ENTRYPOINT_OBJ_NAME}
"TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
"OBJECT_FILE" ""
"OBJECT_FILE_RAW" ""
@@ -134,6 +231,12 @@ function(add_entrypoint_object target_name)
endif()
list(GET ADD_ENTRYPOINT_OBJ_DEPENDS 0 dep_target)
get_fq_dep_name(fq_dep_name ${dep_target})
+
+ if(SHOW_INTERMEDIATE_OBJECTS)
+ message(STATUS "Adding entrypoint object ${fq_target_name} as an alias of"
+ " ${fq_dep_name}")
+ endif()
+
if(NOT TARGET ${fq_dep_name})
message(WARNING "Aliasee ${fq_dep_name} for entrypoint alias ${target_name} missing; "
"Target ${target_name} will be ignored.")
@@ -152,12 +255,13 @@ function(add_entrypoint_object target_name)
set_target_properties(
${fq_target_name}
PROPERTIES
- "ENTRYPOINT_NAME" ${entrypoint_name}
- "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
- "IS_ALIAS" "YES"
- "OBJECT_FILE" ""
- "OBJECT_FILE_RAW" ""
- "DEPS" "${fq_dep_name}"
+ ENTRYPOINT_NAME ${ADD_ENTRYPOINT_OBJ_NAME}
+ TARGET_TYPE ${ENTRYPOINT_OBJ_TARGET_TYPE}
+ IS_ALIAS "YES"
+ OBJECT_FILE ""
+ OBJECT_FILE_RAW ""
+ DEPS "${fq_dep_name}"
+ FLAGS "${ADD_ENTRYPOINT_OBJ_FLAGS}"
)
return()
endif()
@@ -168,6 +272,9 @@ function(add_entrypoint_object target_name)
if(NOT ADD_ENTRYPOINT_OBJ_HDRS)
message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.")
endif()
+ if(NOT ADD_ENTRYPOINT_OBJ_CXX_STANDARD)
+ set(ADD_ENTRYPOINT_OBJ_CXX_STANDARD ${CMAKE_CXX_STANDARD})
+ endif()
_get_common_compile_options(common_compile_options ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS})
set(internal_target_name ${fq_target_name}.__internal__)
@@ -175,6 +282,15 @@ function(add_entrypoint_object target_name)
get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
set(full_deps_list ${fq_deps_list} libc.src.__support.common)
+ if(SHOW_INTERMEDIATE_OBJECTS)
+ message(STATUS "Adding entrypoint object ${fq_target_name}")
+ if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS")
+ foreach(dep IN LISTS ADD_OBJECT_DEPENDS)
+ message(STATUS " ${fq_target_name} depends on ${dep}")
+ endforeach()
+ endif()
+ endif()
+
add_library(
${internal_target_name}
# TODO: We don't need an object library for internal consumption.
@@ -187,6 +303,12 @@ function(add_entrypoint_object target_name)
target_compile_options(${internal_target_name} BEFORE PRIVATE ${common_compile_options})
target_include_directories(${internal_target_name} PRIVATE ${include_dirs})
add_dependencies(${internal_target_name} ${full_deps_list})
+ set_target_properties(
+ ${internal_target_name}
+ PROPERTIES
+ CXX_STANDARD ${ADD_ENTRYPOINT_OBJ_CXX_STANDARD}
+ FLAGS "${ADD_ENTRYPOINT_OBJ_FLAGS}"
+ )
add_library(
${fq_target_name}
@@ -201,24 +323,18 @@ function(add_entrypoint_object target_name)
target_include_directories(${fq_target_name} PRIVATE ${include_dirs})
add_dependencies(${fq_target_name} ${full_deps_list})
- if(ADD_ENTRYPOINT_OBJ_CXX_STANDARD)
- set_target_properties(
- ${fq_target_name} ${internal_target_name}
- PROPERTIES
- CXX_STANDARD ${ADD_ENTRYPOINT_OBJ_CXX_STANDARD}
- )
- endif()
-
set_target_properties(
${fq_target_name}
PROPERTIES
- "ENTRYPOINT_NAME" ${entrypoint_name}
- "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
- "OBJECT_FILE" $<TARGET_OBJECTS:${fq_target_name}>
+ ENTRYPOINT_NAME ${ADD_ENTRYPOINT_OBJ_NAME}
+ TARGET_TYPE ${ENTRYPOINT_OBJ_TARGET_TYPE}
+ OBJECT_FILE "$<TARGET_OBJECTS:${fq_target_name}>"
# TODO: We don't need to list internal object files if the internal
# target is a normal static library.
- "OBJECT_FILE_RAW" $<TARGET_OBJECTS:${internal_target_name}>
- "DEPS" "${fq_deps_list}"
+ OBJECT_FILE_RAW "$<TARGET_OBJECTS:${internal_target_name}>"
+ CXX_STANDARD ${ADD_ENTRYPOINT_OBJ_CXX_STANDARD}
+ DEPS "${fq_deps_list}"
+ FLAGS "${ADD_ENTRYPOINT_OBJ_FLAGS}"
)
if(LLVM_LIBC_ENABLE_LINTING)
@@ -280,6 +396,105 @@ function(add_entrypoint_object target_name)
)
endif()
+endfunction(create_entrypoint_object)
+
+# Internal function, used by `add_entrypoint_object`.
+function(expand_flags_for_entrypoint_object target_name flags)
+ cmake_parse_arguments(
+ "EXPAND_FLAGS"
+ "IGNORE_MARKER" # Optional arguments
+ "" # Single-value arguments
+ "DEPENDS;FLAGS" # Multi-value arguments
+ ${ARGN}
+ )
+
+ list(LENGTH flags nflags)
+ if(NOT ${nflags})
+ create_entrypoint_object(
+ ${target_name}
+ DEPENDS ${EXPAND_FLAGS_DEPENDS}
+ FLAGS ${EXPAND_FLAGS_FLAGS}
+ ${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
+ )
+ return()
+ endif()
+
+ list(POP_FRONT flags flag)
+ extract_flag_modifier(${flag} real_flag modifier)
+
+ if(NOT "${modifier}" STREQUAL "NO")
+ expand_flags_for_entrypoint_object(
+ ${target_name}
+ "${flags}"
+ DEPENDS "${EXPAND_FLAGS_DEPENDS}" IGNORE_MARKER
+ FLAGS "${EXPAND_FLAGS_FLAGS}" IGNORE_MARKER
+ "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}"
+ )
+ endif()
+
+ if("${real_flag}" STREQUAL "" OR "${modifier}" STREQUAL "ONLY")
+ return()
+ endif()
+
+ set(NEW_FLAGS ${EXPAND_FLAGS_FLAGS})
+ list(REMOVE_ITEM NEW_FLAGS ${flag})
+ get_fq_dep_list_without_flag(NEW_DEPS ${real_flag} ${EXPAND_FLAGS_DEPENDS})
+
+ # Only target with `flag` has `.__NO_flag` target, `flag__NO` and
+ # `flag__ONLY` do not.
+ if(NOT "${modifier}")
+ set(TARGET_NAME "${target_name}.__NO_${flag}")
+ else()
+ set(TARGET_NAME "${target_name}")
+ endif()
+
+ expand_flags_for_entrypoint_object(
+ ${TARGET_NAME}
+ "${flags}"
+ DEPENDS "${NEW_DEPS}" IGNORE_MARKER
+ FLAGS "${NEW_FLAGS}" IGNORE_MARKER
+ "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}"
+ )
+endfunction(expand_flags_for_entrypoint_object)
+
+function(add_entrypoint_object target_name)
+ cmake_parse_arguments(
+ "ADD_TO_EXPAND"
+ "" # Optional arguments
+ "NAME" # Single value arguments
+ "DEPENDS;FLAGS" # Multi-value arguments
+ ${ARGN}
+ )
+
+ get_fq_target_name(${target_name} fq_target_name)
+
+ if(ADD_TO_EXPAND_DEPENDS AND ("${SHOW_INTERMEDIATE_OBJECTS}" STREQUAL "DEPS"))
+ message(STATUS "Gathering FLAGS from dependencies for ${fq_target_name}")
+ endif()
+
+ get_fq_deps_list(fq_deps_list ${ADD_TO_EXPAND_DEPENDS})
+ get_flags_from_dep_list(deps_flag_list ${fq_deps_list})
+
+ list(APPEND ADD_TO_EXPAND_FLAGS ${deps_flag_list})
+ remove_duplicated_flags("${ADD_TO_EXPAND_FLAGS}" flags)
+ list(SORT flags)
+
+ if(SHOW_INTERMEDIATE_OBJECTS AND flags)
+ message(STATUS "Object library ${fq_target_name} has FLAGS: ${flags}")
+ endif()
+
+ if(NOT ADD_TO_EXPAND_NAME)
+ set(ADD_TO_EXPAND_NAME ${target_name})
+ endif()
+
+ expand_flags_for_entrypoint_object(
+ ${fq_target_name}
+ "${flags}"
+ NAME ${ADD_TO_EXPAND_NAME} IGNORE_MARKER
+ DEPENDS "${fq_deps_list}" IGNORE_MARKER
+ FLAGS "${flags}" IGNORE_MARKER
+ ${ADD_TO_EXPAND_UNPARSED_ARGUMENTS}
+ )
endfunction(add_entrypoint_object)
set(ENTRYPOINT_EXT_TARGET_TYPE "ENTRYPOINT_EXT")