Hi - As you probably already know, there can only be one version of
libstdc++.so in your runtime link chain - This is usually not a problem,
but when things are linked against the Steam runtime (for example), they
can end up with two - one from the steam runtime, and one pulled in via
the mesa dri libs from the OS/distribution.

In order to address this, Valve asked Collabora to look at enabling
mesa linking with libstdcc+.a/libgcc.a/libgcc_eh.a instead of
listdcc++so and libgcc_s.so.

I think I've figured out a minimally intrusive way to do this, working
around the fact that libtool really, really wants to link those in
if C++ is involved.

I've broken this up into a couple of pieces:

The first patch attached gets libtool to not link in the .so
files in question: It's pretty small - it doesn't introduce a
configure flag to control this behaviour, but I would be happy
to adapt it to do so if that's considered a better approach.

The second and third extend this a little further: Patch #3
is actually to llvm, and builds a parallel libLLVM-X.Y-nostdlib.so
which is likewise linked with libstdc++.a et al instead of .so,
and patch #2 makes the mesa build system use said library if it
is available.

So: Would mesa be interested in patches #1 and/or #2?
If not, is there something I could do to make the patches
more palatable, or some other approach that you'd prefer?

( I'm aware of the configure flags to statically link against
  libLLVM, but when I tried it with llvm-3.5 and a git checkout
  of mesa 10.6-dev I got link errors, hence the LLVM patchset. )
From 2c34ec2af17557ecf01bf8977af6ebfcc756e511 Mon Sep 17 00:00:00 2001
From: vivek <vi...@debian-wheezy-0.carnitas.collabora.co.uk>
Date: Tue, 10 Mar 2015 19:41:53 +0000
Subject: [PATCH 1/2] Link libstdc++ and libgcc .a instead of .so

---
 configure.ac                        | 20 ++++++++++++++++++++
 src/gallium/Automake.inc            |  1 +
 src/gallium/targets/dri/Makefile.am |  5 +++++
 3 files changed, 26 insertions(+)

diff --git a/configure.ac b/configure.ac
index 90c7737..3e509a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -705,6 +705,25 @@ AC_ARG_ENABLE([dri],
     [enable_dri="$enableval"],
     [enable_dri=yes])
 
+dnl Strip out unnecessary dynamic linking in of libstdc++ and libgcc_s for
+dnl DRI modules: they cause problems when loaded by games linked against
+dnl a steam runtime with a different libgcc or libstdc++ version:
+if test x$enable_dri != xno;
+then
+AC_MSG_NOTICE([Cleanup libtool C++ postdeps: $postdeps_CXX (enable_dri=$enable_dri)])
+    tmppdcxx=;
+    for x in ${postdeps_CXX};
+    do
+        case $x in
+            -lstdc++) true; ;;
+            -lgcc_s) true; ;;
+            *) tmppdcxx=${tmppdcxx}${tmppdcxx:+ }$x; ;;
+        esac;
+    done;
+    postdeps_CXX="${tmppdcxx}";
+AC_MSG_NOTICE([Cleaned libtool C++ postdeps: $postdeps_CXX])
+fi
+
 case "$host_os" in
 linux*)
     dri3_default=yes
@@ -2450,6 +2469,7 @@ echo "        prefix:          $prefix"
 echo "        exec_prefix:     $exec_prefix"
 echo "        libdir:          $libdir"
 echo "        includedir:      $includedir"
+echo "        postdeps_CXX:    $postdeps_CXX"
 
 dnl API info
 echo ""
diff --git a/src/gallium/Automake.inc b/src/gallium/Automake.inc
index 95aae50..6de79c1 100644
--- a/src/gallium/Automake.inc
+++ b/src/gallium/Automake.inc
@@ -46,6 +46,7 @@ GALLIUM_TARGET_CFLAGS = \
 
 GALLIUM_COMMON_LIB_DEPS = \
 	-lm \
+ 	-l:libgcc.a -l:libgcc_eh.a -l:libstdc++.a \
 	$(CLOCK_LIB) \
 	$(PTHREAD_LIBS) \
 	$(DLOPEN_LIBS)
diff --git a/src/gallium/targets/dri/Makefile.am b/src/gallium/targets/dri/Makefile.am
index aaeb950..5185273 100644
--- a/src/gallium/targets/dri/Makefile.am
+++ b/src/gallium/targets/dri/Makefile.am
@@ -27,6 +27,11 @@ gallium_dri_la_LDFLAGS = \
 	-shrext .so \
 	-module \
 	-avoid-version \
