Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

bpo-41100: ctypes fixes for arm64 Mac OS#21249

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

@lawrence-danna-apple
Copy link
Contributor

@lawrence-danna-applelawrence-danna-apple commentedJul 1, 2020
edited
Loading

Posted in response to this comment by Ronald#21242 (comment)

This PR would supersede these two, combining because the third commit depends on both

This has three commits:

  • ctypes: use the correct ABI for variadic functions
  • use system libffi for Mac OS 10.15 and up
  • setup.py: probe libffi for ffi_closure_alloc and ffi_prep_cif_var

The first two are from those previous PRs. The third makessetup.py probe for those functions by searching libffi's headers.

https://bugs.python.org/issue41100

This updates setup.py to default to the system libffi on Mac OS 10.15 and forward.   It also updatesdetect_ctypes to prefer finding libffi in the Xcode SDK, rather than /usr/include
On arm64 the calling convention for variardic functions is differentthan the convention for fixed-arg functions of the same arg types.ctypes needs to use ffi_prep_cif_var to tell libffi which callingconvention to use.
SMillerDev pushed a commit to Homebrew/homebrew-core that referenced this pull requestJul 4, 2020
This set of patches includes the following upstream pull requests:-python/cpython#21114  "Support `arm64` in Mac/Tools/pythonw"-python/cpython#21224  "allow python to build for macosx-11.0-arm64"-python/cpython#21249  "ctypes fixes for arm64 Mac OS"Adding the patches before upstream has released them is warranted herebecause `python@3.8` is widely used as a dependency, and the patch isneeded to enable testing dependent formulae on arm64.CC: Sean Molenaar <1484494+SMillerDev@users.noreply.github.com>
@maxbelanger
Copy link
Contributor

@lawrence-danna-apple We currently redistributelibffi along with Python to support Mac OS X 10.10 as our deployment target. Your change implies that there were changes made tolibffi (and the copy that ships with macOS 11) for arm64 macOS. Are these upstreamed and available?

@lawrence-danna-apple
Copy link
ContributorAuthor

@lawrence-danna-apple We currently redistributelibffi along with Python to support Mac OS X 10.10 as our deployment target. Your change implies that there were changes made tolibffi (and the copy that ships with macOS 11) for arm64 macOS. Are these upstreamed and available?

We also distributelibffi as part of Mac OS. Our changes for 10.15, which cover the necessary API changes are available here:https://opensource.apple.com/source/libffi/libffi-25/

I'm not sure what the status is as to upstreaming, but I'll do a review of it and see if anything necessary is still missing from upstream.

Noe that in the changes I'm proposing here, the Mac OS systemlibffi is only used if the deployment target is set to 10.15 or better.

@maxbelanger
Copy link
Contributor

@lawrence-danna-apple We currently redistributelibffi along with Python to support Mac OS X 10.10 as our deployment target. Your change implies that there were changes made tolibffi (and the copy that ships with macOS 11) for arm64 macOS. Are these upstreamed and available?

We also distributelibffi as part of Mac OS. Our changes for 10.15, which cover the necessary API changes are available here:https://opensource.apple.com/source/libffi/libffi-25/

I'm not sure what the status is as to upstreaming, but I'll do a review of it and see if anything necessary is still missing from upstream.

Noe that in the changes I'm proposing here, the Mac OS systemlibffi is only used if the deployment target is set to 10.15 or better.

Got it, thanks for clarifying. It looks like there may be some issues inlibffi w/ XC12 + arm64:libffi/libffi#571. Good to know that we could rely onlibffi-25, though.

Co-authored-by: Arch Oversight <archoversight@gmail.com>
Copy link
Contributor

@ronaldoussorenronaldoussoren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@lawrence-danna-apple We currently redistributelibffi along with Python to support Mac OS X 10.10 as our deployment target. Your change implies that there were changes made tolibffi (and the copy that ships with macOS 11) for arm64 macOS. Are these upstreamed and available?

Isn't it possible/save to use the system libffi on 10.9 or later? The 10.9 SDK includes libffi, even if it uses an older API (just like libffi_osx in the CPython tree).

I'd prefer to drop the copy of libffi included with CPython and always use the system libffi, without including a copy of libffi in the installers for macOS.

@ronaldoussoren
Copy link
Contributor

