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

Fix include directory when cross compiling #9129

Merged
merged 1 commit into from
Jun 25, 2023

Conversation

jameshilliard
Copy link
Contributor

Fixes #9119.

@alex
Copy link
Member

alex commented Jun 23, 2023

I'm concerned this may have the practical effect of reverting aa8dbd8, particularly since we have no ability to test any of these cross-compilation patterns in CI.

Is there any reasonable way to validate this works correctly?

@jameshilliard
Copy link
Contributor Author

I'm concerned this may have the practical effect of reverting aa8dbd8, particularly since we have no ability to test any of these cross-compilation patterns in CI.

I think it's probably not going to cause issues as headers is from my understanding only set for a subset of python cross compilation configurations(it doesn't look like yocto sets it).

Is there any reasonable way to validate this works correctly?

I'm not all that familiar with how yocto handles python cross compilation here.

@alex
Copy link
Member

alex commented Jun 23, 2023

Perhaps a dumb question, but I don't see headers mentioned in https://docs.python.org/3/library/sysconfig.html, is this an official thing?

@jameshilliard
Copy link
Contributor Author

is this an official thing

It's set here I think.

@alex
Copy link
Member

alex commented Jun 23, 2023 via email

@alex
Copy link
Member

alex commented Jun 23, 2023

@kanavin can you confirm that this PR doesn't have a negative impact on your cross-compilation?

@kanavin
Copy link
Contributor

kanavin commented Jun 24, 2023

On our setup 'headers' is not present at all:

>>> import sysconfig; print(sysconfig.get_paths())              
{'stdlib': '/usr/lib/python3.11', 'platstdlib': '/usr/lib/python3.11', 'purelib': '/usr/lib/python3.11/site-packages', 'platlib': '/usr/lib/python3.11/site-packages', 'include': '/usr/include/python3.11', 'platinclude': '/usr/include/python3.11', 'scripts': '/usr/bin', 'data': '/usr'}

Reading the code for sysconfig, 'headers' entry is only present if python is called from its own source/build directory, and so shouldn't be relied on for building other items, such as this one :) It's not documented for the same reason.

@kanavin
Copy link
Contributor

kanavin commented Jun 24, 2023

I'd also like to ask @jameshilliard , how do you get the sysroot prefix from the build host into these paths reported by sysconfig? Yocto doesn't do it, assuming sysconfig should be reporting target paths. Rather, we patch the sysroot prefix into specific variables in _sysconfigdata.py. Python cross-compile is a mess.

@kanavin
Copy link
Contributor

kanavin commented Jun 24, 2023

@kanavin
Copy link
Contributor

kanavin commented Jun 24, 2023

Okay, sorry for the flood.

@alex The more I look at it, the more I'm convinced that "sysconfig.get_path ('include')" was correct all along. I'd suggest at this point that my change is reverted as well - both yocto and buildroot need to figure out how to make that work without having to patch components such as this one.

@jameshilliard
Copy link
Contributor Author

Reading the code for sysconfig, 'headers' entry is only present if python is called from its own source/build directory, and so shouldn't be relied on for building other items, such as this one :) It's not documented for the same reason.

Yeah...I think to some degree we're treating our 3rd party python package builds somewhat like python stdlib module builds. I recall that approach was the least broken and that this patch was related.

Python cross-compile is a mess.

Very true, and it's largely undocumented as well with everyone handling things slightly differently, rust is pretty bad at cross compilation as well considering setting env variables with names like __CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS are effectively mandatory to work around cargo linker bugs when cross compiling with stable rust toolchains.

I don't have a clear idea yet how we can meet in the middle, need to research further.

Well if headers isn't normally defined...then this shouldn't cause side effects right?

@alex The more I look at it, the more I'm convinced that "sysconfig.get_path ('include')" was correct all along. I'd suggest at this point that my change is reverted as well - both yocto and buildroot need to figure out how to make that work without having to patch components such as this one.

Yeah, I agree sysconfig.get_config_var('INCLUDEPY') does not really look right to me, I think using the headers variable when present is probably harmless as it's not normally defined at all. I'm still somewhat confused exactly why this issue only started popping up with 6c39999 is that the same commit that introduced the build issue for yocto as well?

@reaperhulk
Copy link
Member

It popped up in that commit because we fundamentally changed how we build and link openssl with that work. We needed to do this so we could link rust-openssl against the same copy of openssl that we use for the cffi layer.

