X Tutup
The Wayback Machine - https://web.archive.org/web/20250605003025/https://github.com/python/cpython/pull/23523
Skip to content

gh-86642: Allow cross compiling on darwin #23523

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

isuruf
Copy link
Contributor

@isuruf isuruf commented Nov 26, 2020

This was used for providing macos-arm64 builds for conda where we are using cross compiling exclusively for all macos-arm64 builds

https://bugs.python.org/issue42476

@isuruf isuruf changed the title bpo42476: Allow cross compiling on darwin bpo-42476: Allow cross compiling on darwin Nov 26, 2020
Copy link
Contributor

@ronaldoussoren ronaldoussoren left a comment

Choose a reason for hiding this comment

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

Please add documentation on how to cross build, without that it is hard to review this PR. This would preferably added to Mac/README.rst. In particular, I get the impression that cross building involves more than just specifying the target tuple to the configure script.

The change to platform.py is not acceptable as this affects a lot more than just the build. A random script using the platform module shouldn't get different answers when SDKROOT is present in the environment.

And out of interest: Why are you cross building to arm64? The build supports universal2 binaries out of the box, which run on both mac architectures and don't require cross compiling.

Lib/platform.py Outdated
@@ -409,7 +409,12 @@ def win32_ver(release='', version='', csd='', ptype=''):
def _mac_ver_xml():
fn = '/System/Library/CoreServices/SystemVersion.plist'
if not os.path.exists(fn):
return None
if 'SDKROOT' in os.environ:
Copy link
Contributor

Choose a reason for hiding this comment

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

This affects more than just the build. Why is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To install wheels when cross-compiling, this is needed to make sure wheels know what platform that it is targetting.
Setting SDKROOT is supported by clang and I thought python should support that too. I can remove it and figure out a way to monkeypatch it if you think it is too controversial.

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 -1 on this particular change, see also my latest comment in the main discussion.

configure.ac Outdated
@@ -437,6 +437,18 @@ if test "$cross_compiling" = yes; then
_host_cpu=$host_cpu
esac
;;
*-*-darwin*)
case "$host_cpu" in
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are there two cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review. Fixed now.

setup.py Outdated
@@ -62,7 +62,7 @@ def get_platform():
HOST_PLATFORM = get_platform()
MS_WINDOWS = (HOST_PLATFORM == 'win32')
CYGWIN = (HOST_PLATFORM == 'cygwin')
MACOS = (HOST_PLATFORM == 'darwin')
MACOS = (HOST_PLATFORM.startswith('darwin'))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this change needed? HOST_PLATFORM will be darwin on macOS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

HOST_PLATFORM is set to _PYTHON_HOST_PLATFORM which will be darwin-arm64 when cross compiling.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok.

configure.ac Outdated
@@ -2480,7 +2481,8 @@ case $ac_sys_system/$ac_sys_release in
}
]])],[ac_osx_32bit=yes],[ac_osx_32bit=no],[ac_osx_32bit=yes])

if test "${ac_osx_32bit}" = "yes"; then
if test -z "${MACOSX_DEFAULT_ARCH}"; then
Copy link
Contributor

Choose a reason for hiding this comment

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

Why add this test? I guess you are setting this variable when cross building.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On a second look, what is LIBTOOL_CRUFT doing? Is it necessary?

Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't looked at this part of the build in a long time, so I don't know. I'm fairly sure that the configure script can be cleaned up a lot, even just the macOS related parts, but that should be out of scope for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Use of LIBTOOL_CRUFT was removed in 2503249. I'll send a separate PR.

@isuruf
Copy link
Contributor Author

isuruf commented Nov 26, 2020

Please add documentation on how to cross build, without that it is hard to review this PR. This would preferably added to Mac/README.rst. In particular, I get the impression that cross building involves more than just specifying the target tuple to the configure script.

Will add docs

@isuruf
Copy link
Contributor Author

isuruf commented Nov 26, 2020

And out of interest: Why are you cross building to arm64? The build supports universal2 binaries out of the box, which run on both mac architectures and don't require cross compiling.

Because at conda-forge, we don't want a universal2 binary to keep the size of the python installation smaller. We also don't build the dependencies of python as universal binaries, so it would require more work.

Copy link
Member

@ned-deily ned-deily left a comment

Choose a reason for hiding this comment

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

We already have a mechanism for "cross-compiling" on macOS, we just don't call it that:

 --with-universal-archs=ARCH
                          specify the kind of universal binary that should be
                          created. this option is only valid when
                          --enable-universalsdk is set; options are:
                          ("universal2", "32-bit", "64-bit", "3-way", "intel",
                          "intel-32", "intel-64", or "all") see Mac/README.rst

Note that intel-32 and intel-64 produce single architecture binaries. Rather than using the GNU method of specifying cross-compilation just for this one case on macOS, I would prefer to see adding an additional universal-archs option, say arm64, and then doing the minimum fixups necessary, like skipping extension loading and specifying a build interpreter, to truly make building without a common architecture work.

Ideally,it should also support the reverse case: building Intel-64 on arm Macs.

@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 phrase I 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.

@isuruf
Copy link
Contributor Author

isuruf commented Nov 28, 2020

@ned-deily, wouldn't that allow only cross compiling for different macos architectures within macos? My proposal would allow building for macos-arm64 from linux-x86_64.

@ned-deily
Copy link
Member

