Skip to content

Commit 61bbce7

Browse files
committed
gh-145219: Emscripten bld configurable directory & only clean Emscripten
Two small changes to the Emscripten build script: 1. Make clean only delete the parts of cross-build that are emscripten specific 2. Make the cross-build name configurable
1 parent 349639c commit 61bbce7

File tree

1 file changed

+55
-27
lines changed

1 file changed

+55
-27
lines changed

Tools/wasm/emscripten/__main__.py

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,24 @@
2424
CHECKOUT = EMSCRIPTEN_DIR.parent.parent.parent
2525
EMSCRIPTEN_VERSION_FILE = EMSCRIPTEN_DIR / "emscripten_version.txt"
2626

27-
CROSS_BUILD_DIR = CHECKOUT / "cross-build"
28-
NATIVE_BUILD_DIR = CROSS_BUILD_DIR / "build"
27+
DEFAULT_CROSS_BUILD_DIR = CHECKOUT / "cross-build"
2928
HOST_TRIPLE = "wasm32-emscripten"
3029

31-
DOWNLOAD_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "build"
32-
HOST_BUILD_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "build"
33-
HOST_DIR = HOST_BUILD_DIR / "python"
34-
PREFIX_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "prefix"
30+
31+
def get_build_paths(cross_build_dir=None):
32+
"""Compute all build paths from the given cross-build directory."""
33+
if cross_build_dir is None:
34+
cross_build_dir = DEFAULT_CROSS_BUILD_DIR
35+
cross_build_dir = Path(cross_build_dir)
36+
host_triple_dir = cross_build_dir / HOST_TRIPLE
37+
return {
38+
"cross_build_dir": cross_build_dir,
39+
"native_build_dir": cross_build_dir / "build",
40+
"host_triple_dir": host_triple_dir,
41+
"host_build_dir": host_triple_dir / "build",
42+
"host_dir": host_triple_dir / "build" / "python",
43+
"prefix_dir": host_triple_dir / "prefix",
44+
}
3545

3646
LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local"
3747
LOCAL_SETUP_MARKER = b"# Generated by Tools/wasm/emscripten.py\n"
@@ -115,12 +125,17 @@ def updated_env(updates, emsdk_cache):
115125
return environment
116126

117127

118-
def subdir(working_dir, *, clean_ok=False):
119-
"""Decorator to change to a working directory."""
128+
def subdir(path_key, *, clean_ok=False):
129+
"""Decorator to change to a working directory.
130+
131+
path_key is a key into context.build_paths, used to resolve the working
132+
directory at call time.
133+
"""
120134

121135
def decorator(func):
122136
@functools.wraps(func)
123137
def wrapper(context):
138+
working_dir = context.build_paths[path_key]
124139
try:
125140
tput_output = subprocess.check_output(
126141
["tput", "cols"], encoding="utf-8"
@@ -177,20 +192,21 @@ def build_platform():
177192
return sysconfig.get_config_var("BUILD_GNU_TYPE")
178193

179194

180-
def build_python_path():
195+
def build_python_path(context):
181196
"""The path to the build Python binary."""
182-
binary = NATIVE_BUILD_DIR / "python"
197+
native_build_dir = context.build_paths["native_build_dir"]
198+
binary = native_build_dir / "python"
183199
if not binary.is_file():
184200
binary = binary.with_suffix(".exe")
185201
if not binary.is_file():
186202
raise FileNotFoundError(
187-
f"Unable to find `python(.exe)` in {NATIVE_BUILD_DIR}"
203+
f"Unable to find `python(.exe)` in {native_build_dir}"
188204
)
189205

190206
return binary
191207

192208

193-
@subdir(NATIVE_BUILD_DIR, clean_ok=True)
209+
@subdir("native_build_dir", clean_ok=True)
194210
def configure_build_python(context, working_dir):
195211
"""Configure the build/host Python."""
196212
if LOCAL_SETUP.exists():
@@ -206,12 +222,12 @@ def configure_build_python(context, working_dir):
206222
call(configure, quiet=context.quiet)
207223

208224

209-
@subdir(NATIVE_BUILD_DIR)
225+
@subdir("native_build_dir")
210226
def make_build_python(context, working_dir):
211227
"""Make/build the build Python."""
212228
call(["make", "--jobs", str(cpu_count()), "all"], quiet=context.quiet)
213229

214-
binary = build_python_path()
230+
binary = build_python_path(context)
215231
cmd = [
216232
binary,
217233
"-c",
@@ -241,7 +257,7 @@ def download_and_unpack(working_dir: Path, url: str, expected_shasum: str):
241257
shutil.unpack_archive(tmp_file.name, working_dir)
242258

243259

244-
@subdir(HOST_BUILD_DIR, clean_ok=True)
260+
@subdir("host_build_dir", clean_ok=True)
245261
def make_emscripten_libffi(context, working_dir):
246262
ver = "3.4.6"
247263
libffi_dir = working_dir / f"libffi-{ver}"
@@ -253,13 +269,13 @@ def make_emscripten_libffi(context, working_dir):
253269
)
254270
call(
255271
[EMSCRIPTEN_DIR / "make_libffi.sh"],
256-
env=updated_env({"PREFIX": PREFIX_DIR}, context.emsdk_cache),
272+
env=updated_env({"PREFIX": context.build_paths["prefix_dir"]}, context.emsdk_cache),
257273
cwd=libffi_dir,
258274
quiet=context.quiet,
259275
)
260276

261277

262-
@subdir(HOST_BUILD_DIR, clean_ok=True)
278+
@subdir("host_build_dir", clean_ok=True)
263279
def make_mpdec(context, working_dir):
264280
ver = "4.0.1"
265281
mpdec_dir = working_dir / f"mpdecimal-{ver}"
@@ -275,7 +291,7 @@ def make_mpdec(context, working_dir):
275291
mpdec_dir / "configure",
276292
"CFLAGS=-fPIC",
277293
"--prefix",
278-
PREFIX_DIR,
294+
context.build_paths["prefix_dir"],
279295
"--disable-shared",
280296
],
281297
cwd=mpdec_dir,
@@ -289,14 +305,15 @@ def make_mpdec(context, working_dir):
289305
)
290306

