[libc-commits] [libc] [libc] cmake configruation for newhdrgen (PR #98257)
via libc-commits
libc-commits at lists.llvm.org
Tue Jul 9 17:48:10 PDT 2024
https://github.com/aaryanshukla created https://github.com/llvm/llvm-project/pull/98257
- this is a draft to get more input/reviews
- tests have been done on dirent and ctype to see matching results as
old headergen
- added entrypoints filtering within the script
>From 8502b463b718f7f75faa73b848bd48214525d3e2 Mon Sep 17 00:00:00 2001
From: Aaryan Shukla <aaryanshukla at google.com>
Date: Wed, 10 Jul 2024 00:46:38 +0000
Subject: [PATCH] [libc] cmake configruation for newhdrgen
- this is a draft to get more input/reviews
- tests have been done on dirent and ctype to see matching results as
old headergen
- added entrypoints filtering within the script
---
libc/cmake/modules/LLVMLibCHeaderRules.cmake | 87 +++++++++++++++++++-
libc/include/CMakeLists.txt | 7 +-
libc/newhdrgen/yaml_to_classes.py | 32 +++++--
3 files changed, 114 insertions(+), 12 deletions(-)
diff --git a/libc/cmake/modules/LLVMLibCHeaderRules.cmake b/libc/cmake/modules/LLVMLibCHeaderRules.cmake
index 7fc6860f23eb2..51e546b687098 100644
--- a/libc/cmake/modules/LLVMLibCHeaderRules.cmake
+++ b/libc/cmake/modules/LLVMLibCHeaderRules.cmake
@@ -6,6 +6,7 @@
# <target name>
# HDR <header file>
# )
+
function(add_header target_name)
cmake_parse_arguments(
"ADD_HEADER"
@@ -15,7 +16,7 @@ function(add_header target_name)
${ARGN}
)
if(NOT ADD_HEADER_HDR)
- message(FATAL_ERROR "'add_header' rules requires the HDR argument specifying a headef file.")
+ message(FATAL_ERROR "'add_header' rules requires the HDR argument specifying a header file.")
endif()
set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_HEADER_HDR})
@@ -66,6 +67,90 @@ function(add_header target_name)
)
endfunction(add_header)
+function(add_yaml_header target_name)
+ cmake_parse_arguments(
+ "ADD_YAML_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)
+ # We don't want to use generated headers if we are doing a non-full-build.
+ add_library(${fq_target_name} INTERFACE)
+ return()
+ endif()
+ if(NOT ADD_YAML_HDR_DEF_FILE)
+ message(FATAL_ERROR "`add_yaml_hdr` rule requires DEF_FILE to be specified.")
+ endif()
+ if(NOT ADD_YAML_HDR_GEN_HDR)
+ message(FATAL_ERROR "`add_yaml_hdr` rule requires GEN_HDR to be specified.")
+ endif()
+ if(NOT ADD_YAML_HDR_YAML_FILE)
+ message(FATAL_ERROR "`add_yaml_hdr` rule requires YAML_FILE to be specified.")
+ endif()
+
+ set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_YAML_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_YAML_HDR_YAML_FILE})
+ set(def_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_YAML_HDR_DEF_FILE})
+
+ set(fq_data_files "")
+ if(ADD_YAML_HDR_DATA_FILES)
+ foreach(data_file IN LISTS ADD_YAML_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}/newhdrgen/yaml_to_classes.py
+ ${yaml_file}
+ ${def_file}
+ ${entry_points}
+ --output_dir ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${yaml_file} ${def_file} ${fq_data_files}
+ COMMENT "Generating header ${ADD_YAML_HDR_GEN_HDR} from ${yaml_file} and ${def_file}"
+ )
+
+ if(ADD_YAML_HDR_DEPENDS)
+ get_fq_deps_list(fq_deps_list ${ADD_YAML_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}
+ )
+
+ 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}
+ DEPS "${fq_deps_list}"
+ )
+endfunction(add_yaml_header)
+
# A rule for generated header file targets.
# Usage:
# add_gen_header(
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index f8ef35078a8c4..6f4cb9e1ba1d5 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LIBC_INCLUDE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
include(LLVMLibCHeaderRules)
+
# The GPU build wants to install files in the compiler's resource directory.
if(LIBC_TARGET_OS_IS_GPU)
include(GetClangResourceDir)
@@ -17,16 +18,18 @@ add_header(
__llvm-libc-common.h
)
-add_gen_header(
+add_yaml_header(
ctype
+ YAML_FILE ../libc/newhdrgen/yaml/ctype.yaml
DEF_FILE ctype.h.def
GEN_HDR ctype.h
DEPENDS
.llvm_libc_common_h
)
-add_gen_header(
+add_yaml_header(
dirent
+ YAML_FILE ../libc/newhdrgen/yaml/dirent.yaml
DEF_FILE dirent.h.def
GEN_HDR dirent.h
DEPENDS
diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py
index 9e0337f4a308e..ee2abec4fdc11 100644
--- a/libc/newhdrgen/yaml_to_classes.py
+++ b/libc/newhdrgen/yaml_to_classes.py
@@ -11,7 +11,6 @@
import yaml
import argparse
-
from pathlib import Path
from header import HeaderFile
from class_implementation.classes.macro import Macro
@@ -22,12 +21,13 @@
from class_implementation.classes.object import Object
-def yaml_to_classes(yaml_data):
+def yaml_to_classes(yaml_data, entry_points=None):
"""
- Convert YAML data to header classes.
+ Convert YAML data to header classes, filtering functions by entry points.
Args:
yaml_data: The YAML data containing header specifications.
+ entry_points: A list of entry points to filter functions.
Returns:
HeaderFile: An instance of HeaderFile populated with the data.
@@ -47,6 +47,9 @@ def yaml_to_classes(yaml_data):
)
functions = yaml_data.get("functions", [])
+ if entry_points:
+ entry_points_set = set(entry_points)
+ functions = [f for f in functions if f["name"] in entry_points_set]
sorted_functions = sorted(functions, key=lambda x: x["name"])
for function_data in sorted_functions:
arguments = [arg["type"] for arg in function_data["arguments"]]
@@ -75,19 +78,20 @@ def yaml_to_classes(yaml_data):
return header
-def load_yaml_file(yaml_file):
+def load_yaml_file(yaml_file, entry_points):
"""
- Load YAML file and convert it to header classes.
+ Load YAML file and convert it to header classes, filtering by entry points.
Args:
yaml_file: The path to the YAML file.
+ entry_points: A list of entry points to filter functions.
Returns:
HeaderFile: An instance of HeaderFile populated with the data from the YAML file.
"""
with open(yaml_file, "r") as f:
yaml_data = yaml.safe_load(f)
- return yaml_to_classes(yaml_data)
+ return yaml_to_classes(yaml_data, entry_points)
def fill_public_api(header_str, h_def_content):
@@ -177,7 +181,7 @@ def increase_indent(self, flow=False, indentless=False):
print(f"Added function {new_function.name} to {yaml_file}")
-def main(yaml_file, h_def_file, output_dir, add_function=None):
+def main(yaml_file, h_def_file, output_dir, add_function=None, entry_points=None):
"""
Main function to generate header files from YAML and .h.def templates.
@@ -186,12 +190,13 @@ def main(yaml_file, h_def_file, output_dir, add_function=None):
h_def_file: Path to the .h.def template file.
output_dir: Directory to output the generated header file.
add_function: Details of the function to be added to the YAML file (if any).
+ entry_points: A list of entry points to filter functions.
"""
if add_function:
add_function_to_yaml(yaml_file, add_function)
- header = load_yaml_file(yaml_file)
+ header = load_yaml_file(yaml_file, entry_points)
with open(h_def_file, "r") as f:
h_def_content = f.read()
@@ -234,6 +239,15 @@ def main(yaml_file, h_def_file, output_dir, add_function=None):
),
help="Add a function to the YAML file",
)
+ parser.add_argument(
+ "--e", action="append", help="Entry point to include", dest="entry_points"
+ )
args = parser.parse_args()
- main(args.yaml_file, args.h_def_file, args.output_dir, args.add_function)
+ main(
+ args.yaml_file,
+ args.h_def_file,
+ args.output_dir,
+ args.add_function,
+ args.entry_points,
+ )
More information about the libc-commits
mailing list