Hello guys,
As the subject says I've been hacking to get the shared libraries code of GHC 6.12.1 to work on FreeBSD. This patch is mere plumbing to get the code to treat FreeBSD just the same as Linux. I expected FreeBSD to follow the same ELF conventions than Linux and as far as I can tell for now, it's working. This patch probably cannot be applied as is, for different reasons: - It's modifying multiple places to make the FreeBSD case equal to the Linux case. It would probably be much better to define some "ELF-like" target and have both FreeBSD and Linux be part of it, in just one place. Otherwise, similar changes will have to be applied for NetBSD, OpenBSD, and countless others. - It includes a change to deal with the "rules/build-dependencies.mk" file using the 'i' flag of sed, which FreeBSD's sed doesn't support. I changed it to an 'I' flag that is supported and has the exact same meaning. Of course it would be better to not depend on such extensions, or to use a configure-detected GNU sed if that's not possible. This only affects HEAD and not GHC 6.12.1. - It includes another hack to "libffi/ghc.mk" to work around a subtle problem with libtool. That is, libtool detects that it's running under FreeBSD and because of (maybe legitimate) naming conventions doesn't produce a libffi.so.5.0.9 file, while it produces a libffi.so.5 one. However the make targets lists both files, and a loop in the build system ensues. I just removed the libffi.so.5.0.9 dependency. - It lacks proper comments. Despite the above, GHC seems to produce working shared libraries and dynamically linked executables. I pasted a demonstration shell session at the following link if you want to see it in action: http://pastebin.com/m4ec69aea A couple of questions are raised though: - /usr/bin/ld produces a lot of warnings when linking, as can be seen at the pastebin link. It seems those don't occur under Linux and I have no clue where they come from, I just know they seem harmless. Here's my GNU ld version (FreeBSD patches the GNU toolchain, but usually not in an extensive way): GNU ld version 2.15 [FreeBSD] 2004-05-23 - Is there a plan to deal with the ldconfig cache on UNIX systems? As things are now, I had to manually add all the package directories under /usr/local/lib/ghc-6.12.1/ to be able to run the generated executable. I guess Cabal could produce a list of directories in some way for the system to do the right thing afterward, or we need some kind of a hack for setting LD_LIBRARY_PATH prior to starting the executable. - I'm a bit surprised at the naming convention for the shared libraries. The library name includes both the package and the compiler versions, preventing any "automatic" upgrading. If a new version of some package fixes bugs, improves performance, etc... but otherwise doesn't break the ABI, we are still going to be forced to rebuild binaries to take advantage of it. Similarly if a new compiler version produces better code but doesn't break the ABI, but I'm less concerned about that one. I suppose an ABI number could be handled at the Cabal level, and only bumped when maintainers know it is appropriate, otherwise, we won't be getting one of the nice advantages of shared libraries. Many thanks to the people in #ghc for their great help with this! Cheers, Maxime
diff -rN -u old-ghc/compiler/cmm/CLabel.hs new-ghc/compiler/cmm/CLabel.hs --- old-ghc/compiler/cmm/CLabel.hs 2009-12-29 20:25:56.000000000 +0100 +++ new-ghc/compiler/cmm/CLabel.hs 2009-12-29 20:25:57.000000000 +0100 @@ -1001,7 +1001,7 @@ pprDynamicLinkerAsmLabel _ _ = panic "pprDynamicLinkerAsmLabel" -#elif powerpc_TARGET_ARCH && linux_TARGET_OS +#elif powerpc_TARGET_ARCH && (linux_TARGET_OS || freebsd_TARGET_OS) pprDynamicLinkerAsmLabel CodeStub lbl = pprCLabel lbl <> text "@plt" pprDynamicLinkerAsmLabel SymbolPtr lbl @@ -1009,7 +1009,7 @@ pprDynamicLinkerAsmLabel _ _ = panic "pprDynamicLinkerAsmLabel" -#elif x86_64_TARGET_ARCH && linux_TARGET_OS +#elif x86_64_TARGET_ARCH && (linux_TARGET_OS || freebsd_TARGET_OS) pprDynamicLinkerAsmLabel CodeStub lbl = pprCLabel lbl <> text "@plt" pprDynamicLinkerAsmLabel GotSymbolPtr lbl @@ -1019,7 +1019,7 @@ pprDynamicLinkerAsmLabel SymbolPtr lbl = text ".LC_" <> pprCLabel lbl -#elif linux_TARGET_OS +#elif linux_TARGET_OS || freebsd_TARGET_OS pprDynamicLinkerAsmLabel CodeStub lbl = pprCLabel lbl <> text "@plt" pprDynamicLinkerAsmLabel SymbolPtr lbl diff -rN -u old-ghc/compiler/nativeGen/PIC.hs new-ghc/compiler/nativeGen/PIC.hs --- old-ghc/compiler/nativeGen/PIC.hs 2009-12-29 20:25:56.000000000 +0100 +++ new-ghc/compiler/nativeGen/PIC.hs 2009-12-29 20:25:58.000000000 +0100 @@ -350,6 +350,10 @@ | otherwise = AccessDirectly +-- Use the Linux conventions for FreeBSD +howToAccessLabel dflags arch OSFreeBSD refKind lbl + = howToAccessLabel dflags arch OSLinux refKind lbl + -- all other platforms howToAccessLabel _ _ _ _ _ | not opt_PIC @@ -406,6 +410,9 @@ in result +picRelative arch OSFreeBSD lbl + = picRelative arch OSLinux lbl + picRelative _ _ _ = panic "PositionIndependentCode.picRelative undefined for this platform" @@ -734,6 +741,8 @@ where BasicBlock bID insns = head blocks b' = BasicBlock bID (PPC.FETCHPC picReg : insns) +initializePicBase_ppc ArchPPC OSFreeBSD picReg insn + = initializePicBase_ppc ArchPPC OSLinux picReg insn initializePicBase_ppc _ _ _ _ = panic "initializePicBase_ppc: not needed" @@ -764,6 +773,9 @@ where BasicBlock bID insns = head blocks b' = BasicBlock bID (X86.FETCHPC picReg : insns) +initializePicBase_x86 ArchX86 OSFreeBSD picReg insn + = initializePicBase_x86 ArchX86 OSLinux picReg insn + initializePicBase_x86 _ _ _ _ = panic "initializePicBase_x86: not needed" diff -rN -u old-ghc/compiler/nativeGen/Platform.hs new-ghc/compiler/nativeGen/Platform.hs --- old-ghc/compiler/nativeGen/Platform.hs 2009-12-29 20:25:56.000000000 +0100 +++ new-ghc/compiler/nativeGen/Platform.hs 2009-12-29 20:25:58.000000000 +0100 @@ -47,6 +47,7 @@ | OSDarwin | OSSolaris | OSMinGW32 + | OSFreeBSD deriving (Show, Eq) @@ -86,6 +87,8 @@ defaultTargetOS = OSSolaris #elif mingw32_TARGET_OS defaultTargetOS = OSMinGW32 +#elif freebsd_TARGET_OS +defaultTargetOS = OSFreeBSD #else defaultTargetOS = OSUnknown #endif diff -rN -u old-ghc/libffi/ghc.mk new-ghc/libffi/ghc.mk --- old-ghc/libffi/ghc.mk 2009-12-29 20:25:56.000000000 +0100 +++ new-ghc/libffi/ghc.mk 2009-12-29 20:25:59.000000000 +0100 @@ -88,8 +88,7 @@ libffi_DYNAMIC_LIBS = libffi/libffi$(soext) libffi/libffi.5$(soext) libffi/libffi.5.0.9$(soext) else libffi_DYNAMIC_LIBS = libffi/dist-install/build/libffi.so \ - libffi/dist-install/build/libffi.so.5 \ - libffi/dist-install/build/libffi.so.5.0.9 + libffi/dist-install/build/libffi.so.5 endif endif diff -rN -u old-ghc/mk/config.mk.in new-ghc/mk/config.mk.in --- old-ghc/mk/config.mk.in 2009-12-29 20:25:57.000000000 +0100 +++ new-ghc/mk/config.mk.in 2009-12-29 20:26:00.000000000 +0100 @@ -102,7 +102,7 @@ GhcLibProfiled=$(if $(filter p,$(GhcLibWays)),YES,NO) # Do we support shared libs? -PlatformSupportsSharedLibs = $(if $(filter $(TARGETPLATFORM),i386-unknown-linux x86_64-unknown-linux),YES,NO) +PlatformSupportsSharedLibs = $(if $(filter $(TARGETPLATFORM),i386-unknown-linux x86_64-unknown-linux i386-unknown-freebsd),YES,NO) # ToDo later: # buildstaticli...@buildstaticlibs@ diff -rN -u old-ghc/rules/build-dependencies.mk new-ghc/rules/build-dependencies.mk --- old-ghc/rules/build-dependencies.mk 2009-12-29 20:25:57.000000000 +0100 +++ new-ghc/rules/build-dependencies.mk 2009-12-29 20:26:00.000000000 +0100 @@ -110,6 +110,6 @@ define addCFileDeps $(CPP) $($1_$2_MKDEPENDC_OPTS) $($1_$2_v_ALL_CC_OPTS) $($(basename $4)_CC_OPTS) -MM $4 -MF $3.bit - $(foreach w,$5,sed -e "1s|\.o|\.$($w_osuf)|" -e "1s|^|$(dir $4)|" -e "1s|$1/|$1/$2/build/|" -e "1s|$2/build/$2/build|$2/build|g" -e "s|$(TOP)/||gi" $3.bit >> $3.tmp &&) true + $(foreach w,$5,sed -e "1s|\.o|\.$($w_osuf)|" -e "1s|^|$(dir $4)|" -e "1s|$1/|$1/$2/build/|" -e "1s|$2/build/$2/build|$2/build|g" -e "s|$(TOP)/||gI" $3.bit >> $3.tmp &&) true endef
_______________________________________________ Cvs-ghc mailing list Cvs-ghc@haskell.org http://www.haskell.org/mailman/listinfo/cvs-ghc