From 0e5a892f3a3e3dc9d77695cf7f3a4c9a08702aba Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Oct 2024 10:11:57 -0700 Subject: [PATCH 1/3] [libc] Add some integration features into newhdrgen This adds some command-line switches to the newhdrgen script that facilitate more generalized build system integration. These enable the use of the script in Fuchsia's GN build. The --write-if-changed switch avoids touching the .h output file if it's unchanged, which is beneficial to incremental rebuilds. The --depfile switch writes out a make/ninja-compatible depfile describing the inputs and outputs. This is crucial for build system integration when using the following new feature. When the new --libc-dir switch is given, the YAML file argument is optional. Instead, the --h_def_file input file path must have the --libc-dir path as a prefix and the yaml file is found in its corresponding place in the libc source tree. --- libc/newhdrgen/yaml_to_classes.py | 64 +++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py index a295058f7dc82..9eca993da998e 100644 --- a/libc/newhdrgen/yaml_to_classes.py +++ b/libc/newhdrgen/yaml_to_classes.py @@ -219,15 +219,36 @@ def increase_indent(self, flow=False, indentless=False): def main(): parser = argparse.ArgumentParser(description="Generate header files from YAML") parser.add_argument( - "yaml_file", help="Path to the YAML file containing header specification" + "yaml_file", + help="Path to the YAML file containing header specification", + type=Path, + nargs="?", ) parser.add_argument( "--output_dir", help="Directory to output the generated header file", + type=Path, ) parser.add_argument( "--h_def_file", help="Path to the .h.def template file (required if not using --export_decls)", + type=Path, + ) + parser.add_argument( + "--libc-dir", + help="Path to llvm-libc source tree", + type=Path, + default=Path(__file__).parents[1] + ) + parser.add_argument( + "--depfile", + help="Path to write a depfile", + type=argparse.FileType("w"), + ) + parser.add_argument( + "--write-if-changed", + help="Don't touch the output .h file if it's unchanged", + action="store_true", ) parser.add_argument( "--add_function", @@ -252,30 +273,51 @@ def main(): ) args = parser.parse_args() + def write_to_file(path, contents): + if not args.write_if_changed or not path.exists() or path.read_text() != contents: + path.write_text(contents) + + if args.h_def_file and not args.yaml_file: + libc_include_dir = args.libc_dir / "include" + libc_yaml_dir = args.libc_dir / "newhdrgen" / "yaml" + args.yaml_file = libc_yaml_dir / args.h_def_file.with_suffix("").with_suffix(".yaml").relative_to(libc_include_dir) + + if args.output_dir: + output_file_path = args.output_dir + if output_file_path.is_dir(): + libc_yaml_dir = args.libc_dir / "newhdrgen" / "yaml" + output_file_path /= args.yaml_file.relative_to(libc_yaml_dir).with_suffix(".h") + output_file_path.parent.mkdir(parents=True, exist_ok=True) + else: + output_file_path = args.yaml_file.with_suffix(".h") + + if args.depfile and args.h_def_file: + args.depfile.write( + f"{output_file_path}: {args.h_def_file} {args.yaml_file}\n") + args.depfile.close() + if args.add_function: add_function_to_yaml(yaml_file, args.add_function) header_class = GpuHeader if args.export_decls else HeaderFile header = load_yaml_file(args.yaml_file, header_class, args.entry_points) + if args.add_function: + add_function_to_yaml(yaml_file, args.add_function) + header_str = str(header) + header_class = GpuHeader if args.export_decls else HeaderFile + header = load_yaml_file(args.yaml_file, header_class, args.entry_points) - if args.output_dir: - output_file_path = Path(args.output_dir) - if output_file_path.is_dir(): - output_file_path /= f"{Path(args.yaml_file).stem}.h" - else: - output_file_path = Path(f"{Path(args.yaml_file).stem}.h") + header_str = str(header) if not args.export_decls and args.h_def_file: with open(args.h_def_file, "r") as f: h_def_content = f.read() final_header_content = fill_public_api(header_str, h_def_content) - with open(output_file_path, "w") as f: - f.write(final_header_content) else: - with open(output_file_path, "w") as f: - f.write(header_str) + final_header_content = str + write_to_file(output_file_path, final_header_content) if __name__ == "__main__": From 712bbb86db3935a8f350f2d5237eef5b18b4e46b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Oct 2024 10:23:52 -0700 Subject: [PATCH 2/3] Restore old behavior for test suite with explicit YAML file arg --- libc/newhdrgen/yaml_to_classes.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py index 9eca993da998e..9ad6ea0a87d11 100644 --- a/libc/newhdrgen/yaml_to_classes.py +++ b/libc/newhdrgen/yaml_to_classes.py @@ -277,16 +277,20 @@ def write_to_file(path, contents): if not args.write_if_changed or not path.exists() or path.read_text() != contents: path.write_text(contents) - if args.h_def_file and not args.yaml_file: + yaml_file = args.yaml_file + if args.h_def_file and not yaml_file: libc_include_dir = args.libc_dir / "include" libc_yaml_dir = args.libc_dir / "newhdrgen" / "yaml" - args.yaml_file = libc_yaml_dir / args.h_def_file.with_suffix("").with_suffix(".yaml").relative_to(libc_include_dir) + yaml_file = libc_yaml_dir / args.h_def_file.with_suffix("").with_suffix(".yaml").relative_to(libc_include_dir) if args.output_dir: output_file_path = args.output_dir if output_file_path.is_dir(): - libc_yaml_dir = args.libc_dir / "newhdrgen" / "yaml" - output_file_path /= args.yaml_file.relative_to(libc_yaml_dir).with_suffix(".h") + if not args.yaml_file: + libc_yaml_dir = args.libc_dir / "newhdrgen" / "yaml" + output_file_path /= args.yaml_file.relative_to(libc_yaml_dir).with_suffix(".h") + else: + output_file_path /= f"{Path(args.yaml_file).stem}.h" output_file_path.parent.mkdir(parents=True, exist_ok=True) else: output_file_path = args.yaml_file.with_suffix(".h") From 15c13eb5661c5568339cd90dad99b0e2c2e88534 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Oct 2024 10:27:44 -0700 Subject: [PATCH 3/3] python formatting --- libc/newhdrgen/yaml_to_classes.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py index 9ad6ea0a87d11..460bc4a87452c 100644 --- a/libc/newhdrgen/yaml_to_classes.py +++ b/libc/newhdrgen/yaml_to_classes.py @@ -238,7 +238,7 @@ def main(): "--libc-dir", help="Path to llvm-libc source tree", type=Path, - default=Path(__file__).parents[1] + default=Path(__file__).parents[1], ) parser.add_argument( "--depfile", @@ -274,21 +274,29 @@ def main(): args = parser.parse_args() def write_to_file(path, contents): - if not args.write_if_changed or not path.exists() or path.read_text() != contents: + if ( + not args.write_if_changed + or not path.exists() + or path.read_text() != contents + ): path.write_text(contents) yaml_file = args.yaml_file if args.h_def_file and not yaml_file: libc_include_dir = args.libc_dir / "include" libc_yaml_dir = args.libc_dir / "newhdrgen" / "yaml" - yaml_file = libc_yaml_dir / args.h_def_file.with_suffix("").with_suffix(".yaml").relative_to(libc_include_dir) + yaml_file = libc_yaml_dir / args.h_def_file.with_suffix("").with_suffix( + ".yaml" + ).relative_to(libc_include_dir) if args.output_dir: output_file_path = args.output_dir if output_file_path.is_dir(): if not args.yaml_file: libc_yaml_dir = args.libc_dir / "newhdrgen" / "yaml" - output_file_path /= args.yaml_file.relative_to(libc_yaml_dir).with_suffix(".h") + output_file_path /= args.yaml_file.relative_to( + libc_yaml_dir + ).with_suffix(".h") else: output_file_path /= f"{Path(args.yaml_file).stem}.h" output_file_path.parent.mkdir(parents=True, exist_ok=True) @@ -296,8 +304,7 @@ def write_to_file(path, contents): output_file_path = args.yaml_file.with_suffix(".h") if args.depfile and args.h_def_file: - args.depfile.write( - f"{output_file_path}: {args.h_def_file} {args.yaml_file}\n") + args.depfile.write(f"{output_file_path}: {args.h_def_file} {args.yaml_file}\n") args.depfile.close() if args.add_function: