MFH: r499061
Approved by: portmgr (miwi) GCC has two runtime libraries: The static library libgcc.a (-lgcc) and the shared library libgcc_s.so (-lgcc_s). Both implement many of the same functions but they also each have their unique functions. When GCC links programs and libraries there are three possibilities: 1. gcc -static-libgcc or gcc -static: -lgcc => Just use libgcc.a. 2. gcc -shared-libgcc: -lgcc_s -lgcc => Link with libgcc_s first, so libgcc.a is only used for its unique functions. 3. gcc: -lgcc -Wl,--as-needed -lgcc_s -Wl,--no-as-needed => Link with libgcc.a first so libgcc_s is only used for its unique functions (_Unwind_* functions). Approach 3 is the default for gcc and it's also what clang and clang++ use; approach 2 is the default for gfortran, g++ and probably other front ends. This patch makes 3 the default for gfortran. It significantly reduces the use of libgcc_s. The _Unwind_* functions are also available in the old base system libgcc_s which means this reduces the need for -rpath /usr/local/lib/gccN in ports that depend on libraries built with gfortran. Consider a dependency tree like this: prog -> libA -> libgcc_s (old base system libgcc_s is fine) -> libB -> libgcc_s (libB built with gfortran, needs new libgcc_s) Here prog needs to be linked with -rpath /usr/local/lib/gccN even if it's a normal C program compiled with clang. Without -rpath it will fail to start because it loads old libgcc_s first as a dependency of libA and then it fails to load libB. With this patch libB works with old base system libgcc_s or may not need libgcc_s at all, so prog does not need to be linked with -rpath. PR: 208120 Submitted by: tijl
This commit is contained in:
parent
c958c606a8
commit
a86c2dfa1a
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/branches/2019Q2/; revision=500211
@ -3,7 +3,7 @@
|
||||
|
||||
PORTNAME= gcc
|
||||
PORTVERSION= 8.3.0
|
||||
PORTREVISION= 1
|
||||
PORTREVISION= 2
|
||||
CATEGORIES= lang
|
||||
MASTER_SITES= GCC
|
||||
PKGNAMESUFFIX= ${SUFFIX}
|
||||
|
70
lang/gcc8/files/patch-gfortran-libgcc
Normal file
70
lang/gcc8/files/patch-gfortran-libgcc
Normal file
@ -0,0 +1,70 @@
|
||||
GCC has two runtime libraries: The static library libgcc.a (-lgcc) and
|
||||
the shared library libgcc_s.so (-lgcc_s). Both implement many of the
|
||||
same functions but they also each have their unique functions. When
|
||||
gcc links programs and libraries there are three possibilities:
|
||||
|
||||
1. gcc -static-libgcc or gcc -static: -lgcc
|
||||
=> Just use libgcc.a.
|
||||
|
||||
2. gcc -shared-libgcc: -lgcc_s -lgcc
|
||||
=> Link with libgcc_s first, so libgcc.a is only used for its unique
|
||||
functions.
|
||||
|
||||
3. gcc: -lgcc -Wl,--as-needed -lgcc_s -Wl,--no-as-needed
|
||||
=> Link with libgcc.a first so libgcc_s is only used for its unique
|
||||
functions (_Unwind_* functions).
|
||||
|
||||
Approach 3 is the default for gcc and it's also what clang and clang++ use;
|
||||
approach 2 is the default for gfortran, g++ and probably other front ends.
|
||||
|
||||
This patch makes 3 the default for gfortran. It significantly reduces
|
||||
the use of libgcc_s. The _Unwind_* functions are also available in the
|
||||
old base system libgcc_s which means this reduces the need for
|
||||
-rpath /usr/local/lib/gccN in ports that depend on libraries built with
|
||||
gfortran. Consider a dependency tree like this:
|
||||
|
||||
prog -> libA -> libgcc_s (old base system libgcc_s is fine)
|
||||
-> libB -> libgcc_s (libB built with gfortran, needs new libgcc_s)
|
||||
|
||||
Here prog needs to be linked with -rpath /usr/local/lib/gccN even if it's
|
||||
a normal C program compiled with clang. Without -rpath it will fail to
|
||||
start because it loads old libgcc_s first as a dependency of libA and then
|
||||
it fails to load libB. With this patch libB works with old base system
|
||||
libgcc_s or may not need libgcc_s at all, so prog does not need to be
|
||||
linked with -rpath.
|
||||
|
||||
Upstream is unlikely accept a patch like this because libgfortran calls
|
||||
some _Unwind_* functions and so always needs libgcc_s. Also because
|
||||
every Fortran program and library links to libgfortran it makes sense
|
||||
that option 2 above is the default. On FreeBSD where clang and GCC
|
||||
compiled code can be mixed and where multiple libgcc_s may be installed,
|
||||
option 3 is just a lot easier to deal with.
|
||||
|
||||
The bug that sparked this is PR 208120 (but note there's a lot of
|
||||
misleading information in that bug. CMake is not actually doing
|
||||
anything wrong.)
|
||||
|
||||
--- UTC
|
||||
--- gcc/fortran/gfortranspec.c.orig 2015-06-26 17:47:23 UTC
|
||||
+++ gcc/fortran/gfortranspec.c
|
||||
@@ -404,7 +404,7 @@ For more information about these matters
|
||||
}
|
||||
}
|
||||
|
||||
-#ifdef ENABLE_SHARED_LIBGCC
|
||||
+#if 0
|
||||
if (library)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
--- libgfortran/Makefile.in.orig 2019-02-22 14:22:13.000000000 +0000
|
||||
+++ libgfortran/Makefile.in 2019-02-27 16:27:08.856408000 +0000
|
||||
@@ -625,7 +625,7 @@
|
||||
$(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \
|
||||
$(HWCAP_LDFLAGS) \
|
||||
-lm $(extra_ldflags_libgfortran) \
|
||||
- $(version_arg) -Wc,-shared-libgcc
|
||||
+ $(version_arg)
|
||||
|
||||
libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP)
|
||||
cafexeclib_LTLIBRARIES = libcaf_single.la
|
Loading…
Reference in New Issue
Block a user