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

ci(macos): Avoid linking against Homebrew #1755

Merged
merged 10 commits into from
Jan 6, 2025

Conversation

bwoodsend
Copy link
Contributor

Homebrew binaries are always compiled for exactly the version they're installed on making them very unportable. When a wheel is "repaired" by cibuildwheel, delocate-wheel pulls in _psycopg's dependencies (libpq.dylib, libssl.dylib and libcrypto.dylib) which, on a GitHub Actions macOS 14 runner, are provided by Homebrew and are therefore only macOS >= 14 compatible. The resultant wheel is therefore incompatible with all but the latest macOS versions.

Build all dependencies from source so that we can set the deployment target to something sensible. Fixes #1753.

@bwoodsend
Copy link
Contributor Author

bwoodsend commented Nov 22, 2024

I've temporarily disabled all the other bits of CI just to make verifying quicker. I'll revert all that if/when we get closer to merging. I wanted to gauge whether you think this is worth the trouble before finishing it off? I can't imagine you'd be particularly comfortable with having a rather hairy build step that you can't run locally.

Here's a sample build with the macOS versions in the wheel tags back to normal.

@dvarrazzo
Copy link
Member

dvarrazzo commented Nov 23, 2024

Yes, this seems useful, and it's what we do for Linux: see the scripts/build/build_libpq.sh. Maybe it would be worth augmenting that script with macOS support? For sure it's better to edit complex bash in a .sh file than interspersed in yaml.

If you complete this operation it would be useful to port it to psycopg 3 too (which has a script pretty much identical).

Hint: you can use if: false to disable a job, which is less invasive then chopping everything away (the reason why there are the if: true in the workflow file is to remember that).

Thank you very much for your initiative!

export LDFLAGS="-L$fake_prefix/lib"
export CPPFLAGS="-I$fake_prefix/include"
cd postgresql-16.6
./configure --without-icu --prefix="$fake_prefix" --with-ssl=openssl
Copy link
Member

Choose a reason for hiding this comment

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

No gssapi/ldap support?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I was going to ask about which --with-xxx features to use but you beat me to it. I see build_libpq.sh makes that decision for me anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately that also implies building these other libraries. Not doing so would break certain features. I don't know how many people rely on them, but I don't feel they are features that we can drop without being unpunished.

TBH, for some reason, GSSAPI causes a lot of problems to macOS users because in some configuration it causes slowdowns on connection, but still it doesn't seem a good case to decide that nobody in the world requires it.

@dvarrazzo
Copy link
Member

What is, on macOS, the default socket dir? In other words:

$ psql "host='' port=9999"
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.9999" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?

what path is searched for in macOS? If it's not /tmp then it's worth patching the libpq before building, see

# Match the default unix socket dir default with what defined on Ubuntu and
# Red Hat, which seems the most common location
sed -i 's|#define DEFAULT_PGSOCKET_DIR .*'\
'|#define DEFAULT_PGSOCKET_DIR "/var/run/postgresql"|' \
src/include/pg_config_manual.h

@bwoodsend
Copy link
Contributor Author

see the scripts/build/build_libpq.sh. Maybe it would be worth augmenting that script with macOS support? For sure it's better to edit complex bash in a .sh file than interspersed in yaml.

Thanks for pointing that out. Yes, adding macOS support to that script sounds better than doing it all over again in YAML.

What is, on macOS, the default socket dir?

I wasn't aware that there was such thing as a socket dir but does this answer your question?

> psql "host='' port=9999"
psql: error: connection to server on socket "/tmp/.s.PGSQL.9999" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?

(That's homebrew's psql – not a source built one in case it matters.)

@bwoodsend
Copy link
Contributor Author

bwoodsend commented Nov 23, 2024