+	-static-libgcc \
+	-static-libstdc++ \
+	-l:libgcc.a \
+	-l:libstdc++.a \
+	-Wl,--exclude-libs -Wl,libgcc.a:libstdc++.a \
 	$(GC_SECTIONS)
 
 if HAVE_LD_VERSION_SCRIPT
-- 
2.1.4

From 186c1ea9927035607822e3b19892b072044e145d Mon Sep 17 00:00:00 2001
From: vivek <vi...@debian-wheezy-0.carnitas.collabora.co.uk>
Date: Tue, 10 Mar 2015 19:44:05 +0000
Subject: [PATCH 2/2] Use -nostdlib libLLVM-X.Y .so variant when present

---
 configure.ac | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/configure.ac b/configure.ac
index 3e509a6..ac8f783 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2208,6 +2208,16 @@ if test "x$MESA_LLVM" != x0; then
         if test "x$llvm_have_one_so" = xyes; then
             dnl LLVM was built using auto*, so there is only one shared object.
             LLVM_LIBS="-l$LLVM_SO_NAME"
+            dnl Find a libLLVM-X.Y variant that doesn't need -lstdc++ -lgcc_s
+            dnl Also: Make sure we don't ask for libstdc++ or libgcc_s explicitly:
+            llvm_so_otherlibdeps=$($LLVM_CONFIG --ldflags)
+            llvm_so_otherlibdeps=$(echo $llvm_so_otherlibdeps | sed -re 's@-lstdc\+\+|-lgcc_s@@g')
+            AC_MSG_CHECKING([for a stdlib-independent lib$LLVM_SO_NAME])
+            AC_CHECK_LIB([$LLVM_SO_NAME-nostdlib],
+                         [LLVMInitializeCore],
+                         [LLVM_LIBS="-l$LLVM_SO_NAME-nostdlib"],
+                         [],
+                         [$llvm_so_otherlibdeps])
         else
             dnl If LLVM was built with CMake, there will be one shared object per
             dnl component.
-- 
2.1.4

Index: llvm-toolchain-3.5-3.5/tools/llvm-shlib/Makefile
===================================================================
--- llvm-toolchain-3.5-3.5.orig/tools/llvm-shlib/Makefile	2015-03-09 16:25:55.000000000 +0000
+++ llvm-toolchain-3.5-3.5/tools/llvm-shlib/Makefile	2015-03-09 20:22:41.864000000 +0000
@@ -40,7 +40,36 @@
 LLVMLibsOptions := $(IncludeInLibLlvm:$(LibDir)/lib%.a=-l%)
 LLVMLibsPaths   := $(IncludeInLibLlvm)
 
+# if ENABLE_EMBED_STDCXX build an extra DSO without linking
+# libgcc_s and libstdc++ dynamically (and don't re-export) their
+# symbols from the resulting shared library either
+ifeq ($(ENABLE_EMBED_STDCXX),1)
+$(EmbeddedLib.SO): $(SHLIB_STUBS)
+$(EmbeddedLib.SO): $(LLVMLibsPaths)
+	$(Echo) "--- Debug "$(notdir $@)" Link Flags ---";
+	$(Echo) EmbedLinkOptions "    is" "$(EmbedLinkOptions)";
+	$(Echo) ProjLibsOptions "     is" "$(ProjLibsOptions)";
+	$(Echo) EmbedLibsOptions "    is" "$(EmbedLibsOptions)";
+	$(Echo) ObjectsO "            is" "$(ObjectsO)";
+	$(Echo) LIBS "                is" "$(LIBS)";
+	$(Echo) "+++ Debug "$(notdir $@)" Link Flags +++";
+	$(Echo) Linking $(BuildMode) $(SharedLibKindMessage) $(EmbeddedLib.SO)
+	$(Verb) $(Link) $(EmbedLinkOptions) -o $@ $(ObjectsO) \
+	  $(ProjLibsOptions) $(EmbedLibsOptions) $(LIBS)
+	mv $(EmbeddedLib.SO) $(EmbeddedLib.SO).1
+	ln -s $(notdir $(EmbeddedLib.SO)).1 $(EmbeddedLib.SO)
+
+$(LibName.SO): $(LLVMLibsPaths) $(EmbeddedLib.SO)
+else
 $(LibName.SO): $(LLVMLibsPaths)
