[libc-commits] [libc] 8c2e662 - [libc] [NFC] Split the CMake rules into multiple files.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Tue Apr 21 09:27:15 PDT 2020
Author: Siva Chandra Reddy
Date: 2020-04-21T09:24:17-07:00
New Revision: 8c2e66226fb74114fc0e57f239721065d800d33f
URL: https://github.com/llvm/llvm-project/commit/8c2e66226fb74114fc0e57f239721065d800d33f
DIFF: https://github.com/llvm/llvm-project/commit/8c2e66226fb74114fc0e57f239721065d800d33f.diff
LOG: [libc] [NFC] Split the CMake rules into multiple files.
Summary:
The single file was getting too long to be convenient to navigate. This
patch splits it up two into 4 files one each for header rules,
object rules, library rules, and test rules.
Reviewers: abrachet, alexshap
Subscribers: mgorny, tschuett, libc-commits
Tags: #libc-project
Differential Revision: https://reviews.llvm.org/D78536
Added:
libc/cmake/modules/LLVMLibCHeaderRules.cmake
libc/cmake/modules/LLVMLibCLibraryRules.cmake
libc/cmake/modules/LLVMLibCObjectRules.cmake
libc/cmake/modules/LLVMLibCTestRules.cmake
Modified:
libc/cmake/modules/LLVMLibCRules.cmake
Removed:
################################################################################
diff --git a/libc/cmake/modules/LLVMLibCHeaderRules.cmake b/libc/cmake/modules/LLVMLibCHeaderRules.cmake
new file mode 100644
index 000000000000..da61f27b9590
--- /dev/null
+++ b/libc/cmake/modules/LLVMLibCHeaderRules.cmake
@@ -0,0 +1,106 @@
+# A rule for self contained header file targets.
+# This rule merely copies the header file from the current source directory to
+# the current binary directory.
+# Usage:
+# add_header(
+# <target name>
+# HDR <header file>
+# )
+function(add_header target_name)
+ cmake_parse_arguments(
+ "ADD_HEADER"
+ "" # No optional arguments
+ "HDR" # Single value arguments
+ "DEPENDS"
+ ${ARGN}
+ )
+ if(NOT ADD_HEADER_HDR)
+ message(FATAL_ERROR "'add_header' rules requires the HDR argument specifying a headef file.")
+ endif()
+
+ set(dest_file ${CMAKE_CURRENT_BINARY_DIR}/${ADD_HEADER_HDR})
+ set(src_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_HEADER_HDR})
+
+ add_custom_command(
+ OUTPUT ${dest_file}
+ COMMAND cp ${src_file} ${dest_file}
+ DEPENDS ${src_file}
+ )
+
+ get_fq_target_name(${target_name} fq_target_name)
+ add_custom_target(
+ ${fq_target_name}
+ DEPENDS ${dest_file}
+ )
+
+ if(ADD_HEADER_DEPENDS)
+ get_fq_deps_list(fq_deps_list ${ADD_HEADER_DEPENDS})
+ add_dependencies(
+ ${fq_target_name} ${fq_deps_list}
+ )
+ endif()
+endfunction(add_header)
+
+# A rule for generated header file targets.
+# Usage:
+# add_gen_header(
+# <target name>
+# DEF_FILE <.h.def file>
+# GEN_HDR <generated header file name>
+# PARAMS <list of name=value pairs>
+# DATA_FILES <list input data files>
+# )
+function(add_gen_header target_name)
+ cmake_parse_arguments(
+ "ADD_GEN_HDR"
+ "" # No optional arguments
+ "DEF_FILE;GEN_HDR" # Single value arguments
+ "PARAMS;DATA_FILES;DEPENDS" # Multi value arguments
+ ${ARGN}
+ )
+ if(NOT ADD_GEN_HDR_DEF_FILE)
+ message(FATAL_ERROR "`add_gen_hdr` rule requires DEF_FILE to be specified.")
+ endif()
+ if(NOT ADD_GEN_HDR_GEN_HDR)
+ message(FATAL_ERROR "`add_gen_hdr` rule requires GEN_HDR to be specified.")
+ endif()
+
+ set(out_file ${CMAKE_CURRENT_BINARY_DIR}/${ADD_GEN_HDR_GEN_HDR})
+ set(in_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR_DEF_FILE})
+
+ set(fq_data_files "")
+ if(ADD_GEN_HDR_DATA_FILES)
+ foreach(data_file IN LISTS ADD_GEN_HDR_DATA_FILES)
+ list(APPEND fq_data_files "${CMAKE_CURRENT_SOURCE_DIR}/${data_file}")
+ endforeach(data_file)
+ endif()
+
+ set(replacement_params "")
+ if(ADD_GEN_HDR_PARAMS)
+ list(APPEND replacement_params "--args" ${ADD_GEN_HDR_PARAMS})
+ endif()
+
+ set(gen_hdr_script "${LIBC_BUILD_SCRIPTS_DIR}/gen_hdr.py")
+
+ file(GLOB td_includes ${LIBC_SOURCE_DIR}/spec/*.td)
+
+ add_custom_command(
+ OUTPUT ${out_file}
+ COMMAND $<TARGET_FILE:libc-hdrgen> -o ${out_file} --header ${ADD_GEN_HDR_GEN_HDR}
+ --def ${in_file} ${replacement_params} -I ${LIBC_SOURCE_DIR}
+ ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
+
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS ${in_file} ${fq_data_files} ${td_includes}
+ ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td libc-hdrgen
+ )
+
+ get_fq_target_name(${target_name} fq_target_name)
+ if(ADD_GEN_HDR_DEPENDS)
+ get_fq_deps_list(fq_deps_list ${ADD_GEN_HDR_DEPENDS})
+ endif()
+ add_custom_target(
+ ${fq_target_name}
+ DEPENDS ${out_file} ${fq_deps_list}
+ )
+endfunction(add_gen_header)
diff --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
new file mode 100644
index 000000000000..9b30b85cc398
--- /dev/null
+++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
@@ -0,0 +1,126 @@
+# A rule to build a library from a collection of entrypoint objects.
+# Usage:
+# add_entrypoint_library(
+# DEPENDS <list of add_entrypoint_object targets>
+# )
+function(add_entrypoint_library target_name)
+ cmake_parse_arguments(
+ "ENTRYPOINT_LIBRARY"
+ "" # No optional arguments
+ "" # No single value arguments
+ "DEPENDS" # Multi-value arguments
+ ${ARGN}
+ )
+ if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
+ message(FATAL_ERROR "'add_entrypoint_library' target requires a DEPENDS list "
+ "of 'add_entrypoint_object' targets.")
+ endif()
+
+ set(obj_list "")
+ foreach(dep IN LISTS ENTRYPOINT_LIBRARY_DEPENDS)
+ get_target_property(dep_type ${dep} "TARGET_TYPE")
+ 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_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(
+ OUTPUT ${library_file}
+ COMMAND ${CMAKE_AR} -r ${library_file} ${obj_list}
+ DEPENDS ${obj_list}
+ )
+ add_custom_target(
+ ${target_name}
+ ALL
+ DEPENDS ${library_file}
+ )
+endfunction(add_entrypoint_library)
+
+# Rule to build a shared library of redirector objects.
+function(add_redirector_library target_name)
+ cmake_parse_arguments(
+ "REDIRECTOR_LIBRARY"
+ ""
+ ""
+ "DEPENDS"
+ ${ARGN}
+ )
+
+ set(obj_files "")
+ foreach(dep IN LISTS REDIRECTOR_LIBRARY_DEPENDS)
+ # TODO: Ensure that each dep is actually a add_redirector_object target.
+ list(APPEND obj_files $<TARGET_OBJECTS:${dep}>)
+ endforeach(dep)
+
+ # TODO: Call the linker explicitly instead of calling the compiler driver to
+ # prevent DT_NEEDED on C++ runtime.
+ add_library(
+ ${target_name}
+ SHARED
+ ${obj_files}
+ )
+ set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+ target_link_libraries(
+ ${target_name}
+ -nostdlib -lc -lm
+ )
+
+ set_target_properties(
+ ${target_name}
+ PROPERTIES
+ LINKER_LANGUAGE "C"
+ )
+endfunction(add_redirector_library)
+
+# Rule to add header only libraries.
+# Usage
+# add_header_library(
+# <target name>
+# HDRS <list of .h files part of the library>
+# DEPENDS <list of dependencies>
+# )
+function(add_header_library target_name)
+ cmake_parse_arguments(
+ "ADD_HEADER"
+ "" # No optional arguments
+ "" # No Single value arguments
+ "HDRS;DEPENDS" # Multi-value arguments
+ ${ARGN}
+ )
+
+ if(NOT ADD_HEADER_HDRS)
+ message(FATAL_ERROR "'add_header_library' target requires a HDRS list of .h files.")
+ endif()
+
+ get_fq_target_name(${target_name} fq_target_name)
+
+ set(FULL_HDR_PATHS "")
+ # TODO: Remove this foreach block when we can switch to the new
+ # version of the CMake policy CMP0076.
+ foreach(hdr IN LISTS ADD_HEADER_HDRS)
+ list(APPEND FULL_HDR_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/${hdr})
+ endforeach()
+
+ set(interface_target_name "${fq_target_name}_header_library__")
+
+ add_library(${interface_target_name} INTERFACE)
+ target_sources(${interface_target_name} INTERFACE ${FULL_HDR_PATHS})
+ if(ADD_HEADER_DEPENDS)
+ get_fq_deps_list(fq_deps_list ${ADD_HEADER_DEPENDS})
+ add_dependencies(${interface_target_name} ${fq_deps_list})
+ endif()
+
+ add_custom_target(${fq_target_name})
+ add_dependencies(${fq_target_name} ${interface_target_name})
+ set_target_properties(
+ ${fq_target_name}
+ PROPERTIES
+ "TARGET_TYPE" "HDR_LIBRARY"
+ )
+endfunction(add_header_library)
diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake
new file mode 100644
index 000000000000..9879531e056d
--- /dev/null
+++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake
@@ -0,0 +1,313 @@
+set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY")
+
+# Rule which is essentially a wrapper over add_library to compile a set of
+# sources to object files.
+# Usage:
+# add_object_library(
+# <target_name>
+# 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_library target_name)
+ cmake_parse_arguments(
+ "ADD_OBJECT"
+ "" # No option arguments
+ "" # Single value arguments
+ "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
+ ${ARGN}
+ )
+
+ if(NOT ADD_OBJECT_SRCS)
+ 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}
+ OBJECT
+ ${ADD_OBJECT_SRCS}
+ ${ADD_OBJECT_HDRS}
+ )
+ target_include_directories(
+ ${fq_target_name}
+ PRIVATE
+ ${LIBC_BUILD_DIR}/include
+ ${LIBC_SOURCE_DIR}
+ ${LIBC_BUILD_DIR}
+ )
+ if(ADD_OBJECT_COMPILE_OPTIONS)
+ target_compile_options(
+ ${fq_target_name}
+ PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS}
+ )
+ endif()
+
+ set(all_object_files $<TARGET_OBJECTS:${fq_target_name}>)
+ if(ADD_OBJECT_DEPENDS)
+ get_fq_deps_list(fq_deps_list ${ADD_OBJECT_DEPENDS})
+ add_dependencies(
+ ${fq_target_name}
+ ${fq_deps_list}
+ )
+ foreach(obj_target IN LISTS fq_deps_list)
+ if(NOT TARGET obj_target)
+ # Not all targets will be visible. So, we will ignore those which aren't
+ # visible yet.
+ continue()
+ endif()
+ 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(
+ ${fq_target_name}
+ PROPERTIES
+ "TARGET_TYPE" ${OBJECT_LIBRARY_TARGET_TYPE}
+ "OBJECT_FILES" "${all_object_files}"
+ )
+endfunction(add_object_library)
+
+set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
+
+# A rule for entrypoint object targets.
+# Usage:
+# add_entrypoint_object(
+# <target_name>
+# [ALIAS|REDIRECTED] # Specified if the entrypoint is redirected or an alias.
+# [NAME] <the C name of the entrypoint if
diff erent from target_name>
+# SRCS <list of .cpp files>
+# HDRS <list of .h files>
+# 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`>
+# )
+function(add_entrypoint_object target_name)
+ cmake_parse_arguments(
+ "ADD_ENTRYPOINT_OBJ"
+ "ALIAS;REDIRECTED" # Optional argument
+ "NAME" # Single value arguments
+ "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
+ ${ARGN}
+ )
+
+ get_fq_target_name(${target_name} fq_target_name)
+
+ if(ADD_ENTRYPOINT_OBJ_ALIAS)
+ # Alias targets help one add aliases to other entrypoint object targets.
+ # One can use alias targets setup OS/machine independent entrypoint targets.
+ list(LENGTH ADD_ENTRYPOINT_OBJ_DEPENDS deps_size)
+ if(NOT (${deps_size} EQUAL "1"))
+ message(FATAL_ERROR "An entrypoint alias should have exactly one dependency.")
+ endif()
+ list(GET ADD_ENTRYPOINT_OBJ_DEPENDS 0 dep_target)
+ get_fq_dep_name(fq_dep_name ${dep_target})
+ if(NOT TARGET ${fq_dep_name})
+ message(WARNING "Aliasee ${fq_dep_name} for entrypoint alias ${target_name} missing; "
+ "Target ${target_name} will be ignored.")
+ return()
+ endif()
+
+ get_target_property(obj_type ${fq_dep_name} "TARGET_TYPE")
+ if((NOT obj_type) OR (NOT (${obj_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})))
+ message(FATAL_ERROR "The aliasee of an entrypoint alias should be an entrypoint.")
+ endif()
+
+ add_custom_target(${fq_target_name})
+ add_dependencies(${fq_target_name} ${fq_dep_name})
+ get_target_property(all_objects ${fq_dep_name} "OBJECT_FILES")
+ get_target_property(all_objects_raw ${fq_dep_name} "OBJECT_FILES_RAW")
+ set_target_properties(
+ ${fq_target_name}
+ PROPERTIES
+ "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
+ "OBJECT_FILES" "${all_objects}"
+ "OBJECT_FILES_RAW" "${all_objects_raw}"
+ )
+ return()
+ endif()
+
+ if(NOT ADD_ENTRYPOINT_OBJ_SRCS)
+ message(FATAL_ERROR "`add_entrypoint_object` rule requires SRCS to be specified.")
+ endif()
+ if(NOT ADD_ENTRYPOINT_OBJ_HDRS)
+ message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.")
+ endif()
+
+ set(entrypoint_name ${target_name})
+ if(ADD_ENTRYPOINT_OBJ_NAME)
+ set(entrypoint_name ${ADD_ENTRYPOINT_OBJ_NAME})
+ endif()
+
+ set(objects_target_name "${fq_target_name}_objects")
+
+ add_library(
+ ${objects_target_name}
+ # We want an object library as the objects will eventually get packaged into
+ # an archive (like libc.a).
+ OBJECT
+ ${ADD_ENTRYPOINT_OBJ_SRCS}
+ ${ADD_ENTRYPOINT_OBJ_HDRS}
+ )
+ target_compile_options(
+ ${objects_target_name}
+ BEFORE
+ PRIVATE
+ -fpie ${LLVM_CXX_STD_default}
+ )
+ target_include_directories(
+ ${objects_target_name}
+ PRIVATE
+ ${LIBC_BUILD_DIR}/include
+ ${LIBC_SOURCE_DIR}
+ ${LIBC_BUILD_DIR}
+ )
+ add_dependencies(
+ ${objects_target_name}
+ libc.src.__support.common
+ )
+ set(dep_objects "")
+ if(ADD_ENTRYPOINT_OBJ_DEPENDS)
+ get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
+ add_dependencies(
+ ${objects_target_name}
+ ${fq_deps_list}
+ )
+ foreach(dep_target IN LISTS fq_deps_list)
+ 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(
+ ${objects_target_name}
+ PRIVATE ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS}
+ )
+ endif()
+
+ 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 $<TARGET_OBJECTS:${objects_target_name}>)
+ add_custom_command(
+ OUTPUT ${object_file_raw}
+ DEPENDS ${input_objects}
+ COMMAND ${CMAKE_LINKER} -r ${input_objects} -o ${object_file_raw}
+ )
+
+ set(alias_attributes "0,function,global")
+ if(ADD_ENTRYPOINT_OBJ_REDIRECTED)
+ set(alias_attributes "${alias_attributes},hidden")
+ endif()
+
+ add_custom_command(
+ OUTPUT ${object_file}
+ # We llvm-objcopy here as GNU-binutils objcopy does not support the 'hidden' flag.
+ DEPENDS ${object_file_raw} ${llvm-objcopy}
+ COMMAND $<TARGET_FILE:llvm-objcopy> --add-symbol
+ "${entrypoint_name}=.llvm.libc.entrypoint.${entrypoint_name}:${alias_attributes}"
+ ${object_file_raw} ${object_file}
+ )
+
+ add_custom_target(
+ ${fq_target_name}
+ 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(
+ ${fq_target_name}
+ PROPERTIES
+ "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
+ "OBJECT_FILES" "${all_objects}"
+ "OBJECT_FILES_RAW" "${all_objects_raw}"
+ )
+
+ if(LLVM_LIBC_ENABLE_LINTING)
+ set(lint_timestamp "${CMAKE_CURRENT_BINARY_DIR}/.${target_name}.__lint_timestamp__")
+
+ add_custom_command(
+ OUTPUT ${lint_timestamp}
+ # --quiet is used to surpress warning statistics from clang-tidy like:
+ # Suppressed X warnings (X in non-user code).
+ # There seems to be a bug in clang-tidy where by even with --quiet some
+ # messages from clang's own diagnostics engine leak through:
+ # X warnings generated.
+ # Until this is fixed upstream, we use -fno-caret-diagnostics to surpress
+ # these.
+ COMMAND $<TARGET_FILE:clang-tidy> "--extra-arg=-fno-caret-diagnostics" --quiet
+ # Path to directory containing compile_commands.json
+ -p ${PROJECT_BINARY_DIR}
+ ${ADD_ENTRYPOINT_OBJ_SRCS}
+ # We have two options for running commands, add_custom_command and
+ # add_custom_target. We don't want to run the linter unless source files
+ # have changed. add_custom_target explicitly runs everytime therefore we
+ # use add_custom_command. This function requires an output file and since
+ # linting doesn't produce a file, we create a dummy file using a
+ # crossplatform touch.
+ COMMAND "${CMAKE_COMMAND}" -E touch ${lint_timestamp}
+ COMMENT "Linting... ${target_name}"
+ DEPENDS ${clang-tidy} ${objects_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+ add_custom_target(${fq_target_name}.__lint__
+ DEPENDS ${lint_timestamp})
+ add_dependencies(lint-libc ${fq_target_name}.__lint__)
+ add_dependencies(${fq_target_name} ${fq_target_name}.__lint__)
+ endif()
+
+endfunction(add_entrypoint_object)
+
+# Rule build a redirector object file.
+function(add_redirector_object target_name)
+ cmake_parse_arguments(
+ "REDIRECTOR_OBJECT"
+ "" # No optional arguments
+ "SRC" # The cpp file in which the redirector is defined.
+ "" # No multivalue arguments
+ ${ARGN}
+ )
+ if(NOT REDIRECTOR_OBJECT_SRC)
+ message(FATAL_ERROR "'add_redirector_object' rule requires SRC option listing one source file.")
+ endif()
+
+ add_library(
+ ${target_name}
+ OBJECT
+ ${REDIRECTOR_OBJECT_SRC}
+ )
+ target_compile_options(
+ ${target_name}
+ BEFORE PRIVATE -fPIC
+ )
+endfunction(add_redirector_object)
+
diff --git a/libc/cmake/modules/LLVMLibCRules.cmake b/libc/cmake/modules/LLVMLibCRules.cmake
index f2cabee3210d..f76d6e522b4a 100644
--- a/libc/cmake/modules/LLVMLibCRules.cmake
+++ b/libc/cmake/modules/LLVMLibCRules.cmake
@@ -1,704 +1,5 @@
include(LLVMLibCTargetNameUtils)
-
-# A rule for self contained header file targets.
-# This rule merely copies the header file from the current source directory to
-# the current binary directory.
-# Usage:
-# add_header(
-# <target name>
-# HDR <header file>
-# )
-function(add_header target_name)
- cmake_parse_arguments(
- "ADD_HEADER"
- "" # No optional arguments
- "HDR" # Single value arguments
- "DEPENDS"
- ${ARGN}
- )
- if(NOT ADD_HEADER_HDR)
- message(FATAL_ERROR "'add_header' rules requires the HDR argument specifying a headef file.")
- endif()
-
- set(dest_file ${CMAKE_CURRENT_BINARY_DIR}/${ADD_HEADER_HDR})
- set(src_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_HEADER_HDR})
-
- add_custom_command(
- OUTPUT ${dest_file}
- COMMAND cp ${src_file} ${dest_file}
- DEPENDS ${src_file}
- )
-
- get_fq_target_name(${target_name} fq_target_name)
- add_custom_target(
- ${fq_target_name}
- DEPENDS ${dest_file}
- )
-
- if(ADD_HEADER_DEPENDS)
- get_fq_deps_list(fq_deps_list ${ADD_HEADER_DEPENDS})
- add_dependencies(
- ${fq_target_name} ${fq_deps_list}
- )
- endif()
-endfunction(add_header)
-
-# A rule for generated header file targets.
-# Usage:
-# add_gen_header(
-# <target name>
-# DEF_FILE <.h.def file>
-# GEN_HDR <generated header file name>
-# PARAMS <list of name=value pairs>
-# DATA_FILES <list input data files>
-# )
-function(add_gen_header target_name)
- cmake_parse_arguments(
- "ADD_GEN_HDR"
- "" # No optional arguments
- "DEF_FILE;GEN_HDR" # Single value arguments
- "PARAMS;DATA_FILES;DEPENDS" # Multi value arguments
- ${ARGN}
- )
- if(NOT ADD_GEN_HDR_DEF_FILE)
- message(FATAL_ERROR "`add_gen_hdr` rule requires DEF_FILE to be specified.")
- endif()
- if(NOT ADD_GEN_HDR_GEN_HDR)
- message(FATAL_ERROR "`add_gen_hdr` rule requires GEN_HDR to be specified.")
- endif()
-
- set(out_file ${CMAKE_CURRENT_BINARY_DIR}/${ADD_GEN_HDR_GEN_HDR})
- set(in_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR_DEF_FILE})
-
- set(fq_data_files "")
- if(ADD_GEN_HDR_DATA_FILES)
- foreach(data_file IN LISTS ADD_GEN_HDR_DATA_FILES)
- list(APPEND fq_data_files "${CMAKE_CURRENT_SOURCE_DIR}/${data_file}")
- endforeach(data_file)
- endif()
-
- set(replacement_params "")
- if(ADD_GEN_HDR_PARAMS)
- list(APPEND replacement_params "--args" ${ADD_GEN_HDR_PARAMS})
- endif()
-
- set(gen_hdr_script "${LIBC_BUILD_SCRIPTS_DIR}/gen_hdr.py")
-
- file(GLOB td_includes ${LIBC_SOURCE_DIR}/spec/*.td)
-
- add_custom_command(
- OUTPUT ${out_file}
- COMMAND $<TARGET_FILE:libc-hdrgen> -o ${out_file} --header ${ADD_GEN_HDR_GEN_HDR}
- --def ${in_file} ${replacement_params} -I ${LIBC_SOURCE_DIR}
- ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
-
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- DEPENDS ${in_file} ${fq_data_files} ${td_includes}
- ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td libc-hdrgen
- )
-
- get_fq_target_name(${target_name} fq_target_name)
- if(ADD_GEN_HDR_DEPENDS)
- get_fq_deps_list(fq_deps_list ${ADD_GEN_HDR_DEPENDS})
- endif()
- add_custom_target(
- ${fq_target_name}
- DEPENDS ${out_file} ${fq_deps_list}
- )
-endfunction(add_gen_header)
-
-set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY")
-
-# Rule which is essentially a wrapper over add_library to compile a set of
-# sources to object files.
-# Usage:
-# add_object_library(
-# <target_name>
-# 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_library target_name)
- cmake_parse_arguments(
- "ADD_OBJECT"
- "" # No option arguments
- "" # Single value arguments
- "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
- ${ARGN}
- )
-
- if(NOT ADD_OBJECT_SRCS)
- 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}
- OBJECT
- ${ADD_OBJECT_SRCS}
- ${ADD_OBJECT_HDRS}
- )
- target_include_directories(
- ${fq_target_name}
- PRIVATE
- "${LIBC_BUILD_DIR}/include;${LIBC_SOURCE_DIR};${LIBC_BUILD_DIR}"
- )
- if(ADD_OBJECT_COMPILE_OPTIONS)
- target_compile_options(
- ${fq_target_name}
- PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS}
- )
- endif()
-
- set(all_object_files $<TARGET_OBJECTS:${fq_target_name}>)
- if(ADD_OBJECT_DEPENDS)
- get_fq_deps_list(fq_deps_list ${ADD_OBJECT_DEPENDS})
- add_dependencies(
- ${fq_target_name}
- ${fq_deps_list}
- )
- foreach(obj_target IN LISTS fq_deps_list)
- if(NOT TARGET obj_target)
- # Not all targets will be visible. So, we will ignore those which aren't
- # visible yet.
- continue()
- endif()
- 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(
- ${fq_target_name}
- PROPERTIES
- "TARGET_TYPE" ${OBJECT_LIBRARY_TARGET_TYPE}
- "OBJECT_FILES" "${all_object_files}"
- )
-endfunction(add_object_library)
-
-set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
-
-# A rule for entrypoint object targets.
-# Usage:
-# add_entrypoint_object(
-# <target_name>
-# [ALIAS|REDIRECTED] # Specified if the entrypoint is redirected or an alias.
-# [NAME] <the C name of the entrypoint if
diff erent from target_name>
-# SRCS <list of .cpp files>
-# HDRS <list of .h files>
-# 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`>
-# )
-function(add_entrypoint_object target_name)
- cmake_parse_arguments(
- "ADD_ENTRYPOINT_OBJ"
- "ALIAS;REDIRECTED" # Optional argument
- "NAME" # Single value arguments
- "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
- ${ARGN}
- )
-
- get_fq_target_name(${target_name} fq_target_name)
-
- if(ADD_ENTRYPOINT_OBJ_ALIAS)
- # Alias targets help one add aliases to other entrypoint object targets.
- # One can use alias targets setup OS/machine independent entrypoint targets.
- list(LENGTH ADD_ENTRYPOINT_OBJ_DEPENDS deps_size)
- if(NOT (${deps_size} EQUAL "1"))
- message(FATAL_ERROR "An entrypoint alias should have exactly one dependency.")
- endif()
- list(GET ADD_ENTRYPOINT_OBJ_DEPENDS 0 dep_target)
- get_fq_dep_name(fq_dep_name ${dep_target})
- if(NOT TARGET ${fq_dep_name})
- message(WARNING "Aliasee ${fq_dep_name} for entrypoint alias ${target_name} missing; "
- "Target ${target_name} will be ignored.")
- return()
- endif()
-
- get_target_property(obj_type ${fq_dep_name} "TARGET_TYPE")
- if((NOT obj_type) OR (NOT (${obj_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})))
- message(FATAL_ERROR "The aliasee of an entrypoint alias should be an entrypoint.")
- endif()
-
- add_custom_target(${fq_target_name})
- add_dependencies(${fq_target_name} ${fq_dep_name})
- get_target_property(all_objects ${fq_dep_name} "OBJECT_FILES")
- get_target_property(all_objects_raw ${fq_dep_name} "OBJECT_FILES_RAW")
- set_target_properties(
- ${fq_target_name}
- PROPERTIES
- "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
- "OBJECT_FILES" "${all_objects}"
- "OBJECT_FILES_RAW" "${all_objects_raw}"
- )
- return()
- endif()
-
- if(NOT ADD_ENTRYPOINT_OBJ_SRCS)
- message(FATAL_ERROR "`add_entrypoint_object` rule requires SRCS to be specified.")
- endif()
- if(NOT ADD_ENTRYPOINT_OBJ_HDRS)
- message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.")
- endif()
-
- set(entrypoint_name ${target_name})
- if(ADD_ENTRYPOINT_OBJ_NAME)
- set(entrypoint_name ${ADD_ENTRYPOINT_OBJ_NAME})
- endif()
-
- set(objects_target_name "${fq_target_name}_objects")
-
- add_library(
- ${objects_target_name}
- # We want an object library as the objects will eventually get packaged into
- # an archive (like libc.a).
- OBJECT
- ${ADD_ENTRYPOINT_OBJ_SRCS}
- ${ADD_ENTRYPOINT_OBJ_HDRS}
- )
- target_compile_options(
- ${objects_target_name}
- BEFORE
- PRIVATE
- -fpie ${LLVM_CXX_STD_default}
- )
- target_include_directories(
- ${objects_target_name}
- PRIVATE
- "${LIBC_BUILD_DIR}/include;${LIBC_SOURCE_DIR};${LIBC_BUILD_DIR}"
- )
- add_dependencies(
- ${objects_target_name}
- libc.src.__support.common
- )
- set(dep_objects "")
- if(ADD_ENTRYPOINT_OBJ_DEPENDS)
- get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
- add_dependencies(
- ${objects_target_name}
- ${fq_deps_list}
- )
- foreach(dep_target IN LISTS fq_deps_list)
- 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(
- ${objects_target_name}
- PRIVATE ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS}
- )
- endif()
-
- 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 $<TARGET_OBJECTS:${objects_target_name}>)
- add_custom_command(
- OUTPUT ${object_file_raw}
- DEPENDS ${input_objects}
- COMMAND ${CMAKE_LINKER} -r ${input_objects} -o ${object_file_raw}
- )
-
- set(alias_attributes "0,function,global")
- if(ADD_ENTRYPOINT_OBJ_REDIRECTED)
- set(alias_attributes "${alias_attributes},hidden")
- endif()
-
- add_custom_command(
- OUTPUT ${object_file}
- # We llvm-objcopy here as GNU-binutils objcopy does not support the 'hidden' flag.
- DEPENDS ${object_file_raw} ${llvm-objcopy}
- COMMAND $<TARGET_FILE:llvm-objcopy> --add-symbol "${entrypoint_name}=.llvm.libc.entrypoint.${entrypoint_name}:${alias_attributes}" ${object_file_raw} ${object_file}
- )
-
- add_custom_target(
- ${fq_target_name}
- 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(
- ${fq_target_name}
- PROPERTIES
- "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
- "OBJECT_FILES" "${all_objects}"
- "OBJECT_FILES_RAW" "${all_objects_raw}"
- )
-
- if(LLVM_LIBC_ENABLE_LINTING)
- set(lint_timestamp "${CMAKE_CURRENT_BINARY_DIR}/.${target_name}.__lint_timestamp__")
-
- add_custom_command(
- OUTPUT ${lint_timestamp}
- # --quiet is used to surpress warning statistics from clang-tidy like:
- # Suppressed X warnings (X in non-user code).
- # There seems to be a bug in clang-tidy where by even with --quiet some
- # messages from clang's own diagnostics engine leak through:
- # X warnings generated.
- # Until this is fixed upstream, we use -fno-caret-diagnostics to surpress
- # these.
- COMMAND $<TARGET_FILE:clang-tidy> "--extra-arg=-fno-caret-diagnostics" --quiet
- # Path to directory containing compile_commands.json
- -p ${PROJECT_BINARY_DIR}
- ${ADD_ENTRYPOINT_OBJ_SRCS}
- # We have two options for running commands, add_custom_command and
- # add_custom_target. We don't want to run the linter unless source files
- # have changed. add_custom_target explicitly runs everytime therefore we
- # use add_custom_command. This function requires an output file and since
- # linting doesn't produce a file, we create a dummy file using a
- # crossplatform touch.
- COMMAND "${CMAKE_COMMAND}" -E touch ${lint_timestamp}
- COMMENT "Linting... ${target_name}"
- DEPENDS ${clang-tidy} ${objects_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- )
-
- add_custom_target(${fq_target_name}.__lint__
- DEPENDS ${lint_timestamp})
- add_dependencies(lint-libc ${fq_target_name}.__lint__)
- add_dependencies(${fq_target_name} ${fq_target_name}.__lint__)
- endif()
-
-endfunction(add_entrypoint_object)
-
-# A rule to build a library from a collection of entrypoint objects.
-# Usage:
-# add_entrypoint_library(
-# DEPENDS <list of add_entrypoint_object targets>
-# )
-function(add_entrypoint_library target_name)
- cmake_parse_arguments(
- "ENTRYPOINT_LIBRARY"
- "" # No optional arguments
- "" # No single value arguments
- "DEPENDS" # Multi-value arguments
- ${ARGN}
- )
- if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
- message(FATAL_ERROR "'add_entrypoint_library' target requires a DEPENDS list of 'add_entrypoint_object' targets.")
- endif()
-
- set(obj_list "")
- foreach(dep IN LISTS ENTRYPOINT_LIBRARY_DEPENDS)
- get_target_property(dep_type ${dep} "TARGET_TYPE")
- 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_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(
- OUTPUT ${library_file}
- COMMAND ${CMAKE_AR} -r ${library_file} ${obj_list}
- DEPENDS ${obj_list}
- )
- add_custom_target(
- ${target_name}
- ALL
- DEPENDS ${library_file}
- )
-endfunction(add_entrypoint_library)
-
-# Rule build a redirector object file.
-function(add_redirector_object target_name)
- cmake_parse_arguments(
- "REDIRECTOR_OBJECT"
- "" # No optional arguments
- "SRC" # The cpp file in which the redirector is defined.
- "" # No multivalue arguments
- ${ARGN}
- )
- if(NOT REDIRECTOR_OBJECT_SRC)
- message(FATAL_ERROR "'add_redirector_object' rule requires SRC option listing one source file.")
- endif()
-
- add_library(
- ${target_name}
- OBJECT
- ${REDIRECTOR_OBJECT_SRC}
- )
- target_compile_options(
- ${target_name}
- BEFORE PRIVATE -fPIC
- )
-endfunction(add_redirector_object)
-
-# Rule to build a shared library of redirector objects.
-function(add_redirector_library target_name)
- cmake_parse_arguments(
- "REDIRECTOR_LIBRARY"
- ""
- ""
- "DEPENDS"
- ${ARGN}
- )
-
- set(obj_files "")
- foreach(dep IN LISTS REDIRECTOR_LIBRARY_DEPENDS)
- # TODO: Ensure that each dep is actually a add_redirector_object target.
- list(APPEND obj_files $<TARGET_OBJECTS:${dep}>)
- endforeach(dep)
-
- # TODO: Call the linker explicitly instead of calling the compiler driver to
- # prevent DT_NEEDED on C++ runtime.
- add_library(
- ${target_name}
- SHARED
- ${obj_files}
- )
- set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
- target_link_libraries(
- ${target_name}
- -nostdlib -lc -lm
- )
-
- set_target_properties(
- ${target_name}
- PROPERTIES
- LINKER_LANGUAGE "C"
- )
-endfunction(add_redirector_library)
-
-# Rule to add a libc unittest.
-# Usage
-# add_libc_unittest(
-# <target name>
-# SUITE <name of the suite this test belongs to>
-# SRCS <list of .cpp files for the test>
-# HDRS <list of .h files for the test>
-# DEPENDS <list of dependencies>
-# COMPILE_OPTIONS <list of special compile options for this target>
-# )
-function(add_libc_unittest target_name)
- if(NOT LLVM_INCLUDE_TESTS)
- return()
- endif()
-
- cmake_parse_arguments(
- "LIBC_UNITTEST"
- "" # No optional arguments
- "SUITE" # Single value arguments
- "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi-value arguments
- ${ARGN}
- )
- if(NOT LIBC_UNITTEST_SRCS)
- message(FATAL_ERROR "'add_libc_unittest' target requires a SRCS list of .cpp files.")
- endif()
- if(NOT LIBC_UNITTEST_DEPENDS)
- message(FATAL_ERROR "'add_libc_unittest' target requires a DEPENDS list of 'add_entrypoint_object' targets.")
- endif()
-
- set(library_deps "")
- get_fq_deps_list(fq_deps_list ${LIBC_UNITTEST_DEPENDS})
- foreach(dep IN LISTS fq_deps_list)
- get_target_property(dep_type ${dep} "TARGET_TYPE")
- 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)
-
- get_fq_target_name(${target_name} fq_target_name)
- add_executable(
- ${fq_target_name}
- EXCLUDE_FROM_ALL
- ${LIBC_UNITTEST_SRCS}
- ${LIBC_UNITTEST_HDRS}
- )
- target_include_directories(
- ${fq_target_name}
- PRIVATE
- ${LIBC_SOURCE_DIR}
- ${LIBC_BUILD_DIR}
- ${LIBC_BUILD_DIR}/include
- )
- if(LIBC_UNITTEST_COMPILE_OPTIONS)
- target_compile_options(
- ${target_name}
- PRIVATE ${LIBC_UNITTEST_COMPILE_OPTIONS}
- )
- endif()
-
- if(library_deps)
- target_link_libraries(${fq_target_name} PRIVATE ${library_deps})
- endif()
-
- set_target_properties(${fq_target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
- add_dependencies(
- ${fq_target_name}
- ${fq_deps_list}
- )
-
- target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest libc_test_utils)
-
- add_custom_command(
- TARGET ${fq_target_name}
- POST_BUILD
- COMMAND $<TARGET_FILE:${fq_target_name}>
- )
- if(LIBC_UNITTEST_SUITE)
- add_dependencies(
- ${LIBC_UNITTEST_SUITE}
- ${fq_target_name}
- )
- endif()
-endfunction(add_libc_unittest)
-
-function(add_libc_testsuite suite_name)
- add_custom_target(${suite_name})
- add_dependencies(check-libc ${suite_name})
-endfunction(add_libc_testsuite)
-
-# Rule to add a fuzzer test.
-# Usage
-# add_libc_fuzzer(
-# <target name>
-# SRCS <list of .cpp files for the test>
-# HDRS <list of .h files for the test>
-# DEPENDS <list of dependencies>
-# )
-function(add_libc_fuzzer target_name)
- cmake_parse_arguments(
- "LIBC_FUZZER"
- "" # No optional arguments
- "" # Single value arguments
- "SRCS;HDRS;DEPENDS" # Multi-value arguments
- ${ARGN}
- )
- if(NOT LIBC_FUZZER_SRCS)
- message(FATAL_ERROR "'add_libc_fuzzer' target requires a SRCS list of .cpp files.")
- endif()
- if(NOT LIBC_FUZZER_DEPENDS)
- message(FATAL_ERROR "'add_libc_fuzzer' target requires a DEPENDS list of 'add_entrypoint_object' targets.")
- endif()
-
- get_fq_deps_list(fq_deps_list ${LIBC_FUZZER_DEPENDS})
- set(library_deps "")
- foreach(dep IN LISTS fq_deps_list)
- 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_FILES_RAW")
- list(APPEND library_deps ${obj_file})
- continue()
- endif()
- 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)
-
- get_fq_target_name(${target_name} fq_target_name)
- add_executable(
- ${fq_target_name}
- EXCLUDE_FROM_ALL
- ${LIBC_FUZZER_SRCS}
- ${LIBC_FUZZER_HDRS}
- )
- target_include_directories(
- ${fq_target_name}
- PRIVATE
- ${LIBC_SOURCE_DIR}
- ${LIBC_BUILD_DIR}
- ${LIBC_BUILD_DIR}/include
- )
-
- if(library_deps)
- target_link_libraries(${fq_target_name} PRIVATE ${library_deps})
- endif()
-
- set_target_properties(${fq_target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
- add_dependencies(
- ${fq_target_name}
- ${fq_deps_list}
- )
- add_dependencies(libc-fuzzer ${fq_target_name})
-endfunction(add_libc_fuzzer)
-
-# Rule to add header only libraries.
-# Usage
-# add_header_library(
-# <target name>
-# HDRS <list of .h files part of the library>
-# DEPENDS <list of dependencies>
-# )
-function(add_header_library target_name)
- cmake_parse_arguments(
- "ADD_HEADER"
- "" # No optional arguments
- "" # No Single value arguments
- "HDRS;DEPENDS" # Multi-value arguments
- ${ARGN}
- )
-
- if(NOT ADD_HEADER_HDRS)
- message(FATAL_ERROR "'add_header_library' target requires a HDRS list of .h files.")
- endif()
-
- get_fq_target_name(${target_name} fq_target_name)
-
- set(FULL_HDR_PATHS "")
- # TODO: Remove this foreach block when we can switch to the new
- # version of the CMake policy CMP0076.
- foreach(hdr IN LISTS ADD_HEADER_HDRS)
- list(APPEND FULL_HDR_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/${hdr})
- endforeach()
-
- set(interface_target_name "${fq_target_name}_header_library__")
-
- add_library(${interface_target_name} INTERFACE)
- target_sources(${interface_target_name} INTERFACE ${FULL_HDR_PATHS})
- if(ADD_HEADER_DEPENDS)
- get_fq_deps_list(fq_deps_list ${ADD_HEADER_DEPENDS})
- add_dependencies(${interface_target_name} ${fq_deps_list})
- endif()
-
- add_custom_target(${fq_target_name})
- add_dependencies(${fq_target_name} ${interface_target_name})
- set_target_properties(
- ${fq_target_name}
- PROPERTIES
- "TARGET_TYPE" "HDR_LIBRARY"
- )
-endfunction(add_header_library)
+include(LLVMLibCHeaderRules)
+include(LLVMLibCObjectRules)
+include(LLVMLibCLibraryRules)
+include(LLVMLibCTestRules)
diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
new file mode 100644
index 000000000000..3f6aeceed2af
--- /dev/null
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -0,0 +1,169 @@
+# Rule to add a libc unittest.
+# Usage
+# add_libc_unittest(
+# <target name>
+# SUITE <name of the suite this test belongs to>
+# SRCS <list of .cpp files for the test>
+# HDRS <list of .h files for the test>
+# DEPENDS <list of dependencies>
+# COMPILE_OPTIONS <list of special compile options for this target>
+# )
+function(add_libc_unittest target_name)
+ if(NOT LLVM_INCLUDE_TESTS)
+ return()
+ endif()
+
+ cmake_parse_arguments(
+ "LIBC_UNITTEST"
+ "" # No optional arguments
+ "SUITE" # Single value arguments
+ "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi-value arguments
+ ${ARGN}
+ )
+ if(NOT LIBC_UNITTEST_SRCS)
+ message(FATAL_ERROR "'add_libc_unittest' target requires a SRCS list of .cpp "
+ "files.")
+ endif()
+ if(NOT LIBC_UNITTEST_DEPENDS)
+ message(FATAL_ERROR "'add_libc_unittest' target requires a DEPENDS list of "
+ "'add_entrypoint_object' targets.")
+ endif()
+
+ set(library_deps "")
+ get_fq_deps_list(fq_deps_list ${LIBC_UNITTEST_DEPENDS})
+ foreach(dep IN LISTS fq_deps_list)
+ get_target_property(dep_type ${dep} "TARGET_TYPE")
+ 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)
+
+ get_fq_target_name(${target_name} fq_target_name)
+ add_executable(
+ ${fq_target_name}
+ EXCLUDE_FROM_ALL
+ ${LIBC_UNITTEST_SRCS}
+ ${LIBC_UNITTEST_HDRS}
+ )
+ target_include_directories(
+ ${fq_target_name}
+ PRIVATE
+ ${LIBC_SOURCE_DIR}
+ ${LIBC_BUILD_DIR}
+ ${LIBC_BUILD_DIR}/include
+ )
+ if(LIBC_UNITTEST_COMPILE_OPTIONS)
+ target_compile_options(
+ ${target_name}
+ PRIVATE ${LIBC_UNITTEST_COMPILE_OPTIONS}
+ )
+ endif()
+
+ if(library_deps)
+ target_link_libraries(${fq_target_name} PRIVATE ${library_deps})
+ endif()
+
+ set_target_properties(${fq_target_name}
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+ add_dependencies(
+ ${fq_target_name}
+ ${fq_deps_list}
+ )
+
+ target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest libc_test_utils)
+
+ add_custom_command(
+ TARGET ${fq_target_name}
+ POST_BUILD
+ COMMAND $<TARGET_FILE:${fq_target_name}>
+ )
+ if(LIBC_UNITTEST_SUITE)
+ add_dependencies(
+ ${LIBC_UNITTEST_SUITE}
+ ${fq_target_name}
+ )
+ endif()
+endfunction(add_libc_unittest)
+
+function(add_libc_testsuite suite_name)
+ add_custom_target(${suite_name})
+ add_dependencies(check-libc ${suite_name})
+endfunction(add_libc_testsuite)
+
+# Rule to add a fuzzer test.
+# Usage
+# add_libc_fuzzer(
+# <target name>
+# SRCS <list of .cpp files for the test>
+# HDRS <list of .h files for the test>
+# DEPENDS <list of dependencies>
+# )
+function(add_libc_fuzzer target_name)
+ cmake_parse_arguments(
+ "LIBC_FUZZER"
+ "" # No optional arguments
+ "" # Single value arguments
+ "SRCS;HDRS;DEPENDS" # Multi-value arguments
+ ${ARGN}
+ )
+ if(NOT LIBC_FUZZER_SRCS)
+ message(FATAL_ERROR "'add_libc_fuzzer' target requires a SRCS list of .cpp "
+ "files.")
+ endif()
+ if(NOT LIBC_FUZZER_DEPENDS)
+ message(FATAL_ERROR "'add_libc_fuzzer' target requires a DEPENDS list of "
+ "'add_entrypoint_object' targets.")
+ endif()
+
+ get_fq_deps_list(fq_deps_list ${LIBC_FUZZER_DEPENDS})
+ set(library_deps "")
+ foreach(dep IN LISTS fq_deps_list)
+ 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_FILES_RAW")
+ list(APPEND library_deps ${obj_file})
+ continue()
+ endif()
+ 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)
+
+ get_fq_target_name(${target_name} fq_target_name)
+ add_executable(
+ ${fq_target_name}
+ EXCLUDE_FROM_ALL
+ ${LIBC_FUZZER_SRCS}
+ ${LIBC_FUZZER_HDRS}
+ )
+ target_include_directories(
+ ${fq_target_name}
+ PRIVATE
+ ${LIBC_SOURCE_DIR}
+ ${LIBC_BUILD_DIR}
+ ${LIBC_BUILD_DIR}/include
+ )
+
+ if(library_deps)
+ target_link_libraries(${fq_target_name} PRIVATE ${library_deps})
+ endif()
+
+ set_target_properties(${fq_target_name}
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+ add_dependencies(
+ ${fq_target_name}
+ ${fq_deps_list}
+ )
+ add_dependencies(libc-fuzzer ${fq_target_name})
+endfunction(add_libc_fuzzer)
More information about the libc-commits
mailing list