I just recently got a Mac laptop with Mac OS X 10.11 (El Capitan) installed, and one of the things I do in a new system is install a local Perl environment using perlbrew. It allows me to install and upgrade modules without worrying that I am getting in the way of the system environment. Problem is, when I built my first perlbrew environment on El Capitan, I saw some weird stuff happening in the build.
Perlbrew needs compilation tools, so I installed Xcode, as well as the Xcode command-line tools (which you can get from the Downloads for Apple Developers page). Building and testing of Perl went fine, but I noticed some weird warnings throughout the process:
ld: warning: object file (SystemDirectory.o) was built for newer OSX version (10.11) than being linked (10.4)
I got that warning (with other object files) several times through the Perl build process. I was also getting similar warnings when installing modules from CPAN which had XS components.
After some reading of cc and ld man pages, I found the problem: Something is telling the linker to assume that the software we’re building is going to be used on a different system running a lower version of Mac OS X. Although I am building Perl (and various modules), I have no intention of ever packaging this software for distribution. So, I have to tell the compiler and linker that the binaries we are building will not be used with any lower Mac OS X version. Since I am currently running El Capitan, the option that needs to be passed (to both the compiler and the linker) is ‘-mmacosx-version-min=10.11’.
Luckily, perlbrew gives us a way to pass these additional flags to Perl’s configuration & build script:
PERLBREW_CONFIGURE_FLAGS='-de -Dccflags="-mmacosx-version-min=10.11" -Dccdlflags="-mmacosx-version-min=10.11" -Dldflags="-mmacosx-version-min=10.11" -Dlddlflags="-mmacosx-version-min=10.11"' \ perlbrew install 5.20.3 --thread --multi --64all -j 2
The above command runs perlbrew with the PERLBREW_CONFIGURE_FLAGS environment variable set. That variable contains flags that get passed to Perl’s Configure script.
The “-de” option is something that perlbrew sets by default; since we’ve overriding perlbrew’s default Configure script flags, we need to keep that.
The -Dccflags and -Dldflags options tell Perl’s Configure script to pass additional options through to cc (when compiling) and ld (when linking) for executables. The -Dccdlflags and -Dlddlflags options do the same for shared libraries. We need to set both sets of variables, or else we’ll get weird linker errors when we try to build stuff.
The options passed to perlbrew (like –thread and –multi) are just my own selection of features for perl to build. You can set (or not set) them as you like.
Once you build Perl with -mmacosx-verison-min, you should stop getting annoying linker minimum version warnings. An awesome byproduct of this is that the build options get added to the Config module that Perl builds. Virtually all modules with XS (compiled) code rely on the Config module to identify any extra flags to pass to the compiler and linker, so you should not get the warnings when building modules.
That’s it! You should be good to go now with your Perl environments on El Capitan, but you might also want to check out my companion piece (still being written) that talks about problems building modules that rely on OpenSSL.