aboutsummaryrefslogtreecommitdiff
path: root/lang/gcc12-devel/files/patch-gfortran-libgcc
blob: c29c7edc14f44e0e611620a669fe60ae77a04468 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
+++ libgfortran/Makefile.in
@@ -736,7 +736,7 @@
 	$(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \
 	$(HWCAP_LDFLAGS) \
	$(LIBM) $(extra_ldflags_libgfortran) \
-	$(version_arg) -Wc,-shared-libgcc
+	$(version_arg)
 
 libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP)
 cafexeclib_LTLIBRARIES = libcaf_single.la