Bug 190851

Summary: lang/mono build broken when using binutils from ports
Product: Ports & Packages Reporter: Don Lewis <truckman>
Component: Individual Port(s)Assignee: freebsd-mono (Nobody) <mono>
Status: Closed FIXED    
Severity: Affects Some People CC: jcfyecrayz, romain
Priority: ---    
Version: Latest   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
hack loader script to work with binutils-2.24 port's ld(1)
none
disable local symbol wildcarding for linking executables (vs. libs) none

Description Don Lewis freebsd_committer freebsd_triage 2014-06-10 01:03:22 UTC
Update r355323 to lang/mono/Makefile broke the mono build on FreeBSD 8.4-STABLE.

FreeBSD scratch.catspoiler.org 8.4-STABLE FreeBSD 8.4-STABLE #80 r266818M: Thu May 29 02:41:55 PDT 2014     dl@scratch.catspoiler.org:/usr/obj/usr/src/sys/GENERICDDB  i386

mono-3.4.0_1
binutils-2.24
clang33-3.3_6

When I attempt to build mono in this environment, it fails like this:

  CC     libmini_static_la-tramp-x86.lo
  CC     libmini_static_la-mini-posix.lo
  CXXLD  libmini.la
  CCLD   libmonoboehm-2.0.la
  CCLD   libmonosgen-2.0.la
  CXXLD  libmini-static.la
  CC     mono_boehm-main.o
  CC     mono_sgen-main-sgen.o
  CCLD   mono-boehm
  CCLD   mono-sgen
/usr/local/bin/ld: mono-boehm: local symbol `__progname' in /usr/lib/crt1.o is referenced by DSO
/usr/local/bin/ld: final link failed: Bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gmake[4]: *** [mono-boehm] Error 1
gmake[4]: *** Waiting for unfinished jobs....
/usr/local/bin/ld: mono-sgen: local symbol `__progname' in /usr/lib/crt1.o is referenced by DSO
/usr/local/bin/ld: final link failed: Bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gmake[4]: *** [mono-sgen] Error 1
gmake[4]: Leaving directory `/usr/ports/lang/mono/work/mono-3.4.0/mono/mini'
gmake[3]: *** [all] Error 2
gmake[3]: Leaving directory `/usr/ports/lang/mono/work/mono-3.4.0/mono/mini'
gmake[2]: *** [all-recursive] Error 1
gmake[2]: Leaving directory `/usr/ports/lang/mono/work/mono-3.4.0/mono'
gmake[1]: *** [all-recursive] Error 1
gmake[1]: Leaving directory `/usr/ports/lang/mono/work/mono-3.4.0'
gmake: *** [all] Error 2
===> Compilation failed unexpectedly.
Try to set MAKE_JOBS_UNSAFE=yes and rebuild before reporting the failure to
the maintainer.
*** Error code 1


One of the changes to lang/mono/Makefile in r355323 was the replacement of
some logic to force the use of clang33 for ${OSVERSION} < 902001 with
USES=compiler:c11.  In ports/Mk/Uses/compiler.mk, there is some logic c11
also results in clang33 being chosen for the compiler.  There is some additional logic:

.if ${OSVERSION} < 900033
USE_BINUTILS=   yes
LDFLAGS+=       -B${LOCALBASE}/bin
.endif

which causes the mono build to use the ports version of binutils instead of
the version in base.

If I hack ports/Mk/Uses/compiler.mk like this:

Index: Mk/Uses/compiler.mk
===================================================================
--- Mk/Uses/compiler.mk	(revision 356868)
+++ Mk/Uses/compiler.mk	(working copy)
@@ -154,8 +154,8 @@
 CXX=	${LOCALBASE}/bin/clang++33
 CHOSEN_COMPILER_TYPE=	clang
 .if ${OSVERSION} < 900033
-USE_BINUTILS=	yes
-LDFLAGS+=	-B${LOCALBASE}/bin
+#USE_BINUTILS=	yes
+#LDFLAGS+=	-B${LOCALBASE}/bin
 .endif
 .endif
 .endif
@@ -180,8 +180,8 @@
 CC=	${LOCALBASE}/bin/clang33
 CXX=	${LOCALBASE}/bin/clang++33
 .if ${OSVERSION} < 900033
