Skip to content

Commit 5a7e77e

Browse files
committed
Build a complete sysroot in the cache directory
Rather than adding various include paths, copy any needed headers into the sysroot along with any libraries. This means that emscripten can work a lot more like the traditional cross compiler (e.g. clang -target=xxx --sysroot=yyy), and we can start to think of the emscripten driver as a seperate thing to the sysroot. Fixes: #9353
1 parent 8191c6a commit 5a7e77e

File tree

9 files changed

+115
-80
lines changed

9 files changed

+115
-80
lines changed

embuilder.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,9 @@ def main():
129129

130130
if args.lto:
131131
shared.Settings.LTO = "full"
132-
# Reconfigure the cache dir to reflect the change
133-
shared.reconfigure_cache()
134132

135133
if args.pic:
136134
shared.Settings.RELOCATABLE = 1
137-
# Reconfigure the cache dir to reflect the change
138-
shared.reconfigure_cache()
139135

140136
if args.force:
141137
force = True
@@ -177,6 +173,10 @@ def main():
177173
if force:
178174
library.erase()
179175
library.get_path()
176+
elif what == 'sysroot':
177+
if force:
178+
shared.Cache.erase_file('sysroot_install.stamp')
179+
system_libs.ensure_sysroot()
180180
elif what == 'struct_info':
181181
if force:
182182
shared.Cache.erase_file('generated_struct_info.json')

emcc.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,16 +1367,6 @@ def filter_out_duplicate_dynamic_libs(inputs):
13671367
'_emscripten_stack_get_end',
13681368
'_emscripten_stack_set_limits']
13691369

1370-
# Reconfigure the cache now that settings have been applied. Some settings
1371-
# such as LTO and SIDE_MODULE/MAIN_MODULE effect which cache directory we use.
1372-
shared.reconfigure_cache()
1373-
1374-
if not compile_only and not options.post_link:
1375-
ldflags = shared.emsdk_ldflags(newargs)
1376-
for f in ldflags:
1377-
newargs.append(f)
1378-
add_link_flag(len(newargs), f)
1379-
13801370
# SSEx is implemented on top of SIMD128 instruction set, but do not pass SSE flags to LLVM
13811371
# so it won't think about generating native x86 SSE code.
13821372
newargs = [x for x in newargs if x not in shared.SIMD_INTEL_FEATURE_TOWER and x not in shared.SIMD_NEON_FLAGS]
@@ -1984,6 +1974,7 @@ def is_link_flag(flag):
19841974

19851975
compile_args = [a for a in newargs if a and not is_link_flag(a)]
19861976
cflags = calc_cflags(options)
1977+
system_libs.ensure_sysroot()
19871978
system_libs.add_ports_cflags(cflags, shared.Settings)
19881979

19891980
def use_cxx(src):
@@ -2010,9 +2001,8 @@ def get_compiler(cxx):
20102001
return CC
20112002

20122003
def get_clang_command(src_file):
2013-
cxx = use_cxx(src_file)
2014-
per_file_cflags = shared.get_cflags(args, cxx)
2015-
return get_compiler(cxx) + cflags + per_file_cflags + compile_args + [src_file]
2004+
per_file_cflags = shared.get_cflags(args)
2005+
return get_compiler(use_cxx(src_file)) + cflags + per_file_cflags + compile_args + [src_file]
20162006

20172007
def get_clang_command_asm(src_file):
20182008
asflags = shared.get_asmflags()
@@ -2106,6 +2096,10 @@ def compile_source_file(i, input_file):
21062096
if specified_target and specified_target.startswith('-'):
21072097
exit_with_error('invalid output filename: `%s`' % specified_target)
21082098

2099+
ldflags = shared.emsdk_ldflags(newargs)
2100+
for f in ldflags:
2101+
add_link_flag(sys.maxsize, f)
2102+
21092103
using_lld = not (link_to_object and shared.Settings.LTO)
21102104
link_flags = filter_link_flags(link_flags, using_lld)
21112105

