Skip to content
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

Allow dynamic loading in musl builds while CPython itself is static #86

Open
achimnol opened this issue Aug 24, 2021 · 5 comments
Open
Labels
enhancement New feature or request

Comments

@achimnol
Copy link

achimnol commented Aug 24, 2021

I'd like to ship a few wheels including pre-built C modules along with the musl-based standalone Python from here.
When I try to run python -m ensurepip (e.g., #84) or any other imports that involves dynamic loading of C libraries (e.g., ctypes, pyzmq, etc.) then it exits with OSError: Dynamic loading not supported.

Could we have a musl-based static build that allows dynamic loading of additional non-standard modules?
It seems that 0d3ae2a has disabled the ability to use dynamic loading.

@indygreg
Copy link
Owner

When you produce a fully static ELF executable, you can't load dynamic libraries. That Dynamic loading not supported error is coming from the bowels of libc I believe.

Now, what we probably could do is produce a Python distribution that is dynamically linked against musl libc and the executable only has a dependency on musl. This should enable the distributions to load extensions that were also compiled to target musl libc.

We could potentially also include a placeholder shared library to force the resulting executable to be dynamic. Or maybe there's another way to force the linker into making the final executable dynamic.

Something to keep in mind here is once you support loading dynamic libraries, you have to worry about multiple libc versions being loaded. I believe musl - like glibc - is sensitive about multiple versions existing in the same process space. So we probably don't want to statically link musl and enable extensions to also statically link musl, as this is a recipe for disaster. Having a dynamically linked musl is probably the safest route here.

Out of curiosity, could you please explain your use case? Is this for better support for Alpine Linux and/or compatibility with the new platform tag for musl (https://discuss.python.org/t/pep-656-platform-tag-for-linux-distributions-using-musl/7165)?

@indygreg indygreg added the enhancement New feature or request label Sep 26, 2021
@achimnol
Copy link
Author

achimnol commented Oct 12, 2021

Thanks for the reply.
My use case is to mount and execute a Python program with self-contained runtime inside arbitrary Docker containers based on arbitrary images. So far, it's been successful with glibc-flavor of static Python builds and glibc-based Docker images (e.g., Ubuntu/CentOS based images). But for Alpine-based images, a dynamic version of Python build works as expected while no static version did work because of the library import issue.

I think there are two ways if it's not feasible to build static-musl version of Python with import capability:

  • Just use a dynamic version of Python which is built with sufficiently low version of Alpine Linux, to guarantee the musl compatibility with as many Alpine-based Docker images as possible.
    • I just wanted to avoid manually checking compatibility with arbitrary images by using the static version.
  • Embed all external Python packages into the "standard" library and build with the static Python.

indygreg added a commit that referenced this issue Oct 17, 2021
indygreg added a commit that referenced this issue Oct 17, 2021
@bigcat88
Copy link

bigcat88 commented Feb 18, 2022

@indygreg can I help you anything to make musl dynamic build possible for x64 - aarch64?
Familiar with this(not with musl\Alpine itself, but with linkers and compilers), can try clone your repo and do that.
If you just point me in right direction. :)

As I understand I need:

  1. Find a docker image(or build and publish one with lowest musl version)
  2. Change linker(and i think some preprocessor) flags from static to dynamic(what to change will be great to know, but not necessary)
  3. Write an GitHub action for that(like you do)

And not related question:
my friend and i currently developing an open source project where we will use your python standalone, and we need to include some additional python packages in it, that not providing a binary wheels. We plan to do that in GitHub actions and remove all except install and licenses folder and add your License file to it. Do we need to include some additional info(except a link to your project on a main project readme page). Example: alpha_repack

@andrey18106
Copy link

Hi!
When will dynamic Python standalone be available on Alpine 3.13+?

@bpcreech
Copy link

bpcreech commented Mar 5, 2024

Just piping* up with another use case:

Using Hatch to run Python matrix tests, for wheels built on Alpine. Hatch uses python-build-standalone for this, plus pip to download wheels.

Here is what it looks like when you try that today. pip fails, just like Joongi said.

I see this patch, patch-pip-static-binary.patch, fixes the site-packages/pip which is bundled with the python-build-standalone distro, but that doesn't help because Python now runs the bundled pip wheel in lib/python3.12/ensurepip/_bundled/pip-24.0-py3-none-any.whl which does not have that patch.

Note that it's not just code that directly uses ctypes which is broken, but basically any use of pip, including hauling in deps for matrix testing.

One could also upstream patch-pip-static-binary.patch to pip. I think that would fix pip (and thus Hatch's matrix testing would work) but it wouldn't help for code under test which actually uses ctypes (which happens to include my use case anyway).

(*piping up, not pip-ing up, because I can't pip. Sorry, bad pip joke.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants