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