I'm a bit conflicted about the "variadic" attribute for _FuncPtr. I agree that it is necessary, but this is an API change and as such is a lot harder to back port.

@lawrence-danna-apple
Copy link
ContributorAuthor

lawrence-danna-apple commentedJul 14, 2020
edited
Loading

I'd prefer to drop the copy of libffi included with CPython and always use the system libffi

I'm not sure if this is possible. The libffi prior to 10.15 won't have the APIs we need to support arm64. However, we may be able to use ifdefs and availability to sort it out. I'll try.

Do you know why libffi was bundled into cpython in the first place? Do we have reason to believe the libffi on older releases of mac OS was broken in some way?

claui added a commit to Homebrew/formula-patches that referenced this pull requestJul 15, 2020
This set of patches includes the following upstream pull requests,in this order:- PR 20171, "Fix _tkinter use"python/cpython#20171  (prerequisite for patch #21249 to apply)- PR 21114, "Support `arm64` in Mac/Tools/pythonw"python/cpython#21114- PR 21224, "allow python to build for macosx-11.0-arm64"python/cpython#21224- PR 21249, "ctypes fixes for arm64 Mac OS"python/cpython#21249The patches for 20171 and 21249 have been minimally modified in orderto backport them to 3.8.3.Note that these have been successfully tested for `python@3.8`but not for `python@3.7`.The patch directive should be surrounded by an `if Hardware::CPU.arm?`block.
claui pushed a commit to xvilo/homebrew-core that referenced this pull requestJul 15, 2020
This replaces the three unmerged PR patches with a hostedformula patch.This includes the following upstream pull requests:-python/cpython#20171, "Fix _tkinter use" (prerequisite for 21249)-python/cpython#21114, "Support arm64 in Mac/Tools/pythonw"-python/cpython#21224, "allow python to build for macosx-11.0-arm64"-python/cpython#21249, "ctypes fixes for arm64 Mac OS"See also:-Homebrew/formula-patches#292
@lawrence-danna-apple
Copy link
ContributorAuthor

@ronaldoussoren

I'm a bit conflicted about the "variadic" attribute for _FuncPtr. I agree that it is necessary

Well, it looks like I misread the documentation. It turns out that in the case where a variadic function is called with zero variadic arguments, the two calling conventions coincide. So the flag is not necessary after all.

@lawrence-danna-apple
Copy link
ContributorAuthor

lawrence-danna-apple commentedJul 15, 2020
edited
Loading

@ronaldoussoren

I found it is possible to use the system libffi even if the deployment target is set to before 10.15. I've added runtime checks forffi_prep_cif_var,ffi_prep_closure_loc andffi_closure_alloc. If they are present, it will use them. If not, it will fall back on the old way of doing things.

I've also enabled the system ffi if either the deployment target is 10.15 OR the arm64 is in the target arches. I'm not sure if Mac OS on PPC is still supported by python, but these changes shouldn't break it if it is.

The only thing that will not work is to build a super-fat binary that works on ppc, x86 and arm64 at the same time.

Should I add a commit deletinglibffi_osx altogether, or leave it in for ppc support?

BrewTestBot pushed a commit to Homebrew/homebrew-core that referenced this pull requestJul 16, 2020
This replaces the three unmerged PR patches with a hostedformula patch.This includes the following upstream pull requests:-python/cpython#20171, "Fix _tkinter use" (prerequisite for 21249)-python/cpython#21114, "Support arm64 in Mac/Tools/pythonw"-python/cpython#21224, "allow python to build for macosx-11.0-arm64"-python/cpython#21249, "ctypes fixes for arm64 Mac OS"See also:-Homebrew/formula-patches#292Closes#57997.Signed-off-by: Claudia Pellegrino <1239874+claui@users.noreply.github.com>
Copy link
Member

@ned-deilyned-deily left a comment
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

As a smoke test, I tried building with--with-system-ffi on macOS 10.9 and ran into the issue that__builtin_available is apparently not available untilXcode 9.0onmacOS 10.12 and it is a requirement that we can continue to be built on older systems with their supported Xcode versions. I founda workaround from the curl project that might be usable here if we need to support using the system libffi which would be desirable.

Also we should avoid the potential pragma warnings when building on other platforms.

