Build infrastructure always scares me and since I know very little about how this project builds itself, I won't try to touch it but I will say, cibuildwheel has been great: https://github.com/pypa/cibuildwheel
To add M1 / arm64 mac building support it is "as simple as adding 'arm64'" to the Mac build environment variables.
I have also used cross-compilation via `cibuildwheel` on GitHub actions. So there are at least two good options nowadays I think! But given that you have this:
I just tried to pip install lxml in a fresh virtual environment on my MacBook Pro 16" with M1 Pro chip using CPython 3.11.1. Installing works, pip downloads the universal2 wheel as expected. However attempting to import `from lxml import etree` fails with ImportError: "symbol not found in flat namespace (_xmlFree)"
```
$ python
Python 3.11.1 (main, Dec 14 2022, 11:26:39) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import lxml
>>> from lxml import etree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(/Users/clupo/.pyenv/versions/fonttools-py311/lib/python3.11/site-packages/lxml/etree.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace (_xmlFree)
```
xmlFree probably comes from libxml2, but that's strange because according to otool the lxml etree.so only links with libSystem.B.dylib so depedencies (including libxml2) appear to be fully statically linked:
```
$ otool -L /Users/clupo/.pyenv/versions/fonttools-py311/lib/python3.11/site-packages/lxml/etree.cpython-311-darwin.so
/Users/clupo/.pyenv/versions/fonttools-py311/lib/python3.11/site-packages/lxml/etree.cpython-311-darwin.so (architecture x86_64):
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
/Users/clupo/.pyenv/versions/fonttools-py311/lib/python3.11/site-packages/lxml/etree.cpython-311-darwin.so (architecture arm64):
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
```
The error above was with python 3.11.1 compiled from source with pyenv.
So I also tried to download and install the official Python 3.11.1 from python.org (universal2 installer) available at https://www.python.org/downloads/release/python-3111/
I get a similar but slightly different ImportError when I try to import lxml.etree:
```
ImportError: dlopen(/Users/clupo/oss/fontmake/.venv/lib/python3.11/site-packages/lxml/etree.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace (_exsltDateXpathCtxtRegister)
```
If I force this "fat" python3.11 installation to run in emulation mode by prefixing it with `arch -x86_64 /path/to/python3.11` then importing lxml.etree works!
Which leads me to think that the libxml2 library that was statically linked maybe is not "fat" but only contains x86_64 architecture, and no arm64 one?
```
$ arch -x86_64 /Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11
Python 3.11.1 (v3.11.1:a7a450f84a, Dec 6 2022, 15:24:06) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
>>> etree
<module 'lxml.etree' from '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/lxml/etree.cpython-311-darwin.so'>
```
> Which leads me to think that the libxml2 library that was statically linked maybe is not "fat" but only contains x86_64 architecture, and no arm64 one?
That's probably the case. Let's see if we can make the libraries fat as well.
I meant on PyPI, where I had initially uploaded that wheel. I immediately got reports from macOS (not sure which CPU) users that it does not work for them, so I removed it from PyPI again. It seems to work on x86_64, but not on M1, if I understand correctly.
> it doesn't pick up the CFLAGS because those are already set in the environment before the python setup.py build_ext command is run
You're looking in the wrong place. The wheel build is set up in .github/workflows/wheels.yml and done by the Makefile. It does not touch the CFLAGS (for macOS – it sets them for Linux, but that's ok).
Hi, I tested the cp311 universal2 wheel on my M1. It imports fine and I tried some simple etree stuff. Looks like all the compiled parts are universal:
```
Architectures in the fat file: _elementpath.cpython-311-darwin.so are: x86_64 arm64
Architectures in the fat file: builder.cpython-311-darwin.so are: x86_64 arm64
Architectures in the fat file: etree.cpython-311-darwin.so are: x86_64 arm64
Architectures in the fat file: objectify.cpython-311-darwin.so are: x86_64 arm64
Architectures in the fat file: sax.cpython-311-darwin.so are: x86_64 arm64
```
🎉
Could you find out what a good way to build such a wheel is currently?
If it's easy, I'll consider it.