Skip to content

Commit 69894f9

Browse files
committed
build: add gen-predefined-macros
Add a new `gen-predefined-macros` tool to generate the `predefined-macros.txt` and `include-all.c` resources. This allows for a portable way to generate these files, which is important for build environments like Windows which do not have the unix tools available.
1 parent f8b4634 commit 69894f9

File tree

3 files changed

+172
-14
lines changed

3 files changed

+172
-14
lines changed

CMakeLists.txt

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/alltypes.h.gen
3333
${PROJECT_SOURCE_DIR}/libc-top-half/musl/arch/wasm32/bits/alltypes.h.in
3434
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/alltypes.h.in)
3535

36-
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot
37-
COMMAND ${CMAKE_COMMAND} -E make_directory
36+
add_custom_command(
37+
OUTPUT
38+
${CMAKE_BINARY_DIR}/sysroot
39+
${CMAKE_BINARY_DIR}/sysroot/share/include-all.c
40+
41+
COMMAND
42+
${CMAKE_COMMAND} -E make_directory
3843
${CMAKE_BINARY_DIR}/sysroot/include/
3944
${CMAKE_BINARY_DIR}/sysroot/include/arpa/
4045
${CMAKE_BINARY_DIR}/sysroot/include/bits/
@@ -43,7 +48,8 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot
4348
${CMAKE_BINARY_DIR}/sysroot/include/sys/
4449
${CMAKE_BINARY_DIR}/sysroot/include/wasi/
4550

46-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
51+
COMMAND
52+
${CMAKE_COMMAND} -E copy_if_different
4753
${PROJECT_SOURCE_DIR}/basics/include/__errno.h
4854
${PROJECT_SOURCE_DIR}/basics/include/__functions_malloc.h
4955
${PROJECT_SOURCE_DIR}/basics/include/__functions_memcpy.h
@@ -178,7 +184,8 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot
178184
$<$<BOOL:ENABLE_THREADS>:${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/pthread.h>
179185
${CMAKE_BINARY_DIR}/sysroot/include/
180186

181-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
187+
COMMAND
188+
${CMAKE_COMMAND} -E copy_if_different
182189
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/arpa/ftp.h
183190
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/arpa/inet.h
184191
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/arpa/nameser_compat.h
@@ -187,7 +194,8 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot
187194
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/arpa/tftp.h
188195
${CMAKE_BINARY_DIR}/sysroot/include/arpa/
189196

190-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
197+
COMMAND
198+
${CMAKE_COMMAND} -E copy_if_different
191199
${PROJECT_SOURCE_DIR}/libc-top-half/musl/arch/generic/bits/fenv.h
192200
${PROJECT_SOURCE_DIR}/libc-top-half/musl/arch/generic/bits/hwcap.h
193201
${PROJECT_SOURCE_DIR}/libc-top-half/musl/arch/generic/bits/ioctl_fix.h
@@ -210,7 +218,8 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot
210218
${PROJECT_SOURCE_DIR}/libc-top-half/musl/arch/wasm32/bits/stdint.h
211219
${CMAKE_BINARY_DIR}/sysroot/include/bits/
212220

213-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
221+
COMMAND
222+
${CMAKE_COMMAND} -E copy_if_different
214223
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/netinet/icmp6.h
215224
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/netinet/igmp.h
216225
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/netinet/in.h
@@ -222,11 +231,13 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot
222231
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/netinet/udp.h
223232
${CMAKE_BINARY_DIR}/sysroot/include/netinet/
224233

225-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
234+
COMMAND
235+
${CMAKE_COMMAND} -E copy_if_different
226236
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/netpacket/packet.h
227-
${CMAKE_BINARY_DIR}/sysroot/include/netpacket/
237+
${CMAKE_BINARY_DIR}/sysroot/include/netpacket/
228238

229-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
239+
COMMAND
240+
${CMAKE_COMMAND} -E copy_if_different
230241
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/sys/dir.h
231242
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/sys/errno.h
232243
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/sys/eventfd.h
@@ -257,22 +268,33 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot
257268
${PROJECT_SOURCE_DIR}/libc-top-half/musl/include/sys/utsname.h
258269
${CMAKE_BINARY_DIR}/sysroot/include/sys/
259270

260-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
271+
COMMAND
272+
${CMAKE_COMMAND} -E copy_if_different
261273
${PROJECT_SOURCE_DIR}/libc-bottom-half/headers/public/wasi/api.h
262274
${PROJECT_SOURCE_DIR}/libc-bottom-half/headers/public/wasi/libc-find-relpath.h
263275
${PROJECT_SOURCE_DIR}/libc-bottom-half/headers/public/wasi/libc.h
264276
${CMAKE_BINARY_DIR}/sysroot/include/wasi/
265277

266-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
278+
COMMAND
279+
${CMAKE_COMMAND} -E copy_if_different
267280
${CMAKE_BINARY_DIR}/alltypes.h.gen
268281
${CMAKE_BINARY_DIR}/sysroot/include/bits/alltypes.h
269282

283+
COMMAND
284+
${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/sysroot/share
285+
286+
COMMAND
287+
${Python_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/gen-predefined-macros.py
288+
--cc ${CMAKE_C_COMPILER}
289+
--output-directory ${CMAKE_BINARY_DIR}/sysroot/share
290+
--sysroot ${CMAKE_BINARY_DIR}/sysroot
291+
-target ${CMAKE_C_COMPILER_TARGET} -O2 -DNDEBUG
292+
270293
DEPENDS
294+
${PROJECT_SOURCE_DIR}/tools/gen-predefined-macros.py
271295
${CMAKE_BINARY_DIR}/alltypes.h.gen)
272296
add_custom_target(sysroot-headers DEPENDS ${CMAKE_BINARY_DIR}/sysroot)
273297

274-
275-
276298
# startup files
277299
add_library(crt1 OBJECT
278300
libc-bottom-half/crt/crt1.c)

tools/gen-imports.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def main(argv):
3333
'--undefined-only',
3434
'--extern-only',
3535
'--just-symbol-name',
36-
] + unparsed,
36+
] + [ os.path.normpath(path) for path in unparsed ],
3737
stdout = subprocess.PIPE)
3838
output, error = process.communicate()
3939