291307

292-
@subdir(HOST_DIR, clean_ok=True)
308+
@subdir("host_dir", clean_ok=True)
293309
def configure_emscripten_python(context, working_dir):
294310
"""Configure the emscripten/host build."""
311+
paths = context.build_paths
295312
config_site = os.fsdecode(EMSCRIPTEN_DIR / "config.site-wasm32-emscripten")
296313

297314
emscripten_build_dir = working_dir.relative_to(CHECKOUT)
298315

299-
python_build_dir = NATIVE_BUILD_DIR / "build"
316+
python_build_dir = paths["native_build_dir"] / "build"
300317
lib_dirs = list(python_build_dir.glob("lib.*"))
301318
assert len(lib_dirs) == 1, (
302319
f"Expected a single lib.* directory in {python_build_dir}"
@@ -322,13 +339,13 @@ def configure_emscripten_python(context, working_dir):
322339
capture_output=True,
323340
)
324341
host_runner = res.stdout.strip()
325-
pkg_config_path_dir = (PREFIX_DIR / "lib/pkgconfig/").resolve()
342+
pkg_config_path_dir = (paths["prefix_dir"] / "lib/pkgconfig/").resolve()
326343
env_additions = {
327344
"CONFIG_SITE": config_site,
328345
"HOSTRUNNER": host_runner,
329346
"EM_PKG_CONFIG_PATH": str(pkg_config_path_dir),
330347
}
331-
build_python = os.fsdecode(build_python_path())
348+
build_python = os.fsdecode(build_python_path(context))
332349
configure = [
333350
"emconfigure",
334351
os.path.relpath(CHECKOUT / "configure", working_dir),
@@ -342,7 +359,7 @@ def configure_emscripten_python(context, working_dir):
342359
"--disable-ipv6",
343360
"--enable-big-digits=30",
344361
"--enable-wasm-dynamic-linking",
345-
f"--prefix={PREFIX_DIR}",
362+
f"--prefix={paths['prefix_dir']}",
346363
]
347364
if pydebug:
348365
configure.append("--with-pydebug")
@@ -403,7 +420,7 @@ def configure_emscripten_python(context, working_dir):
403420
sys.stdout.flush()
404421

405422

406-
@subdir(HOST_DIR)
423+
@subdir("host_dir")
407424
def make_emscripten_python(context, working_dir):
408425
"""Run `make` for the emscripten/host build."""
409426
call(
@@ -432,9 +449,10 @@ def build_all(context):
432449

433450
def clean_contents(context):
434451
"""Delete all files created by this script."""
435-
if CROSS_BUILD_DIR.exists():
436-
print(f"🧹 Deleting {CROSS_BUILD_DIR} ...")
437-
shutil.rmtree(CROSS_BUILD_DIR)
452+
host_triple_dir = context.build_paths["host_triple_dir"]
453+
if host_triple_dir.exists():
454+
print(f"🧹 Deleting {host_triple_dir} ...")
455+
shutil.rmtree(host_triple_dir)
438456

439457
if LOCAL_SETUP.exists():
440458
with LOCAL_SETUP.open("rb") as file:
@@ -489,6 +507,14 @@ def main():
489507
dest="quiet",
490508
help="Redirect output from subprocesses to a log file",
491509
)
510+
subcommand.add_argument(
511+
"--cross-build-dir",
512+
action="store",
513+
default=None,
514+
dest="cross_build_dir",
515+
help="Path to the cross-build directory "
516+
f"(default: {DEFAULT_CROSS_BUILD_DIR})",
517+
)
492518
subcommand.add_argument(
493519
"--emsdk-cache",
494520
action="store",
@@ -521,6 +547,8 @@ def main():
521547

522548
context = parser.parse_args()
523549

550+
context.build_paths = get_build_paths(context.cross_build_dir)
551+
524552
if context.emsdk_cache:
525553
validate_emsdk_version(context.emsdk_cache)
526554
context.emsdk_cache = Path(context.emsdk_cache).absolute()

0 commit comments

Comments
 (0)