result=ffi_prep_closure(p->pcl_write,&p->cif,closure_fcn,p);
#ifHAVE_FFI_PREP_CLOSURE_LOC
# ifUSING_APPLE_OS_LIBFFI
# defineHAVE_FFI_PREP_CLOSURE_LOC_RUNTIME __builtin_available(macos 11, ios 13, watchos 6, tvos 13, *)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

__builtin_available is itself not available with older versions of macOS and Xcode, in particular with macOS 10.9 and Xcode 6, which we currently need to use to build our most common installer variants. And there are other projects like MacPorts that builds Python for older macOS systems. The general review comment has a link for a possible workaround from the curl project.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This use of __builtin_available should be safe, it is within a guard of HAVE_FFI_PREP_CLOSURE_LOC and USING_APPLE_OS_LIBFFI: The system version of libffi does not have ffi_prep_closure_loc in the 10.9 SDK (it is introduced in 10.15).

return-1;

# ifUSING_APPLE_OS_LIBFFI
# defineHAVE_FFI_PREP_CIF_VAR_RUNTIME __builtin_available(macos 11, ios 13, watchos 6, tvos 13, *)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

__builtin_available again

voidPy_ffi_closure_free(void*p)
{
#ifUSING_APPLE_OS_LIBFFI
if (__builtin_available(macos11,ios13,watchos6,tvos13,*)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

__builtin_available again

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm afraid this needs a configure test, ffi_closure_free is not available at all in older SDKs.

void*Py_ffi_closure_alloc(size_tsize,void**codeloc)
{
#ifUSING_APPLE_OS_LIBFFI
if (__builtin_available(macos11,ios13,watchos6,tvos13,*)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

__builtin_available again

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

same here

p,
p->pcl_exec);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ditto

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
result=ffi_prep_closure(p->pcl_write,&p->cif,closure_fcn,p);
#pragma clang diagnostic pop
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ditto

result=ffi_prep_closure_loc(p->pcl_write,&p->cif,closure_fcn,
p,
p->pcl_exec);
#pragma clang diagnostic push
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We should avoid-Wunknown-pragmas warnings when building on other platforms.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

fixed

@bedevere-bot
Copy link

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 phraseI have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Copy link
Contributor

@ronaldoussorenronaldoussoren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I've added some comments, and am finally working on this PR on the DTK.

Armenm reacted with thumbs up emoji
result=ffi_prep_closure(p->pcl_write,&p->cif,closure_fcn,p);
#ifHAVE_FFI_PREP_CLOSURE_LOC
# ifUSING_APPLE_OS_LIBFFI
# defineHAVE_FFI_PREP_CLOSURE_LOC_RUNTIME __builtin_available(macos 11, ios 13, watchos 6, tvos 13, *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This use of __builtin_available should be safe, it is within a guard of HAVE_FFI_PREP_CLOSURE_LOC and USING_APPLE_OS_LIBFFI: The system version of libffi does not have ffi_prep_closure_loc in the 10.9 SDK (it is introduced in 10.15).


Returns the object to which to pointer points. Assigning to this
attribute changes the pointer to point to the assigned object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Unnecessary removal of a blank line (not important)

result=ffi_prep_closure(p->pcl_write,&p->cif,closure_fcn,p);
#ifHAVE_FFI_PREP_CLOSURE_LOC
# ifUSING_APPLE_OS_LIBFFI
# defineHAVE_FFI_PREP_CLOSURE_LOC_RUNTIME __builtin_available(macos 11, ios 13, watchos 6, tvos 13, *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Why test for macOS 11 and not 10.15? According to the header files this API is introduced in 10.15.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

you're right it should be 10.15

return-1;

# ifUSING_APPLE_OS_LIBFFI
# defineHAVE_FFI_PREP_CIF_VAR_RUNTIME __builtin_available(macos 11, ios 13, watchos 6, tvos 13, *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Likewise: the headers claim this _var variant is present in macOS 10.15.

"ffi_prep_cif failed");
return-1;

# ifUSING_APPLE_OS_LIBFFI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Proposed change:

#if USING_APPLE_OS_LIBFFI && HAVE_FFI_PREP_CIF_VAR

This way the __builtin_available is not used when building on older macOS versions.

voidPy_ffi_closure_free(void*p)
{
#ifUSING_APPLE_OS_LIBFFI
if (__builtin_available(macos11,ios13,watchos6,tvos13,*)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm afraid this needs a configure test, ffi_closure_free is not available at all in older SDKs.

void*Py_ffi_closure_alloc(size_tsize,void**codeloc)
{
#ifUSING_APPLE_OS_LIBFFI
if (__builtin_available(macos11,ios13,watchos6,tvos13,*)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

same here

self.use_system_libffi=True
else:
self.use_system_libffi='--with-system-ffi'insysconfig.get_config_var("CONFIG_ARGS")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'd prefer to just drop "use_system_libffi" and unconditionally use the system headers.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ok

ronaldoussoren added a commit to ronaldoussoren/cpython that referenced this pull requestJul 20, 2020
This is support for ctypes on macOS/arm64 basedon PR 21249 by Lawrence D'Anna (Apple).Changes:- changed __builtin_available tests from 11.0 to 10.15- added test to setup.py for ffi_closure_alloc and use  that in malloc_closure.c- Minor change in the code path for ffi_prep_closure_var  (coding style change)
@lawrence-danna-apple
Copy link
ContributorAuthor

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@ned-deily: please review the changes made to this pull request.

@lawrence-danna-apple
Copy link
ContributorAuthor

@ned-deily

Your comments have alerted me to a new problem. If I understand you correctly, the way you're doing the official builds for python is to build on an old version of Mac OS, with an old version of Xcode, in order to assure compatibility with a broad range of Mac OS versions.

This will work for x86_64, but if you want a universal build that works on both 10.10 and 11.0-arm64, it will not work, becaue the old Xcode doesn't support arm64 for Mac OS

On the other hand, if you build with the new Xcode using MACOSX_DEPLOYMENT_TARGET=10.10, that also does not work on 10.10, because autoconf will discover several functions such asgetentropy which are available in the SDK, but are not available at runtime on 10.10. This will cause-Wunguarded-availability warnings in the build and an abort at runtime if the symbol is used.

@maxbelanger
Copy link
Contributor

@lawrence-danna-apple quite right. This has been an issue for us at Dropbox in recent years. Python's official approach for backwards compatibility is not based on setting the deployment target, which is problematic for use in client-side software. We've fixed this internally by patchingpyconfig.h, but that's not a great fix (ideally we could do something like weak-link them).

Seehttps://bugs.python.org/issue31359.

@lawrence-danna-apple
Copy link
ContributorAuthor

lawrence-danna-apple commentedJul 21, 2020
edited
Loading

@maxbelanger@ned-deily

I opened up a new PR to deal with the deployment target issue.

#21576
#21577

@ned-deily
Copy link
Member

Thanks for the PR. We are aware of the issues with supporting multiple levels and architectures Being able to weaklink from a build on a newer version to an older version has been desirable but it hasn't been a high priority issue. Actively supporting multiple architectures again (something we haven't had to do since the retirement of PPC :) makes this a higher priority issue and@ronaldoussoren is now working on it. I've added him to the reviewers of the new PR (#21577).

Comment on lines +2153 to +2154
ext.extra_compile_args.append("-DUSING_APPLE_OS_LIBFFI=1")
ffi_in_sdk=os.path.join(macosx_sdk_root(),"usr/include/ffi")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Please bear in mind that Python may be built against an external libffi on macOS that is not the OS-provided version. In MacPorts we build against our port of libffi 3.3 on all OS versions.

Copy link
ContributorAuthor

@lawrence-danna-applelawrence-danna-appleSep 20, 2020
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

See previous comment by@ronaldoussoren who prefers to unconditionally use the system's libffi. I updated this PR accordingly. Is there any reason not to use the system libffi anymore? I tested going back to 10.10 i think for the other PR adding availability checks. What's the need to support alternative libffi these days?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Same reasons as any other library: the OS often ships an older version which naturally lacks the features and bug fixes of later versions.

@ned-deily
Copy link
Member

Thanks for the PR. It has been included in and superseded byGH-22855.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@ronaldoussorenronaldoussorenronaldoussoren left review comments

@ned-deilyned-deilyAwaiting requested review from ned-deily

+2 more reviewers

@jmrootjmrootjmroot left review comments

@archoversightarchoversightarchoversight left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

8 participants

@lawrence-danna-apple@maxbelanger@ronaldoussoren@bedevere-bot@ned-deily@jmroot@archoversight@the-knights-who-say-ni

[8]ページ先頭

©2009-2025 Movatter.jp