x86_64 10.5/i386 fink 10.6 and the options for MacPorts

Jack Howarth howarth at bromo.med.uc.edu
Sun Sep 13 05:48:25 PDT 2009


   I should explain to everyone here the situation with
i386 fink on 10.6 and x86_64 fink on 10.5 so it is clearer
what is possible in packaging binaries of a different 
architecture than the default and the costs involved.
   Chronologically, i386 fink on 10.6 came first during
the Snow Leopard seeding process. At that time, it was
unclear how viable it would be to build all of the fink
package set as x86_64 code.
   The approach used in fink for both i386 fink on 10.6
and x86_64 fink on 10.5 involves the use of compiler
wrappers. For i386 fink on 10.6, these reside in...

/sw.i386/var/lib/fink/path-prefix-10.6

as...

lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 c++ -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 c++-4.0 -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 c++-4.2 -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 cc -> compiler_wrapper
-rwxr-xr-x  1 root  admin  49 Aug 10 19:47 compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 g++ -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 g++-4.0 -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 g++-4.2 -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 gcc -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 gcc-4.0 -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 gcc-4.2 -> compiler_wrapper
lrwxr-xr-x  1 root  admin  16 Aug 10 19:47 gcc=4.0 -> compiler_wrapper

where the compiler_wrapper file, which is repeatedly symlinked,
contains...

#!/bin/sh
exec /usr/bin/${0##*/} -arch i386 "$@"

On x86_64 fink for 10.5, this is oddly in the same directory...

/sw.x86_64/var/lib/fink/path-prefix-10.6

but the content of the compiler_wrapper is now changed to...

#!/bin/sh
exec /usr/bin/${0##*/} -arch x86_64 "$@"

Note that these compiler wrappers are not invoked automatically.
The default fink init scripts DO NOT change the code generation behavior
of the system compilers when invoked outside of the fink packaging
program. These wrappers are only activated within the fink builds.
   So what limitations does this place on you as a packager? The
primary one is that your package builds must NEVER invoke the
compiler with a complete path. This was actually the hardest issue
to initially get across to all of the other fink developers who
weren't working with i386 fink on 10.6 or x86_64 fink on 10.5
themselves. If you have CC=/usr/bin/gcc in a Makefile it must
become CC=gcc.
    Now on i386 fink on 10.6, because the current config.guess
is broken and incorrectly reports the triplet as i386-apple-darwin10,
there was no need to ever pass the triplets manually to
configure for those builds. In the case of x86_64 fink on 10.5
however, there is because if configure guesses the wrong triplet, you
may not compile the proper sections code or set incorrect values
for the type of code being generated. This was the origin of the
breakage in the MacPorts gcc44 package that I fixed last night.
In fink, this process is generalized by passing...

--build=%m-apple-darwin`uname -r|cut -f1 -d.` --host=%m-apple-darwin`uname -r|cut -f1 -d.`

to configure where %m is set in fink to the architecture determined via
the sysctl -n output. Unless the source package is broken, this should work
for all permutations (ie i386-apple-darwin*, powerpc-apple-darwin* and x86_64-apple-darwin*)
without breakage in the build).
    A few months into the i386 fink on 10.6 development, we added the
option to build x86_64 fink on 10.6 which was then shortly extended via
the compiler_wrappers to x86_64 fink on 10.5 (in order to have more developers
involved in porting packages to build on x86_64). As the 10.6 release approached,
it became clearer that the x86_64 fink support was quite viable with all the
major components building save a few odds and ends like SDL. In recent weeks,
the biggest problem the fink developers have has is with i386 fink on 10.6.
This is because it can be an exhausting process to make sure that none of
the packages manually sneak in a pathed call to the compilers which will
suddenly throw x86_64 code into a linkage. Some of the fink developers even
came to view the i386 fink on 10.6 support as more trouble than it was worth
however they were so far along there was no option but to fix all the packages.
    So what does this all mean for MacPorts? I am a little unclear on what
your ambitions are for Snow Leopard, but if you really intend to support
an option where the package are all built as i386 code, you will have to
resort to a compiler wrapper approach like fink for it to be viable. Also
be warned it will consume huge resources here because of the need to patch
all of the software to never directly call the compiler with a complete path.
    In the last few weeks, I have been working with the config.guess maintainer
and the FSF gcc developers to construct an acceptable patch to config.guess
that will ensure that the reported triplet always appropriately reflects the
compilers default code generation as invoked through CC for example. The
current version of this patch, which used to fix the MacPorts gcc44 build, is...

--- config.guess.orig   2009-09-12 20:13:05.000000000 -0400
+++ config.guess        2009-09-12 20:14:07.000000000 -0400
@@ -1259,6 +1259,24 @@
     *:Darwin:*:*)
        UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
        case $UNAME_PROCESSOR in