We don't support building a complete Python for macOS on anything but macOS today using Apple's Developer Tools. The current Python build system is criticized as being overly complex as it stands today and the whole area of cross-compilation is among the least documented and tested, with a few select architectures having been shoehorned in. There have been calls to fund redoing Python's build system using on a standard build tool, like autotools or cmake or ..., that support cross-compilation and other features out of the box. (As far as I know, such calls are currently on hold pending the return of PSF finances to normal after the cancellations of PyCons due to the pandemic.) I don't think we should shoehorn in yet another hack on top of all the other hacks we already have there (speaking as someone who put some of those hacks there in the first place :).

@ned-deily
Copy link
Member

@ronaldoussoren, what's your opinion?

@ned-deily
Copy link
Member

Also, FWIW, and I'm not a lawyer (and I don't play one on the Internet), the copies of Apple Developer agreements that I see include a clause to the effect that: "You agree not to install, use or run the Apple SDKs on any non-Apple-branded computer".

@ronaldoussoren
Copy link
Contributor

I'm in favour of adding single-architecture variants to --with-universal-archs, but that won't solve the problem this PR intends to solve: --enable-universalsdk --with-universal=archs=.... only works when at least one of the specified architectures can be used on the build machine (that is host-python == build-python), while the condaforge use case entails building arm64 on an x86_64 (and requires host-python != build-python).

This PR is acceptable in principal, as long as it doesn't complicate the build too much and it is clear that this build option is basically unsupported by the core devs. That said, the version of the PR that I reviewed earlier is not in a mergeable state yet.

I definitely don't like the change to platform.py, that is a backward incompatible change that affects way more than just building. I don't want to end up in a situation where "platform.mac_ver()" does not report the version of the currently running version of macOS due to an environment variable.

BTW. I'll probably create a PR for the --with-univeral-archs change when the dust settles on the univeral2 work (both here, in my own projects and packaging related projects).

Lib/platform.py Outdated
@@ -409,7 +409,12 @@ def win32_ver(release='', version='', csd='', ptype=''):
def _mac_ver_xml():
fn = '/System/Library/CoreServices/SystemVersion.plist'
if not os.path.exists(fn):
return None
if 'SDKROOT' in os.environ:
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 -1 on this particular change, see also my latest comment in the main discussion.

configure.ac Outdated
@@ -2480,7 +2481,8 @@ case $ac_sys_system/$ac_sys_release in
}
]])],[ac_osx_32bit=yes],[ac_osx_32bit=no],[ac_osx_32bit=yes])

if test "${ac_osx_32bit}" = "yes"; then
if test -z "${MACOSX_DEFAULT_ARCH}"; then
Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't looked at this part of the build in a long time, so I don't know. I'm fairly sure that the configure script can be cleaned up a lot, even just the macOS related parts, but that should be out of scope for this PR.

setup.py Outdated
@@ -62,7 +62,7 @@ def get_platform():
HOST_PLATFORM = get_platform()
MS_WINDOWS = (HOST_PLATFORM == 'win32')
CYGWIN = (HOST_PLATFORM == 'cygwin')
MACOS = (HOST_PLATFORM == 'darwin')
MACOS = (HOST_PLATFORM.startswith('darwin'))
Copy link
Contributor

Choose a reason for hiding this comment

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

ok.

@ned-deily
Copy link
Member

I'm in favour of adding single-architecture variants to --with-universal-archs, but that won't solve the problem this PR intends to solve: --enable-universalsdk --with-universal=archs=.... only works when at least one of the specified architectures can be used on the build machine (that is host-python == build-python), while the condaforge use case entails building arm64 on an x86_64 (and requires host-python != build-python).

Yes, which is what I meant by "would prefer to see adding an additional universal-archs option, say arm64, and then doing the minimum fixups necessary, like skipping extension loading and specifying a build interpreter, to truly make building without a common architecture work". In other words, add the universal arch option and use the specification of a build Python to turn off extension module load checking in the build as is done in the pr and anything else that can't be performed without using the built Python. That generalizes the pr to any case of macOS archs. It doesn't allow for cross builds on non-macOS hosts but I don't think that is a use case we should support, at least in the existing build system.

@isuruf isuruf force-pushed the cross-darwin branch 2 times, most recently from 496f7cd to 6fe3dd7 Compare November 29, 2020 14:25
@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Dec 30, 2020
@isuruf
Copy link
Contributor Author

isuruf commented Sep 16, 2021

cc @FFY00

@isuruf
Copy link
Contributor Author

isuruf commented Sep 16, 2021

This PR is acceptable in principal, as long as it doesn't complicate the build too much and it is clear that this build option is basically unsupported by the core devs.

I've changed this PR so that it is very minimal.

@ned-deily ned-deily self-assigned this Sep 16, 2021
@github-actions github-actions bot removed the stale Stale PR or inactive for long period of time. label Aug 1, 2022
@furkanonder
Copy link
Contributor

furkanonder commented May 9, 2023

@isuruf Could you sign the CLA and resolve the conflict?

@isuruf
Copy link
Contributor Author

isuruf commented May 9, 2023

@furkanonder, done

@AA-Turner AA-Turner changed the title bpo-42476: Allow cross compiling on darwin gh-86642: Allow cross compiling on darwin May 9, 2023
isuruf and others added 2 commits May 9, 2023 13:39
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Copy link
Member

@ned-deily ned-deily left a comment

Choose a reason for hiding this comment

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

Thanks for simplifying the PR. But it still doesn't address @ronaldoussoren's earlier request:

Please add documentation on how to cross build, without that it is hard to review this PR.

As it stands, it is still not clear exactly how someone would use this and under what circumstances it is intended to work.

@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 phrase I 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.

@nightscape
Copy link

@isuruf I'd be interested in this as well. I'm trying to build a JavaCPP ARM64 binding to CPython and unfortunately Github Actions still don't have Mac ARM64 runners...
Can you give any pointers of what's left to do?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants
X Tutup