tools/gen-predefined-macros.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# -*- encoding: utf-8 -*-
2+
"""Generate macro enumeration for WASI target
3+
4+
This utility generates the full list of compiler macros defined during the WASI
5+
builds. It writes out the `predefined-macros.txt` and `include-all.c` files
6+
into the directory specificed.
7+
8+
Examples:
9+
$ python gen-predefined-macros.py --cc clang --sysroot sysroot --output-directory sysroot/share
10+
"""
11+
12+
import argparse
13+
import os
14+
import re
15+
import subprocess
16+
import sys
17+
18+
from subprocess import Popen
19+
20+
def _enumerate_headers(directory):
21+
headers = set()
22+
23+
for root, directories, files in os.walk(directory):
24+
# ignore the bits directories as they are internal implementation
25+
# details
26+
directories[:] = [ d for d in directories if not d == 'bits' ]
27+
28+
# Compute the include relative path, however special case '.' to be
29+
# ignored as a prefix.
30+
path = os.path.relpath(root, directory)
31+
if path == '.':
32+
path = ''
33+
34+
# ignore mman.h
35+
# XXX(compnerd) document why mman.h is being ignored
36+
for include in filter(lambda file: not file == 'mman.h', files):
37+
headers.add(os.path.join(path, include))
38+
39+
return headers
40+
41+
def _enumerate_defines(cc, sysroot, flags, include_all_c):
42+
include = os.path.join(sysroot, 'include')
43+
44+
# Collect all the predefined macros ...
45+
process = Popen([
46+
cc,
47+
'-D_ALL_SOURCE',
48+
49+
# ... except for compiler names to keep these
50+
# compiler-idependent
51+
'-U__llvm__',
52+
'-U__clang__',
53+
54+
# ... except for the compiler version macros which we do
55+
# not need to track here
56+
'-U__clang_major__',
57+
'-U__clang_minor__',
58+
'-U__clang_patchlevel__',
59+
'-U__clang_version__',
60+
61+
'-U__GNUC__',
62+
'-U__GNUC_MINOR__',
63+
'-U__GNUC_MAJOR__',
64+
'-U__GNUC_PATCHLEVEL__',
65+
66+
'-U__VERSION__',
67+
68+
# ... marking the sysroot as a system include path as
69+
# clang will include its resource directory include path
70+
# earlier producing compiler-specific output
71+
'-isystem', include,
72+
73+
'-E', include_all_c,
74+
'-dM',
75+
76+
'-Wno-#warnings',
77+
] + flags,
78+
stdout = subprocess.PIPE,
79+
stderr = sys.stderr)
80+
output, error = process.communicate()
81+
82+
if process.returncode:
83+
sys.exit(process.returncode)
84+
85+
defines = output.decode('utf-8').splitlines()
86+
87+
# filter out
88+
# - __FLT16_* for now as not all versions of clang have these
89+
# - __FLOAT128__ as it is not in clang 8.0
90+
__FLT16_ = re.compile(r'\b__FLT16_')
91+
__FLOAT128__ = re.compile(r'\b__FLOAT128__\b')
92+
93+
defines = [
94+
define for define in defines if not (
95+
re.search(__FLT16_, define) or
96+
re.search(__FLOAT128__, define) or
97+
False
98+
)
99+
]
100+
101+
# For the __*_ATOMIC_*_LOCK_FREE macros, squash individual compiler names to
102+
# attempt to keep these files compiler-independent
103+
defines = [
104+
re.sub(r'__[A-Z0-9]*_ATOMIC_([A-Z0-9_]*)_LOCK_FREE',
105+
r'__compiler_ATOMIC_\1_LOCK_FREE', define)
106+
for define in defines
107+
]
108+
109+
return defines
110+
111+
def main(argv):
112+
parser = argparse.ArgumentParser('gen-predefined-macros')
113+
parser.add_argument('--cc', default = 'clang')
114+
parser.add_argument('--sysroot', required = True)
115+
parser.add_argument('--output-directory', required = True, dest = 'output')
116+
117+
args, unparsed = parser.parse_known_args()
118+
119+
args.output = os.path.normpath(args.output)
120+
args.sysroot = os.path.normpath(args.sysroot)
121+
122+
include = os.path.join(args.sysroot, 'include')
123+
include_all_c = os.path.join(args.output, 'include-all.c')
124+
predefined_macros_txt = os.path.join(args.output, 'predefined-macros.txt')
125+
126+
with open(include_all_c, 'w') as source:
127+
for header in sorted(_enumerate_headers(include)):
128+
source.write('#include <{}>\n'.format(header))
129+
130+
with open(predefined_macros_txt, 'w') as macros:
131+
for define in _enumerate_defines(args.cc, args.sysroot, unparsed,
132+
include_all_c):
133+
macros.write('{}\n'.format(define))
134+
135+
if __name__ == '__main__':
136+
main(sys.argv)

0 commit comments

Comments
 (0)