bucardo / dbdpg

Perl Postgres driver DBD::Pg aka dbdpg
48 stars 36 forks source link

ld -rpath error when compiling on Mac (12.0.1) #127

Open mstratman opened 3 months ago

mstratman commented 3 months ago

Using perl-5.40.0 from perlbrew I get the following error (full build log attached):

LD_RUN_PATH="/Applications/Postgres.app/Contents/Versions/9.6/lib" env MACOSX_DEPLOYMENT_TARGET=10.3 cc -Wl,-rpath,"/Applications/Postgres.app/Contents/Versions/9.6/lib" -bundle -undefined dynamic_lookup -L/usr/local/lib -fstack-protector-strong  Pg.o dbdimp.o quote.o types.o  -o blib/arch/auto/DBD/Pg/Pg.bundle  \
       -L/Applications/Postgres.app/Contents/Versions/9.6/lib -lpq -lm   \

ld: -rpath can only be used when targeting Mac OS X 10.5 or later
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [blib/arch/auto/DBD/Pg/Pg.bundle] Error 1
-> FAIL Installing DBD::Pg failed. See /Users/mstratman/.cpanm/work/1725293641.93688/build.log for details. Retry with --force to force install it.
1 distribution installed

If I naively remove the "-rpath" argument, it builds but gives these warnings:

ld: warning: object file (Pg.o) was built for newer macOS version (12.0.1) than being linked (11.0)
ld: warning: object file (dbdimp.o) was built for newer macOS version (12.0.1) than being linked (11.0)
ld: warning: object file (quote.o) was built for newer macOS version (12.0.1) than being linked (11.0)
ld: warning: object file (types.o) was built for newer macOS version (12.0.1) than being linked (11.0)
ld: warning: ignoring file /Applications/Postgres.app/Contents/Versions/9.6/lib/libpq.dylib, building for macOS-arm64 but attempting to link with file built for macOS-x86_64

Which, if used, result in runtime errors: mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64'))

mstratman commented 3 months ago

Full build log

esabol commented 3 months ago

I think ld: warning: object file (...) was built for newer macOS version (12.0.1) than being linked (11.0) means you need to recompile your Perl installation. Or you are compiling DBD::Pg with the wrong Perl. Make sure your path is set correctly and such.

mstratman commented 3 months ago

I tried recompiling perl through perlbrew with no change. This installation was attempted with cpanm which was definitely running out of the same perlbrew path.

esabol commented 3 months ago

This web page says you need to add -mmacosx-version-min=11.0 to the cc flags somehow.

First, do a make clean as you will need to recompile all the DBD::Pg C code from scratch. Then, I would edit the Makefile and add -mmacosx-version-min=11.0 to the CFLAGS and/or CXXFLAGS settings. It might be possible to do make CFLAGS="-mmacosx-version-min=11.0" or something like that without editing the Makefile, but I'm not sure.

esabol commented 3 months ago

Looking at your build.log, I'm worried that your macOS SDK is too old, based on this line:

ld: warning: object file (/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/bundle1.o) was built for newer macOS version (10.4) than being linked (10.3)

Your PostgreSQL installation is also very old (9.6) and may have been built using 10.3? I think that's where the MACOSX_DEPLOYMENT_TARGET=10.3 is coming from, I think!

In both cases, the PostgreSQL code and the macOS SDK need to be built for macOS 10.5+.

Maybe do something like this to update your SDK?

sudo mv /Library/Developer/CommandLineTools{,.save}
sudo xcode-select --install

And then download and compile a more recent PostgreSQL version?

mstratman commented 3 months ago

Thanks. I tried updating the xcode CommandLineTools, updating Postgres to 16 (via Postgres.app), but that didn't seem to make a difference.

Adding -mmacosx-version-min=11.0 to CCFLAGS allowed it to compile without any errors or warnings.

Unfortunately once I try to run it (this is an M1 mac) I get the following error: (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64'))

Or in full:

DBIx::Class::Storage::DBI::catch {...} (): DBI Connection failed: install_driver(Pg) failed: Can't load '/Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/site_perl/5.40.0/darwin-2level/auto/DBD/Pg/Pg.bundle' for module DBD::Pg: dlopen(/Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/site_perl/5.40.0/darwin-2level/auto/DBD/Pg/Pg.bundle, 0x0001): tried: '/Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/site_perl/5.40.0/darwin-2level/auto/DBD/Pg/Pg.bundle' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/local/lib/Pg.bundle' (no such file), '/usr/lib/Pg.bundle' (no such file) at /Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/5.40.0/XSLoader.pm line 97.
 at /Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/site_perl/5.40.0/darwin-2level/DBD/Pg.pm line 98.
Compilation failed in require at (eval 54) line 3.
Perhaps a required shared library or dll isn't installed where expected
 at /Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/site_perl/5.40.0/DBIx/Class/Storage/DBI.pm line 1639. at ./build_schema.pl line 10
esabol commented 3 months ago

Unfortunately once I try to run it (this is an M1 mac) I get the following error: (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64'))

If you are on an M1 Mac, then you shouldn't need x86_64 at all unless either your Perl or your PostgreSQL installation is x86_64? Run the file command on them.

mstratman commented 3 months ago

Yeah, I have no idea what the install scripts are doing or how the file architecture's are chosen, etc. That's why I opened this bug.

I should be able to just type 'cpanm DBD::Pg'

file /Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/site_perl/5.40.0/darwin-2level/auto/DBD/Pg/Pg.bundle
/Users/mstratman/perl5/perlbrew/perls/perl-5.40.0/lib/site_perl/5.40.0/darwin-2level/auto/DBD/Pg/Pg.bundle: Mach-O 64-bit bundle arm64
esabol commented 3 months ago

That's not either of the two files I said to run file on.

file `which perl`
file /path/to/PostgreSQL_16.x/libpq.so
mstratman commented 3 months ago

Sorry, I misunderstood. Perl is (for reasons I don't yet know) Mach-O 64-bit executable x86_64 and Postgres is a universal binary. I even tried recompiling a new and different version of perl with the same results.

~ $ file /Users/mstratman/perl5/perlbrew/perls/perl-5.38.2/bin/perl
/Users/mstratman/perl5/perlbrew/perls/perl-5.38.2/bin/perl: Mach-O 64-bit executable x86_64

~ $ file /Applications/Postgres.app/Contents/Versions/16/bin/postgres
/Applications/Postgres.app/Contents/Versions/16/bin/postgres: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64]
/Applications/Postgres.app/Contents/Versions/16/bin/postgres (for architecture x86_64): Mach-O 64-bit executable x86_64
/Applications/Postgres.app/Contents/Versions/16/bin/postgres (for architecture arm64):  Mach-O 64-bit executable arm64
esabol commented 3 months ago

Your previous commands showed you using Perl 5.40.0, but that output says you're using Perl 5.38.2. Regardless, it would seem that that's the problem. Your Perl is x86_64 even though your architecture is Apple Silicon, and it's not even a dual-architecture compile. I suggest asking the perlbrew people about that. If you can fix that, you should be in the home stretch to getting DBD::Pg to work. I suppose you could force DBD::Pg to compile as x86_64, but I don't think you want to do that.

mstratman commented 3 months ago

Yeah, all perlbrew perl's are x86_64. As I noted I tried recompiling for good measure.

esabol commented 3 months ago

Try prefixing your perlbrew (and cpanm) commands with arch -arm64.

Or maybe switch to Homebrew: https://formulae.brew.sh/formula/perl