-
-
Notifications
You must be signed in to change notification settings - Fork 31k
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
bpo-44689: ctypes.util.find_library() now finds macOS 11+ system libraries when built on older macOS systems #27251
Conversation
…ache_contains_path Fix tests
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA). Recognized GitHub usernameWe couldn't find a bugs.python.org (b.p.o) account corresponding to the following GitHub usernames: This might be simply due to a missing "GitHub Name" entry in one's b.p.o account settings. This is necessary for legal reasons before we can look at this contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. You can check yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
Since this PR suggests changes to code that was merged in #22855, I'd love a review from @ronaldoussoren |
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'll leave the technical review to Ronald, but I've left some remarks regarding code style (PEP 7).
BTW, did you read the discussion in GH-21241 regarding _dyld_shared_cache_contains_path
?
Misc/NEWS.d/next/macOS/2021-07-20-22-27-01.bpo-44689.mmT_xH.rst
Outdated
Show resolved
Hide resolved
Thanks a lot for the feedback @erlend-aasland - and for linking the discussion about _dyld_shared_cache_contains_path. Do you know if there a VSCode plugin for checking or auto-formatting C code according to PEP 7? I discussed a bit with Ronald on the issue linked to this PR, and he made me realize that using dlopen to check for library existence is not a good idea because it can have side effects. A shared library can execute arbitrary code when opened with dlopen. This is why _dyld_shared_cache_contains_path is currently being used instead. Instead of checking for _dyld_shared_cache_contains_path at compile time - it is possible to resolve it at run-time (dynamic loading) - and provide a fallback function which always returns false if the symbol does not exist. Then it won't matter whether the compilation happened on Catalina or Big Sur. I'll make an attempt at implementing this over the next few days. |
…tains_path at runtime instead of compile time. (pythonGH-27251)
Co-authored-by: Erlend Egeberg Aasland <[email protected]>
Sorry, I do not; I don't use VSCode, I use Vim. |
I would like to see this merged too, because having custom build of cpython in nix is a bit pain - some functions are private and has to be copy-pasted. |
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.
Thanks for the updated PR. Please see my recent detailed response on the bug tracker issue for comments that apply to this version.
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 |
…mic loading when compiling on MacOS < 11
I have made the requested changes; please review again |
Thanks for making the requested changes! @ned-deily: please review the changes made to this pull request. |
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.
The PR looks good to me, from staring at the code. I have not yet tried building on an older macOS version and running tests on Big Sur.
I will review and test it next week. |
Thanks @bergkvist for the PR, and @ned-deily for merging it 🌮🎉.. I'm working now to backport this PR to: 3.8, 3.9, 3.10. |
@ned-deily: Please replace |
…aries when built on older macOS systems (pythonGH-27251) Previously, when built on older macOS systems, `find_library` was not able to find macOS system libraries when running on Big Sur due to changes in how system libraries are stored. (cherry picked from commit 71853a7) Co-authored-by: Tobias Bergkvist <[email protected]>
GH-28052 is a backport of this pull request to the 3.10 branch. |
GH-28053 is a backport of this pull request to the 3.9 branch. |
GH-28054 is a backport of this pull request to the 3.8 branch. |
…aries when built on older macOS systems (pythonGH-27251) Previously, when built on older macOS systems, `find_library` was not able to find macOS system libraries when running on Big Sur due to changes in how system libraries are stored. (cherry picked from commit 71853a7) Co-authored-by: Tobias Bergkvist <[email protected]>
…aries when built on older macOS systems (GH-27251) (GH-28054) Previously, when built on older macOS systems, `find_library` was not able to find macOS system libraries when running on Big Sur due to changes in how system libraries are stored. (cherry picked from commit 71853a7) Co-authored-by: Tobias Bergkvist <[email protected]>
…aries when built on older macOS systems (GH-27251) (GH-28053) Previously, when built on older macOS systems, `find_library` was not able to find macOS system libraries when running on Big Sur due to changes in how system libraries are stored. (cherry picked from commit 71853a7) Co-authored-by: Tobias Bergkvist <[email protected]>
…aries when built on older macOS systems (GH-27251) Previously, when built on older macOS systems, `find_library` was not able to find macOS system libraries when running on Big Sur due to changes in how system libraries are stored. (cherry picked from commit 71853a7) Co-authored-by: Tobias Bergkvist <[email protected]>
Improve binary portability between MacOS versions
https://bugs.python.org/issue44689
When compiling CPython using a MacOS Catalina build server, it won't work as expected when trying to run it on MacOS Big Sur. In particular,
ctypes.util.find_library(name)
will always return None. This PR adds support for compiling on an older MacOS version.Background
Checking if a shared library exists on MacOS Big Sur is no longer possible by looking at the file system. Instead, Apple recommends the use of dlopen to check if a shared library exists (MacOS Big Sur 11.0.1 changenotes). Note that using dlopen to check for library existence is not ideal, since this might cause arbitrary side effects.
_dyld_shared_cache_contains_path and build time requirements
The current solution (introduced in #22855) to make find_library work on MacOS Big Sur does not use dlopen, but rather _dyld_shared_cache_contains_path from
#include <mach-io/dyld>
. This function/symbol is only available on MacOS Big Sur, meaning it will only be included if you compile CPython on MacOS Big Sur.In other words, if we compile CPython on MacOS Catalina, and move the binary to MacOS Big Sur,
from _ctypes import _dyld_shared_cache_contains_path
will raise an ImportError - and find_library will not work, always returning None.Method/Verification
In order to support building for MacOS >= 11.0 (Big Sur or later) with a build server running MacOS < 11.0 (Catalina or earlier), we use dynamic loading to avoid errors when compiling. _dyld_shared_cache_contains_path will be resolved at runtime instead of compile-time, since it is not available at compile-time in this case.
The downside to doing this at runtime instead of compile-time is that the compiler won't give us useful error messages. This is why we want to keep using the weak linking approach when compiling on MacOS >= 11.0 (Big Sur or later) - and only use dynamic loading to support the deprecated use case of compiling on an older MacOS version.
To test that this works, I've set up 2 virtual machines using OSX-KVM on a Manjaro Linux host:
Files are copied between the 2 virtual machines using rsync:
Checks
/usr/local/*
over to BigSur, and callfind_library('c')
Results
Before this change:
❌ Compile on Catalina and install, copy
/usr/local/*
over to BigSur, and callfind_library('c')
After this change:
✔️ Compile on Catalina and install, copy
/usr/local/*
over to BigSur, and callfind_library('c')
Related issues/Symptoms of the issue
Note that some of these are closed due to the symptom having been treated - rather than the underlying cause.
https://bugs.python.org/issue44689