+           i386)
+               eval $set_cc_for_build
+               if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+                 sed 's/^                //' << EOF >$dummy.c
+                 #if defined(__LP64__)
+                 main()
+                 {
+                 }
+                 #endif
+EOF
+                 if test `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep -c main` = 1 ; then
+                     UNAME_PROCESSOR=x86_64
+                 fi
+               else
+                 if sysctl -a | grep -c hw.cpu64bit_capable>/dev/null 2>&1 ; then
+                   UNAME_PROCESSOR=x86_64
+                 fi
+               fi ;;
            unknown) UNAME_PROCESSOR=powerpc ;;
        esac
        echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}


For i386, this patch checks first if a compiler is available. If none is found, the default code
execution is determined through sysctl. If there is a c compiler installed, the default
code generation is determined via a small test program with a __LP64__ wrapper around main().
This could have been done with a much shorter test using -dM but that is a gcc-centric option
not available on all c compilers. This patched config.guess will now always properly track
the code generation of what can be viewed as the system compiler set via CC. So consider the
cases...

[Macintosh-2:~/gcc-4.5-20090905] howarth% setenv CC gcc-4.2
[Macintosh-2:~/gcc-4.5-20090905] howarth% ./config.guess.proposed
x86_64-apple-darwin10.0.0

[Macintosh-2:~/gcc-4.5-20090905] howarth% setenv CC gcc-4.0
[Macintosh-2:~/gcc-4.5-20090905] howarth% ./config.guess.proposed
i386-apple-darwin10.0.0

[Macintosh-2:~/gcc-4.5-20090905] howarth% setenv CC "gcc-4.2 -m32"
[Macintosh-2:~/gcc-4.5-20090905] howarth% ./config.guess.proposed
i386-apple-darwin10.0.0

[Macintosh-2:~/gcc-4.5-20090905] howarth% setenv CC "gcc-4.0 -m64"
[Macintosh-2:~/gcc-4.5-20090905] howarth% ./config.guess.proposed
x86_64-apple-darwin10.0.0

In each case, the correct triplet is now detected that matches the
default code generation of the compiler as invoked through CC.
We did not have this config.guess fix available to use during the
x86_64 fink on 10.5 development (and it is orthogonal to the problems
of building i386 fink on 10.6).
    If MacPorts is willing to junk the idea of building i386 packages
as a default on 10.6, the config.guess fix is really the way to go.
When patched this way, all programs that use config.guess to determine
the triplets for configure will pick the correct value of
x86_64-apple-darwin10 and there will be no need to force -m64 onto any
compiler flags or to bother to pass --build/--host/--target to
configure. From my own experiences on fink, I would strongly urge 
MacPorts to abandon any attempt to build an i386 MacPorts on 10.6
(except where non-EMT64 Core Duo and Core Solo's will do that without
any intervention) and to focus on the x86_64 Macport builds for 10.6
fully utilizing the proposed config.guess patch to avoid the bother
of passing the --build/--target/--host triplets to configure in
Portfiles. My two cents anyway as a newcomer to MacPorts.
              Jack



More information about the macports-dev mailing list