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

Reply via email to