The Problem
I compiled a small Haskell script I'd been writing on my old Mac (32-bit architecture). It compiled fine, but when I ran a script that tried connecting to PostgreSQL, I got the following error.
can't load .so/.DLL for: pq (dlopen(/usr/local/Cellar/postgresql/8.4.4/lib/libpq.dylib, 9): no suitable image found. Did find: /usr/local/Cellar/postgresql/8.4.4/lib/libpq.dylib: mach-o, but wrong architecture)Obviously, there was a problem with 32 vs 64 bit architectures.
libpq, which I had built on the 64-bit machine, was a 64-bit build:$ file /usr/local/Cellar/postgresql/8.4.4/lib/libpq.5.2.dylib /usr/local/Cellar/postgresql/8.4.4/lib/libpq.5.2.dylib: Mach-O 64-bit dynamically linked shared library x86_64but GHC was 32-bit:
$ file /Library/Frameworks/GHC.framework/Versions/612/usr/lib/ghc-6.12.3/ghc /Library/Frameworks/GHC.framework/Versions/612/usr/lib/ghc-6.12.3/ghc: Mach-O executable i386Incidentally, 64-bit builds of GHC on OS X are still pending.
Failed Attempts
My first thought was to simply rebuild PostgreSQL as a universal binary. That way Haskell could load the 32-bit version it needed and everything else could stay 64-bit. I knew that Perl was a universal binary:
$ file /usr/bin/perl /usr/bin/perl: Mach-O universal binary with 3 architectures /usr/bin/perl (for architecture x86_64): Mach-O 64-bit executable x86_64 /usr/bin/perl (for architecture i386): Mach-O executable i386 /usr/bin/perl (for architecture ppc7400): Mach-O executable ppcAccording to
perl -V, the necessary CFLAGS and LDFLAGS options are -arch i386 -arch x86_64 -arch ppc. Several attempts invoking Homebrew with those options in the environment failed.
I came across some tips about building a PostgreSQL universal binary. I tried several variations of his latest build script, but wasn't able to make it work.The tricks for building a universal binary seemed easy enough, so I decided to modify the Homebrew formula using those tricks. In the process, I discovered that Homebrew has a convenient way for enabling universal builds within a formula. Just add to the formula the line:
ENV.universal_binary if ARGV.include? '--universal'and universal binaries are built automatically. Even with this change (and rebuilding OSSP-UUID as a universal binary), I still got compiler errors when building PostgreSQL. The problem appeared to be the way that certain macros were expanded when compiling for multiple architectures.
Final Solution
At this point, I gave up on building from source. I came across the handy PostgreSQL installer for OS X. It installs a 32-bit version of PostgreSQL. After the installation, I linked
Although I might encounter problems down the road without a 64-bit PostgreSQL, this solution got me past the roadblock and taught me a lot about compiling for multiple architectures.
libpq into /usr/local/lib and now everything works fine:
cd /usr/local/lib ln -s /Library/PostgreSQL/8.4/lib/libpq.5.2.dylib libpq.dylib
1 comments:
Yup, only having 32-bit PostgreSQL did cause me troubles. I ended up using this other PostgreSQL installer which provides a 32/64 bit universal binary. I then linked /usr/local/pgsql/lib/libpq.5.2.dylib into /usr/local/lib and everything works great now.
Post a Comment