llvm-project/libc/cmake/modules/LLVMLibCHeaderRules.cmake
2024-12-04 08:48:12 -08:00

174 lines
5.4 KiB
CMake

# 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;DEST_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()
if(ADD_HEADER_DEST_HDR)
set(dest_leaf_filename ${ADD_HEADER_DEST_HDR})
else()
set(dest_leaf_filename ${ADD_HEADER_HDR})
endif()
set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${dest_leaf_filename})
file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_SOURCE_DIR} ${absolute_path})
set(dest_file ${LIBC_INCLUDE_DIR}/${relative_path})
set(src_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_HEADER_HDR})
add_custom_command(
OUTPUT ${dest_file}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dest_file}
DEPENDS ${src_file}
)
get_fq_target_name(${target_name} fq_target_name)
set(copied_hdr_target ${fq_target_name}.__copied_hdr__)
add_custom_target(
${copied_hdr_target}
DEPENDS ${dest_file}
)
if(ADD_HEADER_DEPENDS)
get_fq_deps_list(fq_deps_list ${ADD_HEADER_DEPENDS})
# Dependencies of a add_header target can only be another add_header target
# or an add_gen_header target.
foreach(dep IN LISTS fq_deps_list)
get_target_property(header_file ${dep} HEADER_FILE_PATH)
if(NOT header_file)
message(FATAL_ERROR "Invalid dependency '${dep}' for '${fq_target_name}'.")
endif()
endforeach()
add_dependencies(
${copied_hdr_target} ${fq_deps_list}
)
endif()
add_header_library(
${target_name}
HDRS
${dest_file}
DEPENDS
${copied_hdr_target}
)
set_target_properties(
${fq_target_name}
PROPERTIES
HEADER_FILE_PATH ${dest_file}
DEPS "${fq_deps_list}"
)
endfunction(add_header)
function(add_gen_header target_name)
cmake_parse_arguments(
"ADD_GEN_HDR"
"PUBLIC" # No optional arguments
"YAML_FILE;DEF_FILE;GEN_HDR" # Single value arguments
"DEPENDS" # Multi value arguments
${ARGN}
)
get_fq_target_name(${target_name} fq_target_name)
if(NOT LLVM_LIBC_FULL_BUILD)
add_library(${fq_target_name} INTERFACE)
return()
endif()
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()
if(NOT ADD_GEN_HDR_YAML_FILE)
message(FATAL_ERROR "`add_gen_hdr` rule requires YAML_FILE to be specified.")
endif()
set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR_GEN_HDR})
file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_SOURCE_DIR} ${absolute_path})
set(out_file ${LIBC_INCLUDE_DIR}/${relative_path})
set(yaml_file ${CMAKE_SOURCE_DIR}/${ADD_GEN_HDR_YAML_FILE})
set(def_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(entry_points "${TARGET_ENTRYPOINT_NAME_LIST}")
list(TRANSFORM entry_points PREPEND "--e=")
add_custom_command(
OUTPUT ${out_file}
COMMAND ${Python3_EXECUTABLE} ${LIBC_SOURCE_DIR}/hdrgen/yaml_to_classes.py
${yaml_file}
--h_def_file ${def_file}
${entry_points}
--output_dir ${out_file}
DEPENDS ${yaml_file} ${def_file} ${fq_data_files}
COMMENT "Generating header ${ADD_GEN_HDR_GEN_HDR} from ${yaml_file} and ${def_file}"
)
if(LIBC_TARGET_OS_IS_GPU)
file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls)
file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls/gpu)
set(decl_out_file ${LIBC_INCLUDE_DIR}/llvm-libc-decls/${relative_path})
add_custom_command(
OUTPUT ${decl_out_file}
COMMAND ${Python3_EXECUTABLE} ${LIBC_SOURCE_DIR}/hdrgen/yaml_to_classes.py
${yaml_file}
--export-decls
${entry_points}
--output_dir ${decl_out_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${yaml_file} ${fq_data_files}
)
endif()
if(ADD_GEN_HDR_DEPENDS)
get_fq_deps_list(fq_deps_list ${ADD_GEN_HDR_DEPENDS})
# Dependencies of a add_header target can only be another add_gen_header target
# or an add_header target.
foreach(dep IN LISTS fq_deps_list)
get_target_property(header_file ${dep} HEADER_FILE_PATH)
if(NOT header_file)
message(FATAL_ERROR "Invalid dependency '${dep}' for '${fq_target_name}'.")
endif()
endforeach()
endif()
set(generated_hdr_target ${fq_target_name}.__generated_hdr__)
add_custom_target(
${generated_hdr_target}
DEPENDS ${out_file} ${fq_deps_list} ${decl_out_file}
)
add_header_library(
${target_name}
HDRS
${out_file}
)
add_dependencies(${fq_target_name} ${generated_hdr_target})
set_target_properties(
${fq_target_name}
PROPERTIES
HEADER_FILE_PATH ${out_file}
DECLS_FILE_PATH "${decl_out_file}"
DEPS "${fq_deps_list}"
)
endfunction(add_gen_header)