-USE_BINUTILS=	yes
-LDFLAGS+=	-B${LOCALBASE}/bin
+#USE_BINUTILS=	yes
+#LDFLAGS+=	-B${LOCALBASE}/bin
 .endif
 .endif
 .endif
@@ -206,8 +206,8 @@
 CC=	${LOCALBASE}/bin/clang33
 CXX=	${LOCALBASE}/bin/clang++33
 .if ${OSVERSION} < 900033
-USE_BINUTILS=	yes
-LDFLAGS+=	-B${LOCALBASE}/bin
+#USE_BINUTILS=	yes
+#LDFLAGS+=	-B${LOCALBASE}/bin
 .endif
 .endif
 .endif

the mono build uses the base version of binutils and succeeds.  This is the opposite of my usual experience with binutils on 8.4-STABLE.  Normally the ports version works better than the base version ...
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2014-06-13 04:14:50 UTC
Over to mainainters.
Comment 2 John Hein 2014-06-19 01:49:35 UTC
Created attachment 143916 [details]
hack loader script to work with binutils-2.24 port's ld(1)

I can confirm the same behavior (8-stable/i386, same ports).

Another workaround is attached (add to port as file/patch-mono-mini).
Comment 3 John Hein 2014-06-20 17:12:47 UTC
Here are some more details.  Base OS is using binutils 2.17.50 (+ freebsd changes) or freebsd 8.x is using a base binutils based on 2.15.  Latest port is binutils 2.24.  I think the check that is causing this build failure was added to binutils in 2.21-ish time frame.

See also:
https://sourceware.org/bugzilla/show_bug.cgi?id=13255

Both mono/mini/ldscripts & ldscripts.mono have:

 .
 .
      local:
              *;
 .
 .

Because of this when ld(1) from binutils 2.24 tries to link object files to create a binary executable, it notices that crt1.o has __progname defined and libc.so has an undefined reference to __progname.  Normally this link together just fine, but via the linker script we've told it that all symbols that are not the explicitly listed global symbols are local symbols.  So ld(1) refuses to resolve the libc->crt1.o dependency for __progname and spits out the 'local symbol is reference by DSO' message.

I'm pondering the best way to fix this. Maybe:

 (1) add __progname & environ to globals list in the linker script like my previous attached patch.  This is specific to platforms like freebsd that define __progname (and environ) in one object file (crt1.o) and reference it in a DSO (libc.so).

 (2) remove 'local: *' from the linker script used for producing programs (as opposed to shared libs) - namely mono/mini/ldscripts.mono.  We don't really care whether symbols are marked global or local in the executable images, just the shared libs.

 (3) modify Makefile.am (&/or Makefile.in for the mono port since lang/mono doesn't currently re-run the auto* tools) to not use the linker script for the executables, just for the shared libs.

I think I prefer (2) and that seems most likely acceptable for upstream (although I haven't opened a bug there yet).
Comment 4 John Hein 2014-06-20 17:18:39 UTC
Created attachment 143970 [details]
disable local symbol wildcarding for linking executables (vs. libs)

This diff implements (2) described in comment 3.
Comment 5 John Hein 2014-06-20 17:44:39 UTC
I submitted a bug upstream:

https://bugzilla.xamarin.com/show_bug.cgi?id=20762
Comment 6 Romain Tartière freebsd_committer freebsd_triage 2014-06-20 18:44:31 UTC
This has been a recurring problem, from time to time a similar PR is opened, the proposed fix (adding __progname + environ) often breaked build on my system (recent FreeBSD ususaly), and without being in capacity of reproducting the problem, PR got stall then closed :-(.

Thank you for your deep inspection of the situation.  I'll try the proposed patch ASAP.
Comment 7 Romain Tartière freebsd_committer freebsd_triage 2014-06-25 09:37:09 UTC
Seems fine:
https://redports.org/buildarchive/20140625085501-22082/
Comment 8 commit-hook freebsd_committer freebsd_triage 2014-06-25 09:41:09 UTC
A commit references this bug:

Author: romain
Date: Wed Jun 25 09:40:16 UTC 2014
New revision: 359212
URL: http://svnweb.freebsd.org/changeset/ports/359212

Log:
  Unbreak on FreeBSD 8.4.

  PR:		ports/190851
  Submitted by:	truckman

Changes:
  head/lang/mono/Makefile
  head/lang/mono/files/patch-mono-mini-ldscript.mono