kanavin pushed a commit to kanavin/python-cryptography that referenced this pull request Jun 24, 2023
…t in cross builds (pyca#9105)"

The original code was right all along: it uses the official API for
obtaining header locations, and it is on the build environment
to ensure python supplies that in cross-build scenarios
(another option is to apply a custom patch, however any such patch
is not eligible for upstream submission due to its specificity).

Further info: pyca#9129
alex pushed a commit that referenced this pull request Jun 24, 2023
…t in cross builds (#9105)" (#9131)

The original code was right all along: it uses the official API for
obtaining header locations, and it is on the build environment
to ensure python supplies that in cross-build scenarios
(another option is to apply a custom patch, however any such patch
is not eligible for upstream submission due to its specificity).

Further info: #9129

Co-authored-by: Alexander Kanavin <alex@linutronix.de>
@kanavin
Copy link
Contributor

kanavin commented Jun 24, 2023

I submitted a revert PR to my change. Yocto will carry the fix locally and mark it as unsuitable for upstream submission. (and we need to seriously look into cross-building python in a better way).

I cannot agree that using undocumented API is harmless, 'headers' or otherwise. It's problematic for two reasons:

  • anyone reading the code will have a hard time understanding what the undocumented api call does and why is it there. You'd need to research commit history, PR comments, and python code which implements undocumented stuff, and hope you can grasp all of it and make things clear for yourself.

  • python upstream can change the behavior behind undocumented items at any point, and then there's suddenly a bug in components using it with no clear resolution, as adapting to new behavior will break installations of python with old behavior.

I'd suggest that this change stays local to buildroot as well, as it is very much specific to that environment (running python out of its build tree) and is unlikely to be useful elsewhere.

@jameshilliard jameshilliard force-pushed the cross-headers branch 2 times, most recently from a5873f9 to e411697 Compare June 24, 2023 21:03
@jameshilliard
Copy link
Contributor Author

It popped up in that commit because we fundamentally changed how we build and link openssl with that work.

Was this include directory not being used anywhere in the build previously? I'm wondering if there's a different way of pulling this directory that wouldn't trigger this issue that is being used in other places.

anyone reading the code will have a hard time understanding what the undocumented api call does and why is it there.

Well anything related to python cross compilation tends to be poorly or entirely undocumented in general, I updated the PR to add a comment to indicate how headers is used.

python upstream can change the behavior behind undocumented items at any point, and then there's suddenly a bug in components using it with no clear resolution, as adapting to new behavior will break installations of python with old behavior.

That's not all that clear, it seems to be used by distutils/setuptools based on what I'm seeing here in some situations which would indicate that the behavior should be semi-stable as long as it's used similar to distutils/setuptools.

I'd suggest that this change stays local to buildroot as well, as it is very much specific to that environment (running python out of its build tree) and is unlikely to be useful elsewhere.

To clarify we're not actually running python out of its build tree for these 3rd party module builds, we're setting the sysconfig environment up similar to how module builds from within the python build tree work from my understanding but still running the host python binary itself from its out of tree location.

@alex
Copy link
Member

alex commented Jun 24, 2023

Was this include directory not being used anywhere in the build previously? I'm wondering if there's a different way of pulling this directory that wouldn't trigger this issue that is being used in other places.

Previously the include directory was being found somewhere inside of setuptools logic. My preference would be to just reproduce whatever it's doing (that's what we thought we were doing with the sysconfig usage, but perhaps there's a subtly we're missing).

@jameshilliard
Copy link
Contributor Author

Previously the include directory was being found somewhere inside of setuptools logic.

It looks like it might be here, not entirely sure I've traced this properly however.

@alex
Copy link
Member

alex commented Jun 25, 2023 via email

@jameshilliard
Copy link
Contributor Author

I think we'd be happy to take a patch that emulated this.

Seems easier and probably more reliable to just pass the include_dirs via an env variable from setuptools-rust like this.

@alex
Copy link
Member

alex commented Jun 25, 2023

@jameshilliard @kanavin can you both confirm that this latest version works for your setups? Seems like it should, which will be great, and we can put this cursed issue to bed :-)

@jameshilliard
Copy link
Contributor Author

can you both confirm that this latest version works for your setups?

Yeah, seems to work for me.

@alex alex merged commit 2f9cd40 into pyca:main Jun 25, 2023
59 checks passed
@kanavin
Copy link
Contributor

kanavin commented Jun 26, 2023

Works for me as well, thanks!

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

Successfully merging this pull request may close these issues.

fatal error: pyconfig.h: No such file or directory when cross compiling
4 participants