+endif
+	$(Echo) "--- Debug "$(notdir $@)" Link Flags ---";
+	$(Echo) SharedLinkOptions "   is" "$(SharedLinkOptions)";
+	$(Echo) ProjLibsOptions "     is" "$(ProjLibsOptions)";
+	$(Echo) LLVMLibsOptions "     is" "$(LLVMLibsOptions)";
+	$(Echo) ObjectsO "            is" "$(ObjectsO)";
+	$(Echo) LIBS "                is" "$(LIBS)";
+	$(Echo) "+++ Debug "$(notdir $@)" Link Flags +++";
 	$(Echo) Linking $(BuildMode) $(SharedLibKindMessage) \
 	  $(LIBRARYNAME)$(SHLIBEXT)
 	$(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO) \
@@ -80,6 +109,11 @@
     LLVMLibsOptions := -Wl,-z -Wl,allextract $(LLVMLibsOptions)
 endif
 
+ifeq ($(ENABLE_EMBED_STDCXX),1)
+    EmbedLibsOptions := $(patsubst %$(notdir $(LibName.SO)).1,%$(notdir $(EmbeddedLib.SO)).1,$(LLVMLibsOptions))
+    EmbedLinkOptions := $(SharedLinkOptions) -static-libgcc -static-libstdc++ -Wl,--exclude-libs -Wl,libstdc++.a:libgcc.a
+endif
+
 ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
 
 SHLIB_STUBS := $(addprefix $(ObjDir)/, $(SHLIB_FRAG_NAMES))
Index: llvm-toolchain-3.5-3.5/Makefile.rules
===================================================================
--- llvm-toolchain-3.5-3.5.orig/Makefile.rules	2014-06-20 20:00:41.000000000 +0100
+++ llvm-toolchain-3.5-3.5/Makefile.rules	2015-03-09 20:27:08.872000000 +0000
@@ -1164,14 +1164,17 @@
 BaseLibName.A  := $(LIBRARYNAME).a
 BaseLibName.SO := $(LIBRARYNAME)$(SHLIBEXT)
 BaseAliasName.SO := $(LIBRARYALIASNAME)$(SHLIBEXT)
+EmbeddedLib.SO := $(LIBRARYNAME)-nostdlib$(SHLIBEXT)
 else
 BaseLibName.A  := lib$(LIBRARYNAME).a
 BaseLibName.SO := $(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT)
 BaseAliasName.SO := $(SharedPrefix)$(LIBRARYALIASNAME)$(SHLIBEXT)
+EmbeddedLib.SO := $(SharedPrefix)$(LIBRARYNAME)-nostdlib$(SHLIBEXT)
 endif
 LibName.A  := $(LibDir)/$(BaseLibName.A)
 LibName.SO := $(SharedLibDir)/$(BaseLibName.SO)
 AliasName.SO := $(SharedLibDir)/$(BaseAliasName.SO)
+EmbeddedLib.SO := $(SharedLibDir)/$(EmbeddedLib.SO)
 LibName.O  := $(LibDir)/$(LIBRARYNAME).o
 
 #---------------------------------------------------------
@@ -1214,6 +1217,7 @@
 clean-local::
 ifneq ($(strip $(LibName.SO)),)
 	-$(Verb) $(RM) -f $(LibName.SO)
+	-$(Verb) $(RM) -f $(EmbeddedLib.SO)
 endif
 
 ifdef NO_INSTALL
@@ -1231,12 +1235,18 @@
 endif
 DestSharedLib := $(DestSharedLibDir)/$(BaseLibName.SO)
 DestSharedAlias := $(DestSharedLibDir)/$(BaseAliasName.SO)
+DestEmbeddedLib := $(DestSharedLibDir)/$(notdir $(EmbeddedLib.SO))
 
 install-local:: $(DestSharedLib)
 
 $(DestSharedLib): $(LibName.SO) $(DestSharedLibDir)
 	$(Echo) Installing $(BuildMode) Shared Library $(DestSharedLib)
 	$(Verb) $(INSTALL) $(LibName.SO) $(DestSharedLib)
+	$(Verb) if [ -f "$(EmbeddedLib.SO)" ]; \
+	        then                           \
+	            echo Installing $(BuildMode) Shared Library $(DestEmbeddedLib); \
+	            $(INSTALL) $(EmbeddedLib.SO) $(DestEmbeddedLib);                \
+	        fi;
 ifdef SHARED_ALIAS
 	$(Echo) Creating alias from $(DestSharedLib) to $(DestSharedAlias)
 	$(Verb) $(AliasTool) $(BaseLibName.SO) $(DestSharedAlias)
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to