Do you mind if I bump the OpenLDAP version? I need this fix or the check for POSIX regex throws a false negative. (It's probably sed-able if not.)

@bwoodsend bwoodsend force-pushed the fix-macos-deployment-target branch 3 times, most recently from 2b1b6f2 to 57bfbda Compare November 23, 2024 22:00
@dvarrazzo
Copy link
Member

I wasn't aware that there was such thing as a socket dir but does this answer your question?

Yes it does. It seems that the default socket dir is /tmp/, which is the default one in Postgres source, so we don't need patching.

It is useful that it is the brew one. If it wasn't, a program configured and running correctly so far would stop working if we switch to a libpq with a different default. See past issues for example.

Do you mind if I bump the OpenLDAP version?

Absolutely not, go ahead 🙂

@bwoodsend bwoodsend force-pushed the fix-macos-deployment-target branch 3 times, most recently from 96dbaa3 to 3d29e02 Compare November 24, 2024 20:07
@dvarrazzo
Copy link
Member

Hello @bwoodsend! How is it going with this work? Is it ready, or are you stuck somewhere, or you don't think you want to finish the MR?

Thank you very much!

@bwoodsend
Copy link
Contributor Author

bwoodsend commented Dec 4, 2024

Sorry, I'm still here. I ground to a halt over some m4 issue running cyrus-sasl's autoreconf which I couldn't reproduce locally (despite also using macOS 14 M1). I suspect there's something from homebrew on the GitHub runner shadowing the xcode version that works somewhere. When I get a quiet moment where I'm more than half awake, I'll tmate my way in and see if I can figure it out.

@bwoodsend
Copy link
Contributor Author

Yay! Got there eventually. I'll clean up my mess in a bit and move this out of draft.

I suspect there's something from homebrew on the GitHub runner shadowing the xcode version that works somewhere.

Sure enough, brew install libtool was the magic cure. I never really appreciated before how evil these xcode/brew tools and brew/system libraries dualities were for issue debugging and reproducibility.

The macos-12 GitHub runners have just had the plug pulled on them. I'll bump us onto macos-13 but I'm rather uncomfortable that this time next year, that'll be gone too and we'll have no more x86_64 runners. At that point I suspect we'll be forced to cross compile. I've given it a brief poke locally and it looks like each component insists on doing it in their own way. So not quick and not fun...

@bwoodsend bwoodsend force-pushed the fix-macos-deployment-target branch from 3d29e02 to b49ff40 Compare December 12, 2024 06:33
# If available, libpq seemingly insists on linking against homebrew's
# openssl no matter what so remove it. Since homebrew's curl depends on
# it, force use of system curl.
brew uninstall --force --ignore-dependencies openssl gettext
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't suppose you know a better way to force which copy of a library to link against? The build system seems to add homebrew to its search path even if I env -i away all the brew related environment variables.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe with -L/-l options in the compiler? Not sure.

@bwoodsend
Copy link
Contributor Author

Up to date verification run: https://github.com/bwoodsend/psycopg2/actions/runs/12291165704

@bwoodsend bwoodsend marked this pull request as ready for review December 12, 2024 07:31
Homebrew binaries are always compiled for exactly the version they're
installed on making them very un-portable. When a wheel is "repaired" by
cibuildwheel, delocate-wheel pulls in _psycopg's dependencies
(libpq.dylib, libssl.dylib and libcrypto.dylib) which, on a GitHub
Actions macOS 14 runner, are provided by Homebrew and are therefore only
macOS >= 14 compatible. The resultant wheel is therefore incompatible
with all but the latest macOS versions.

Build all dependencies from source so that we can set the deployment
target to something sensible. Fixes psycopg#1753.
@dvarrazzo dvarrazzo force-pushed the fix-macos-deployment-target branch 6 times, most recently from 9c871cf to 5b643a2 Compare January 5, 2025 02:56
We don't run complete tests in CI, so let's not waste this chance. The
overhead for complete tests is minimal compared to all the pipeline
boilerplate.
@dvarrazzo dvarrazzo force-pushed the fix-macos-deployment-target branch from 5b643a2 to 1eac4fd Compare January 5, 2025 03:01
@dvarrazzo
Copy link
Member

Hello @bwoodsend

I have worked a bit on this branch, mostly adding libpq build caching and moving the libpq build from the CI workflow to the BEFORE script, consistently with the linux workflow.

A complete package build with all the version run here.

This looks ok to merge for me. Ok for you too?

After this is safe I will also port it to psycopg3, which has the same type of problem.

Thank you very much for your contribution!

@bwoodsend
Copy link
Contributor Author

Do you want to cherry pick bwoodsend@ede7cd2 in or we can save it for later? I wrote it a while ago but never got around to pushing it (curse my tiny attention span).

I'm happy for this to be merged now either way.

@dvarrazzo
Copy link
Member

dvarrazzo commented Jan 5, 2025

Do you want to cherry pick bwoodsend@ede7cd2 in or we can save it for later?

If it works, it seems good. I remember that with cross-compiling on macOS you could build but not run/test what built. Is that only a concern for cross-compiling ARM on X86?


Edit: answering to myself: looking here it seems that x86 code can be tested on arm.

The GitHub Actions runners look like they're only 1 year away from the
last macOS x86_64 platform being removed. Get ahead of the game and
build x86_64 on arm64.
@bwoodsend
Copy link
Contributor Author

Do you want to cherry pick bwoodsend@ede7cd2 in or we can save it for later?

If it works, it seems good. I remember that with cross-compiling on macOS you could build but not run/test what built. Is that only a concern for cross-compiling ARM on X86?

Edit: answering to myself: looking here it seems that x86 code can be tested on arm.

Yeah, you can run x86_64 binaries on arm64 using Rosetta emulation but not the other way around. I think that's also scheduled for removal in macOS 16 but we can make the most of it whilst it's still there.

@dvarrazzo
Copy link
Member

Thank you for the in-depth co-review, it seems a good improvement to only depend on the ARM runners.

Building packages in this job. If everything works I guess we can merge this.

@bwoodsend
Copy link
Contributor Author

That's everything I can think of. Ready for the merge button when you are...

@dvarrazzo dvarrazzo force-pushed the fix-macos-deployment-target branch from e2e51d7 to 6cd0fbd Compare January 5, 2025 21:00
dvarrazzo added a commit to psycopg/psycopg that referenced this pull request Jan 6, 2025
This avoids problems with MACOSX_DEPLOYMENT_TARGET drifting in builders
(see #858).

Largely contributed by @bwoodsend in psycopg/psycopg2#1755.
dvarrazzo added a commit to psycopg/psycopg that referenced this pull request Jan 6, 2025
This avoids problems with MACOSX_DEPLOYMENT_TARGET drifting in builders
(see #858).

Largely contributed by @bwoodsend in psycopg/psycopg2#1755.
@dvarrazzo dvarrazzo merged commit 5509e01 into psycopg:master Jan 6, 2025
98 checks passed
@dvarrazzo
Copy link
Member

Thank you very much! Merged, now poriting to psycopg 3 in psycopg/psycopg#986.

dvarrazzo added a commit to psycopg/psycopg that referenced this pull request Jan 6, 2025
This avoids problems with MACOSX_DEPLOYMENT_TARGET drifting in builders
(see #858).

Largely contributed by @bwoodsend in psycopg/psycopg2#1755.
dvarrazzo added a commit to psycopg/psycopg that referenced this pull request Jan 14, 2025
This avoids problems with MACOSX_DEPLOYMENT_TARGET drifting in builders
(see #858).

Largely contributed by @bwoodsend in psycopg/psycopg2#1755.
dvarrazzo added a commit to psycopg/psycopg that referenced this pull request Jan 14, 2025
This avoids problems with MACOSX_DEPLOYMENT_TARGET drifting in builders
(see #858).

Largely contributed by @bwoodsend in psycopg/psycopg2#1755.
dvarrazzo added a commit to psycopg/psycopg that referenced this pull request Jan 14, 2025
This avoids problems with MACOSX_DEPLOYMENT_TARGET drifting in builders
(see #858).

Largely contributed by @bwoodsend in psycopg/psycopg2#1755.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

High macOS deployment targets for psycopg2-binary
2 participants