Skip to content

Commit 905b110

Browse files
author
Alexey Samsonov
committed
[libc][hdrgen] Allow to treat hdrgen Python code as a Python module.
Move the hdrgen code under a subdirectory to treat it as a Python module. This mimics the structure used by llvm/utils/lit and llvm/utils/mlgo-utils and simplifies integration of hdrgen to the build system which rely on Python modules. In addition to that, it clarifies which imports are coming from the hdrgen-specific helpers (e.g. "from type import ..." becomes "from hdrgen.type import ...". Leave the entrypoints (top-level main.py and yaml_to_classes.py) as-is: they can keep being referred by the CMake build system w/o any changes.
1 parent ca5bb23 commit 905b110

File tree

13 files changed

+429
-398
lines changed

13 files changed

+429
-398
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2+
# See https://llvm.org/LICENSE.txt for license information.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
File renamed without changes.

libc/utils/hdrgen/function.py renamed to libc/utils/hdrgen/hdrgen/function.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import re
1010
from functools import total_ordering
11-
from type import Type
11+
from hdrgen.type import Type
1212

1313

1414
# These are the keywords that appear in C type syntax but are not part of the

libc/utils/hdrgen/gpu_headers.py renamed to libc/utils/hdrgen/hdrgen/gpu_headers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#
77
# ==-------------------------------------------------------------------------==#
88

9-
from header import HeaderFile
9+
from hdrgen.header import HeaderFile
1010

1111

1212
class GpuHeaderFile(HeaderFile):
File renamed without changes.
File renamed without changes.

libc/utils/hdrgen/hdrgen/main.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/usr/bin/env python3
2+
#
3+
# ===- Generate headers for libc functions ------------------*- python -*--==#
4+
#
5+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6+
# See https://llvm.org/LICENSE.txt for license information.
7+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
#
9+
# ==------------------------------------------------------------------------==#
10+
11+
import argparse
12+
import json
13+
import sys
14+
from pathlib import Path
15+
16+
from hdrgen.header import HeaderFile
17+
from hdrgen.yaml_to_classes import load_yaml_file, fill_public_api
18+
19+
20+
def main():
21+
parser = argparse.ArgumentParser(description="Generate header files from YAML")
22+
parser.add_argument(
23+
"yaml_file",
24+
help="Path to the YAML file containing header specification",
25+
metavar="FILE",
26+
type=Path,
27+
nargs="+",
28+
)
29+
parser.add_argument(
30+
"-o",
31+
"--output",
32+
help="Path to write generated header file",
33+
type=Path,
34+
required=True,
35+
)
36+
parser.add_argument(
37+
"--json",
38+
help="Write JSON instead of a header, can use multiple YAML files",
39+
action="store_true",
40+
)
41+
parser.add_argument(
42+
"--depfile",
43+
help="Path to write a depfile",
44+
type=Path,
45+
)
46+
parser.add_argument(
47+
"--write-if-changed",
48+
help="Write the output file only if its contents have changed",
49+
action="store_true",
50+
default=False,
51+
)
52+
parser.add_argument(
53+
"-e",
54+
"--entry-point",
55+
help="Entry point to include; may be given many times",
56+
metavar="SYMBOL",
57+
action="append",
58+
)
59+
args = parser.parse_args()
60+
61+
if not args.json and len(args.yaml_file) != 1:
62+
print("Only one YAML file at a time without --json", file=sys.stderr)
63+
parser.print_usage(sys.stderr)
64+
return 2
65+
66+
files_read = set()
67+
68+
def write_depfile():
69+
if not args.depfile:
70+
return
71+
deps = " ".join(str(f) for f in sorted(files_read))
72+
args.depfile.parent.mkdir(parents=True, exist_ok=True)
73+
with open(args.depfile, "w") as depfile:
74+
depfile.write(f"{args.output}: {deps}\n")
75+
76+
def load_yaml(path):
77+
files_read.add(path)
78+
return load_yaml_file(path, HeaderFile, args.entry_point)
79+
80+
def load_header(yaml_file):
81+
merge_from_files = dict()
82+
83+
def merge_from(paths):
84+
for path in paths:
85+
# Load each file exactly once, in case of redundant merges.
86+
if path in merge_from_files:
87+
continue
88+
header = load_yaml(path)
89+
merge_from_files[path] = header
90+
merge_from(path.parent / f for f in header.merge_yaml_files)
91+
92+
# Load the main file first.
93+
header = load_yaml(yaml_file)
94+
95+
# Now load all the merge_yaml_files, and transitive merge_yaml_files.
96+
merge_from(yaml_file.parent / f for f in header.merge_yaml_files)
97+
98+
# Merge in all those files' contents.
99+
for merge_from_path, merge_from_header in merge_from_files.items():
100+
if merge_from_header.name is not None:
101+
print(
102+
f"{merge_from_path!s}: Merge file cannot have header field",
103+
file=sys.stderr,
104+
)
105+
return 2
106+
header.merge(merge_from_header)
107+
108+
return header
109+
110+
if args.json:
111+
contents = json.dumps(
112+
[load_header(file).json_data() for file in args.yaml_file],
113+
indent=2,
114+
)
115+
else:
116+
[yaml_file] = args.yaml_file
117+
header = load_header(yaml_file)
118+
# The header_template path is relative to the containing YAML file.
119+
template = header.template(yaml_file.parent, files_read)
120+
contents = fill_public_api(header.public_api(), template)
121+
122+
write_depfile()
123+
124+
if (
125+
not args.write_if_changed
126+
or not args.output.exists()
127+
or args.output.read_text() != contents
128+
):
129+
args.output.parent.mkdir(parents=True, exist_ok=True)
130+
args.output.write_text(contents)
131+
132+
133+
if __name__ == "__main__":
134+
sys.exit(main())
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)