indygreg / PyOxidizer

A modern Python application packaging and distribution tool
Mozilla Public License 2.0
5.4k stars 234 forks source link

PyOxidizer 0.21 macOS binaries link against `/usr/local/opt/xz/lib/liblzma.5.dylib` #585

Closed indygreg closed 2 years ago

indygreg commented 2 years ago

The linking of this dylib outside the macOS base install is wrong and likely a regression from 0.21. I'm not sure where the dependency came from. Likely via a Rust crate.

indygreg commented 2 years ago

The rcodesign executables have this issue as well.

indygreg commented 2 years ago

The dependency came from the apple-xar crate via the xz2 Rust crate. That crate has a static feature to ensure liblzma is statically linked. But this feature doesn't exist in a published crate version. I requested a release in https://github.com/alexcrichton/xz2-rs/issues/97.

In the mean time, we can work around this by forcing the linker to prefer the macOS SDK liblzma copy or rewrite the Mach-O afterwards to change the path of liblzma (assuming all referenced symbols are in the system's liblzma). That assertion may not be correct if the system liblzma is old (which is often the case with 3rd party libraries in macOS).

indygreg commented 2 years ago

I may have aggravated this into a fatal error by enabling the hardened runtime setting in the code signature of distributed macOS binaries.

The bad liblzma dependency/path was present in the rcodesign 0.14 release binaries. But those run just fine! However, in the just-released 0.15 release binaries:

dyld: Library not loaded: /usr/local/opt/xz/lib/liblzma.5.dylib

  Referenced from: /Users/runner/Library/Application Support/hatch/env/virtual/pyapp-UYSILkbu/build/bin/pyoxidizer

  Reason: no suitable image found.  Did find:

    /usr/local/opt/xz/lib/liblzma.5.dylib: code signature in (/usr/local/opt/xz/lib/liblzma.5.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.

    /usr/local/opt/xz/lib/liblzma.5.dylib: stat() failed with errno=1

We could disable the hardened runtime. But then we won't be able to pass Apple notarization checks.

indygreg commented 2 years ago

Turns out lzma-sys's build script looks for an LZMA_API_STATIC environment variable to force static linking (https://github.com/alexcrichton/xz2-rs/blob/949294ec701ee1727e1b2d5541bcf9e644ac0764/lzma-sys/build.rs#L12). So we can just set that in CI runners to get the same effect as the static feature.