src/struct_info.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,7 +1525,7 @@
15251525
]
15261526
},
15271527
{
1528-
"file": "../lib/libc/musl/src/internal/pthread_impl.h",
1528+
"file": "system/lib/libc/musl/src/internal/pthread_impl.h",
15291529
"structs": {
15301530
"pthread": [
15311531
"threadStatus",
@@ -1548,7 +1548,7 @@
15481548
"defines": ["__ATTRP_C11_THREAD"]
15491549
},
15501550
{
1551-
"file": "../lib/libc/musl/src/internal/libc.h",
1551+
"file": "system/lib/libc/musl/src/internal/libc.h",
15521552
"structs": {
15531553
"libc": [
15541554
"global_locale"

tests/test_sanity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from tools.shared import EXPECTED_LLVM_VERSION, Cache
2222
from tools import shared, system_libs, utils
2323

24-
SANITY_FILE = shared.Cache.get_path('sanity.txt', root=True)
24+
SANITY_FILE = shared.Cache.get_path('sanity.txt')
2525
commands = [[EMCC], [PYTHON, path_from_root('tests', 'runner.py'), 'blahblah']]
2626

2727

tools/cache.py

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,9 @@ class Cache(object):
2323
# acquired.
2424
EM_EXCLUSIVE_CACHE_ACCESS = int(os.environ.get('EM_EXCLUSIVE_CACHE_ACCESS', '0'))
2525

26-
def __init__(self, dirname, use_subdir=True):
26+
def __init__(self, dirname):
2727
# figure out the root directory for all caching
2828
dirname = os.path.normpath(dirname)
29-
self.root_dirname = dirname
30-
31-
# if relevant, use a subdir of the cache
32-
if use_subdir:
33-
subdir = 'wasm'
34-
if shared.Settings.LTO:
35-
subdir += '-lto'
36-
if shared.Settings.RELOCATABLE:
37-
subdir += '-pic'
38-
if shared.Settings.MEMORY64:
39-
subdir += '-memory64'
40-
dirname = os.path.join(dirname, subdir)
41-
4229
self.dirname = dirname
4330
self.acquired_count = 0
4431

@@ -81,30 +68,56 @@ def ensure(self):
8168
def erase(self):
8269
self.acquire_cache_lock()
8370
try:
84-
if os.path.exists(self.root_dirname):
85-
for f in os.listdir(self.root_dirname):
86-
tempfiles.try_delete(os.path.join(self.root_dirname, f))
71+
if os.path.exists(self.dirname):
72+
for f in os.listdir(self.dirname):
73+
tempfiles.try_delete(os.path.join(self.dirname, f))
8774
finally:
8875
self.release_cache_lock()
8976

90-
def get_path(self, shortname, root=False):
91-
if root:
92-
return os.path.join(self.root_dirname, shortname)
93-
return os.path.join(self.dirname, shortname)
77+
def get_path(self, name):
78+
return os.path.join(self.dirname, name)
79+
80+
def get_sysroot_dir(self, absolute):
81+
if absolute:
82+
return os.path.join(self.dirname, 'sysroot')
83+
return 'sysroot'
84+
85+
def get_include_dir(self):
86+
return os.path.join(self.get_sysroot_dir(absolute=True), 'include')
87+
88+
def get_lib_dir(self, absolute):
89+
path = os.path.join(self.get_sysroot_dir(absolute=absolute), 'lib')
90+
if shared.Settings.MEMORY64:
91+
path = os.path.join(path, 'wasm64-emscripten')
92+
else:
93+
path = os.path.join(path, 'wasm32-emscripten')
94+
# if relevant, use a subdir of the cache
95+
subdir = []
96+
if shared.Settings.LTO:
97+
subdir.append('lto')
98+
if shared.Settings.RELOCATABLE:
99+
subdir.append('pic')
100+
if subdir:
101+
path = os.path.join(path, '-'.join(subdir))
102+
return path
103+
104+
def get_lib_name(self, name):
105+
return os.path.join(self.get_lib_dir(absolute=False), name)
94106

95107
def erase_file(self, shortname):
96108
name = os.path.join(self.dirname, shortname)
97109
if os.path.exists(name):
98110
logging.info('Cache: deleting cached file: %s', name)
99111
tempfiles.try_delete(name)
100112

113+
def getlib(self, libname, *args, **kwargs):
114+
name = self.get_lib_name(libname)
115+
return self.get(name, *args, **kwargs)
116+
101117
# Request a cached file. If it isn't in the cache, it will be created with
102118
# the given creator function
103-
def get(self, shortname, creator, what=None, force=False, root=False):
104-
if root:
105-
cachename = os.path.join(self.root_dirname, shortname)
106-
else:
107-
cachename = os.path.join(self.dirname, shortname)
119+
def get(self, shortname, creator, what=None, force=False):
120+
cachename = os.path.join(self.dirname, shortname)
108121
cachename = os.path.abspath(cachename)
109122
# Check for existence before taking the lock in case we can avoid the
110123
# lock completely.

tools/gen_struct_info.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def inspect_code(headers, cpp_opts, structs, defines):
246246
'-O0',
247247
'-Werror',
248248
'-Wno-format',
249+
'-I', shared.path_from_root(),
249250
'-s', 'BOOTSTRAPPING_STRUCT_INFO=1',
250251
'-s', 'WARN_ON_UNDEFINED_SYMBOLS=0',
251252
'-s', 'STRICT=1',

tools/ports/sdl2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def create():
8282
ports.create_lib(final, o_s)
8383
return final
8484

85-
return [shared.Cache.get(libname, create, what='port')]
85+
return [shared.Cache.getlib(libname, create, what='port')]
8686

8787

8888
def clear(ports, settings, shared):

tools/shared.py

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def check_sanity(force=False):
273273
return # config stored directly in EM_CONFIG => skip sanity checks
274274
expected = generate_sanity()
275275

276-
sanity_file = Cache.get_path('sanity.txt', root=True)
276+
sanity_file = Cache.get_path('sanity.txt')
277277
if os.path.exists(sanity_file):
278278
sanity_data = open(sanity_file).read()
279279
if sanity_data != expected:
@@ -420,9 +420,7 @@ def emsdk_ldflags(user_args):
420420
return []
421421

422422
library_paths = [
423-
path_from_root('system', 'local', 'lib'),
424-
path_from_root('system', 'lib'),
425-
Cache.dirname
423+
Cache.get_lib_dir(absolute=True)
426424
]
427425
ldflags = ['-L' + l for l in library_paths]
428426

@@ -437,12 +435,12 @@ def emsdk_ldflags(user_args):
437435
return ldflags
438436

439437

440-
def emsdk_cflags(user_args, cxx):
438+
def emsdk_cflags(user_args):
441439
# Disable system C and C++ include directories, and add our own (using
442440
# -isystem so they are last, like system dirs, which allows projects to
443441
# override them)
444442

445-
c_opts = ['--sysroot=' + path_from_root('system')]
443+
c_opts = ['--sysroot=' + Cache.get_sysroot_dir(absolute=True)]
446444

447445
def array_contains_any_of(hay, needles):
448446
for n in needles:
@@ -477,24 +475,8 @@ def array_contains_any_of(hay, needles):
477475

478476
sysroot_include_paths = []
479477

480-
if cxx:
481-
sysroot_include_paths += [
482-
os.path.join('/include', 'libcxx'),
483-
os.path.join('/lib', 'libcxxabi', 'include'),
484-
]
485-
486-
# TODO: Merge the cache into the sysroot.
487-
c_opts += ['-Xclang', '-isystem' + Cache.get_path('include')]
488-
489478
sysroot_include_paths += [
490479
os.path.join('/include', 'compat'),
491-
os.path.join('/include', 'libc'),
492-
os.path.join('/lib', 'libc', 'musl', 'arch', 'emscripten'),
493-
os.path.join('/local', 'include'),
494-
os.path.join('/include', 'SSE'),
495-
os.path.join('/include', 'neon'),
496-
os.path.join('/lib', 'compiler-rt', 'include'),
497-
os.path.join('/lib', 'libunwind', 'include'),
498480
]
499481

500482
def include_directive(paths):
@@ -511,7 +493,7 @@ def get_asmflags():
511493
return ['-target', get_llvm_target()]
512494

513495

514-
def get_cflags(user_args, cxx):
496+
def get_cflags(user_args):
515497
# Set the LIBCPP ABI version to at least 2 so that we get nicely aligned string
516498
# data and other nice fixes.
517499
c_opts = [# '-fno-threadsafe-statics', # disabled due to issue 1289
@@ -538,7 +520,7 @@ def get_cflags(user_args, cxx):
538520
if os.environ.get('EMMAKEN_NO_SDK') or '-nostdinc' in user_args:
539521
return c_opts
540522

541-
return c_opts + emsdk_cflags(user_args, cxx)
523+
return c_opts + emsdk_cflags(user_args)
542524

543525

544526
# Settings. A global singleton. Not pretty, but nicer than passing |, settings| everywhere
@@ -747,11 +729,6 @@ def asmjs_mangle(name):
747729
return name
748730

749731

750-
def reconfigure_cache():
751-
global Cache
752-
Cache = cache.Cache(config.CACHE)
753-
754-
755732
class JS(object):
756733
emscripten_license = '''\
757734
/**

0 commit comments

Comments
 (0)