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:
authorSiva Chandra Reddy <sivachandra@google.com>2020-04-18 04:42:40 +0300
committerSiva Chandra Reddy <sivachandra@google.com>2020-04-21 19:24:17 +0300
commit8c2e66226fb74114fc0e57f239721065d800d33f (patch)
treec7e176e5d817c35c2a0771566388d9a34f550c6c /libc/cmake/modules/LLVMLibCObjectRules.cmake
parent177c065e5065ef140c1e83ab655c3aad904a3a40 (diff)
[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
Diffstat (limited to 'libc/cmake/modules/LLVMLibCObjectRules.cmake')
-rw-r--r--libc/cmake/modules/LLVMLibCObjectRules.cmake313
1 files changed, 313 insertions, 0 deletions
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 different 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)
+