-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-124932: Cross builds: Distinguish build prefix from host prefix #124933
base: main
Are you sure you want to change the base?
Conversation
…ost prefix In Emscripten and wasi builds, and presumably for other cross builds, the build file system and the host file system look different. For instance, we may want to install into `cross-build/$TARGET/lib` and then mount that as `/lib` in the host file system. `wasi.py` has to mess around with setting `PYTHONPATH` because `prefix` is set to a path from the build machine. It would simplify this if we distinguish between: * `prefix` -- the path in the build file system where we want to install the files * `host_prefix` -- the path in the host file system where getpath.c will look for the files And similarly for `exec_prefix` and `host_exec_prefix`.
I think the issue title is a bit misleading as this is only for WASI and Emscripten (which isn't officially tier 3 again yet). |
if test -z "$host_prefix"; then | ||
AS_CASE([$ac_sys_system], | ||
[Emscripten], [host_prefix=/], | ||
[WASI], [host_prefix=/], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tried the PR out, but won't this forcibly anchor a WASI build to mount lib
at /
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I presume the WASI situation is more akin to the iOS/Android case, where the runtime mount point depends on how/where the code is running, rather than knowing ahead of time that the code will be installed at a known fixed mount point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it seems to me it would be better to have it default to /
or /usr
than to /buildmachine/path/to/checkout/of/cpython/cross-build/wasm32-wasi
. If it's only known at runtime, we can control that by setting the PYTHONHOME
environment variable or from the C api by setting the path directly. This only controls the final fallback case for determining the prefix
, so it would also be possible to fix it by giving a value for program_name
that makes sense in the file system visible to Python. Leaving this set based on the install target on the build machine doesn't seem that likely to be helpful in my opinion.
But I would also be perfectly happy to leave it with the default value in all cases, it is just nice to have the option of overriding it with a configure
argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it seems to me it would be better to have it default to
/
or/usr
than to/buildmachine/path/to/checkout/of/cpython/cross-build/wasm32-wasi
.
That's entirely a checkout thing and not a release thing. For instance, to package up the code, I copy that file to the right place. So that's why I'm asking if it only impacts a checkout or not as you can currently mount the files anywhere inside the WASI host and everything works since Python looks from the file location up for lib/python3.NN
. As long as that keeps working then I'm fine with the change.
This only controls the final fallback case for determining the
prefix
, so it would also be possible to fix it by giving a value forprogram_name
that makes sense in the file system visible to Python.
This makes it sound like it won't break the case I want to preserve since step 5 in getpath.py
will override:
Lines 143 to 147 in f474391
# Step 5. Try to find prefix and exec_prefix relative to executable_dir, | |
# backtracking up the path until it is exhausted. This is the most common | |
# step to succeed. Note that if prefix and exec_prefix are different, | |
# exec_prefix is more likely to be found; however if exec_prefix is a | |
# subdirectory of prefix, both will be found. |
As such, I'm good with the change, although if this is to help with wasi.py
can that also be updated as a test case in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As such, I'm good with the change, although if this is to help with wasi.py can that also be updated as a test case in this PR?
Yeah I'll try it out and see if it works the way I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not work the way I thought: wasi.py
is mounting the checkout root into the wasi file system and using step 3 from getpath.py
to run Python from the source checkout directory. The source checkout is clean so it's necessary to adjust the PYTHONPATH
so that we pick up the sysconfigdata
.
https://github.com/python/cpython/blob/main/Modules/getpath.py#L128-L135
But if I set --prefix={wasi_build_dir}
, run make commoninstall
instead of make all
, and mount the wasi_build_dir/lib
to /lib
then this change helps. I'll push these changes to this branch to wasi.py
to demonstrate and we can either keep them or revert them as you prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed the ability to differentiate between build-time and run-time general capability would be useful in other cross-build situations (notably, iOS and Android). One Q to resolve inline about WASI support; there's also a need for a NEWS entry.
if test -z "$host_prefix"; then | ||
AS_CASE([$ac_sys_system], | ||
[Emscripten], [host_prefix=/], | ||
[WASI], [host_prefix=/], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I presume the WASI situation is more akin to the iOS/Android case, where the runtime mount point depends on how/where the code is running, rather than knowing ahead of time that the code will be installed at a known fixed mount point?
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need clarification on the use of commoninstall
as a make
target.
@@ -264,7 +257,7 @@ def configure_wasi_python(context, working_dir): | |||
@subdir(lambda context: CROSS_BUILD_DIR / context.host_triple) | |||
def make_wasi_python(context, working_dir): | |||
"""Run `make` for the WASI/host build.""" | |||
call(["make", "--jobs", str(cpu_count()), "all"], | |||
call(["make", "--jobs", str(cpu_count()), "commoninstall"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this (attempt to) trigger an install of Python itself?
Lines 2220 to 2222 in fca5529
commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ | |
altbininstall libinstall inclinstall libainstall \ | |
sharedinstall altmaninstall @FRAMEWORKALTINSTALLLAST@ |
That doesn't seem quite right to be triggering here as we aren't doing an install. For instance, commoninstall
includes altbininstall
which is used to install the interpreter:
Lines 2248 to 2251 in fca5529
# Install the interpreter with $(VERSION) affixed | |
# This goes into $(exec_prefix) | |
.PHONY: altbininstall | |
altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ |
Are you doing this to get sysconfig
copied to lib/
since the install commands blindly copy what's in that directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think doing an install in CI is good (as opposed to running the source directory) because I think downstream users are likely to want to do an install themselves. The CI is the most authoritative reference on how things should work for the downstream so in absence of other more important factors it's nice to make it helpful.
Because I set --prefix={working_dir}
in the call to configure, it's installing into the build directory. Which is a bit sloppy but it works.
But what's actually needed here is that commoninstall
implies libinstall
and sharedinstall
.
libinstall
copies $CHECKOUT/Lib
to $BUILDDIR/lib
and also copies the sysconfigdata into lib
here:
Lines 2620 to 2621 in 21c04e1
$(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py \ | |
$(DESTDIR)$(LIBDEST); \ |
The other target that we use is sharedinstall
which makes a lib-dynload
folder and prevents getpath.py
from printing 'Could not find platform dependent libraries <exec_prefix>'
. This message is harmless, but it's nice to suppress it.
In Emscripten and wasi builds, and presumably for other cross builds, the build file system and the host file system look different. For instance, we may want to install into
cross-build/$TARGET/lib
and then mount that as/lib
in the host file system.wasi.py
has to mess around with settingPYTHONPATH
becauseprefix
is set to a path from the build machine. It would simplify this if we distinguish between:prefix
-- the path in the build file system where we want to install the fileshost_prefix
-- the path in the host file system where getpath.c will look for the filesAnd similarly for
exec_prefix
andhost_exec_prefix
.