Created attachment 168368 [details] Fix for RPATH bug with gfortran Cmake strips local RPATH as it installs, this also strips the needed RPATH for gfortran and gcc (non base gcc). Symptoms in the fortran case is it tries to use the base /lib/libgcc_s.so instead of ${LOCALBASE}/lib/gcc${_GCC_VER} This result in a failure at run time since our base libgcc_s is not compatible with gfortran's version. After back and forth email/IRC discussion with groot@kde.org Adriaan came up with this final suggested patch to cmake-modules. N.B. The same bug using gcc g++ from ports has not been addressed here since they also should be using ${LOCALBASE} libgcc_s.so not base libgcc_s.so An exp run is suggested with this change.
tweak subject, and assign to cmake maintainers.
Uses/cmake.mk could be touched instead. --- /usr/ports/Mk/Uses/cmake.mk 2016-03-17 15:49:04.000000000 -0400 +++ /usr/ports/Mk/Uses/cmake.mk.new 2016-03-13 12:36:39.000000000 -0400 @@ -69,7 +69,9 @@ CMAKE_ARGS+= -DCMAKE_C_COMPILER:STRING="${CC}" \ -DCMAKE_CXX_COMPILER:STRING="${CXX}" \ -DCMAKE_C_FLAGS:STRING="${CFLAGS}" \ + -DCMAKE_Fortran_FLAGS_DEBUG:STRING="${FFLAGS}" \ -DCMAKE_C_FLAGS_DEBUG:STRING="${CFLAGS}" \ + -DCMAKE_Fortran_FLAGS_RELEASE:STRING="${FFLAGS}" \ -DCMAKE_C_FLAGS_RELEASE:STRING="${CFLAGS}" \ -DCMAKE_CXX_FLAGS:STRING="${CXXFLAGS}" \ -DCMAKE_CXX_FLAGS_DEBUG:STRING="${CXXFLAGS}" \ @@ -80,7 +82,8 @@ -DCMAKE_INSTALL_PREFIX:PATH="${CMAKE_INSTALL_PREFIX}" \ -DCMAKE_BUILD_TYPE:STRING="${CMAKE_BUILD_TYPE}" \ -DTHREADS_HAVE_PTHREAD_ARG:BOOL=YES \ - -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=YES + -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=YES \ + -DCMAKE_INSTALL_RPATH:STRING="${LOCALBASE}/lib/gcc${_GCC_VER}" CMAKE_INSTALL_PREFIX?= ${PREFIX} This diff isn't quite right since it unconditionally always adds CMAKE_INSTALL_RPATH
This problem also affects arm and armv6. Ports that are built with gcc (from ports, not the old one in base) will have references to symbols named __aeabi_* which are compiler helper routines to implement the arm abi. Our libgcc_s and libc in base (both are involved, for arcane reasons) export a small subset of the __aeabi routines, just the ones referenced by gcc 4.2.1. I have no opinion on how to fix it, just pointing out that trying to use the libgcc_s from base instead of the one in $LOCALBASE that matches the gcc used to build the port is a real problem on arm.
Created attachment 168796 [details] Simple GNU Radio test network failure case This sample network fails to compile, with gnuradio-companion failing: ImportError: /lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc48/libgfortran.so.3 not found
So the patch attached, which fixes up things in the fortran cmake modules, isn't general enough. This should be done in the GNU module, or any module that notices that it's using gcc as the backend. I can futz around with the patch in order to make it more general. I can use both ARM (e.g. on my Beagle Bone) and GNU Radio as test cases for making this work, but no guarantees on a delivery date.
It also affects gcc from ports as well and not just gfortran, though the bug is not as evident.
Created attachment 168925 [details] Self-contained fortran+CMake example To me, CMake does not seem to be doing anything wrong or unusual here. lang/gcc's pkg-message says: > To ensure binaries built with this toolchain find appropriate versions > of the necessary run-time libraries, you may want to link using > > -Wl,-rpath=/usr/local/lib/gcc48 > > For ports leveraging USE_GCC, USES=compiler, or USES=fortran this happens > transparently. Indeed, if I just do `gcc48 hello.c' I get a binary that depends (via DT_NEEDED) on libstdc++.so.6 and libgcc_so.1 (among other libraries) but with no RPATH. And obviously I pass -Wl,rpath=/usr/local/lib/gcc48 I get a binary that depends on those two libraries and has a DT_RPATH entry set to /usr/local/lib/gcc48 (and ldd shows that both libstdc++.so.6 and libgcc_so.1 come from GCC 4.8's directory). And if instead of calling `gcc48' (or `gfortran48') I create a CMakeLists.txt and get CMake to generate a Makefile that will call the compiler, the results are exactly the same, regardless of whether I pass -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=YES to CMake or not. And then if I want to use the ports tree infrastructure to call CMake for me, I also get the same results. I'm attaching a .shar file with a test port called "bug208120" that does exactly this (the source is based on code sent to me by email by Ade and Diane). You can build it like a regular port, install it and the "bug208120" binary will work just fine. It is also possible to just build the code on your own and bypass the ports tree bits with `cd files && mkdir build && cd build && FFLAGS=-Wl,-rpath=/usr/local/lib/gcc48 cmake .. && make VERBOSE=1'. > This sample network fails to compile, with gnuradio-companion failing: ImportError: /lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc48/libgfortran.so.3 not found I tried looking for "gfortran48" invocations in http://beefy4.nyi.freebsd.org/bulk/latest-per-pkg/gnuradio/3.7.8/head-amd64-default.log, and comms/gnuradio only appears to have a USE_GCC=yes entry for FreeBSD 9.x. It's unclear to me what is linking against libgfortran.so and how. It might be the case that some Python library used by GNU Radio is trying to dlopen() libgfortran, or it's actually a port that comms/gnuradio depends on that is doing something wrong. > This problem also affects arm and armv6. I'm interested in hearing more about this. My knowledge about ARM and the ports tree is zero, so please assume you're talking to a 5-year-old :-) Do you have a link to a build log for a port that is being built incorrectly (ie. without the right RPATH even though it is being passed to the linker)? Where/how should I start if I wanted to investigate this and do my own tests?
(In reply to Raphael Kubo da Costa from comment #7) > lang/gcc's pkg-message says: > > To ensure binaries built with this toolchain find appropriate versions > > of the necessary run-time libraries, you may want to link using > > > > > -Wl,-rpath=/usr/local/lib/gcc48 > > > > > For ports leveraging USE_GCC, USES=compiler, or USES=fortran this happens > > transparently. That's fine. I think the issue is more about the expectations when using a different build system on top. In other words, what do you get with USES=compiler and cmake as a build system inside the port? I would expect a port using CMake as build system and USES=fortran to link to the right bits. With the attached self-contained example, on 10.2 amd64, the resulting executable does indeed link to the right libgcc_s.so, so it seems that CMake is already doing the right thing in at least some cases. I'll try the same thing on my BB for the ARM case next.
.. so far, we've mostly been talking about ports, where the infrastructure helps with inserting the right linker flags, and comment:7 points out that it seems to DTRT. But what about non-ports builds? Can we do something to make CMake a helpful and useful build system on FreeBSD? Having to remember the pkg-message from gcc48 is less convenient than having CMake itself DTRT when it runs into gcc.
Sure. My original thought was it belonged in cmake.mk anyway! groot@ convinced me it should go in cmake port itself and myself don't care. The pkg-message is -Wl,-rpath=%%TARGLIB%% Which is dutifully added with USES= fortran but cmake.mk doesn't pick up the rpath variable. That entire string is what is exposed out of the port make subsystem and available to the port Makefile. We know at port build time that we are using fortran hence would know to add the TARGLIB magic but TARGLIB is not exposed. Examining Uses fortran.mk I note FFLAGS+= -Wl,-rpath=${LOCALBASE}/lib/gcc${_GCC_VER} If _GCC_VER was available in the Makefile for the port I simply would have added CMAKE_ARGS+= -DCMAKE_INSTALL_RPATH::STRING="${LOCALBASE}/lib/gcc${_GCC_VER}" and be done with it. Similar could be done with GCC if set. Thoughts?
Simpler fix to compiler.mk Index: compiler.mk =================================================================== --- compiler.mk (revision 416615) +++ compiler.mk (working copy) @@ -248,3 +248,7 @@ .endif .endif + +.if ${CHOSEN_COMPILER_TYPE == gcc } +CMAKE_ARGS+= -DCMAKE_INSTALL_RPATH:STRING="${LOCALBASE}/lib/gcc${_GCC_VER}" +.endif
See https://people.freebsd.org/~db/libgcc_summary.txt
Note that this issue is intended to be the one that identifies and isolates the root cause of the symptoms, therebyte resolving all blocked issues (at the time of writing 4) If cmake stripping rpath turns out not to be the root cause, the summary should be updated as more information comes to hand
Received this work-around by private email: I think I found a work-around that fixes *runtime* dynamic linking issues. I added the following line to /etc/libmap.conf: libgcc_s.so.1 gcc48/libgcc_s.so.1 This seems to have solved a number of issues that I have had involving Fortran, including numpy and scilab.
This ticket is languishing *mostly* because it's unclear what the right course is (there's no WWJD for cmake behavior in the presence of gcc on FreeBSD). Diane Bruce in comment:12 explains the issues and has two fixes: - fix things in cmake - fix individual ports using cmake The workaround posted here in comment:14 takes another tack and fixes "everything" that uses libgcc_s by mapping it to a gcc-version-specific library. The example program referenced in comment:12 compiles a Fortran program like so: gfortran sum.f90 This program doesn't run, because it links to the wrong libgcc_s.so. So there's at least four questions we can ask: - should Fortran programs, compiled naively, run out-of-the-box? (they don't, currently) - should Fortran programs, compiled with -Wl,rpath, run OOB? (yes) - should Fortran programs, compiled using a build-system, run OOB? - should Fortran programs, compiled using a build-system and a specific workaround, run OOB? The workround / fix in comment:14 answers all of these four questions with "yes". Fixing things in cmake answers the last two questions with "yes"; working around in ports answers just the last one with "yes". Personally I think that the build-system should DTRT as much as possible to deliver a working executable, and that the rpath-fix for gcc-compilers should be added in cmake.
The problem with the fix mentioned in comment #14 is it then forces everything compiled with native compilers to use a port based libgcc_s which might be seen as a feature, not a bug by some. ;) Our libgcc_s is not GPL code at all, it is our own code. It just happens to be compatible with gcc's libgcc_s except apparently for gfortran. We don't have our own BSDL libquadmath and gfortran requires libquadmath which is enforced by libgfortran insisting it needs a later version of libgcc_s than we claim to be compatible with. ;) And that's what the error message is telling us! "ImportError: /lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc48/libgfortran.so.3 not found" libgfortran requires GCC_4.6.0 or later and our libgcc_s is only GCC_4.2.0 (from memory) compliant. You can use elfdump to see this elfdump -a /usr/lib/libgcc_s.so|grep GCC st_name: GCC_3.0 st_name: GCC_3.3 st_name: GCC_3.4 st_name: GCC_4.2.0 st_name: GCC_4.3.0 st_name: GCC_3.3.1 st_name: GCC_3.4.2 st_name: GCC_3.4.4 st_name: GCC_4.0.0 vs. elfdump -a /usr/local/lib/gcc49/libgcc_s.so|grep GCC st_name: GCC_3.3.1 st_name: GCC_4.0.0 st_name: GCC_3.0 st_name: GCC_3.4 st_name: GCC_4.6.0 st_name: GCC_4.7.0 st_name: GCC_3.4.2 st_name: GCC_3.4.4 st_name: GCC_4.2.0 st_name: GCC_4.3.0 st_name: GCC_3.3 st_name: GCC_4.8.0 st_name: GCC_3.3.1 st_name: GCC_4.0.0 st_name: GCC_3.0 st_name: GCC_3.4 st_name: GCC_4.6.0 st_name: GCC_4.7.0 st_name: GCC_3.4.2 st_name: GCC_3.4.4 st_name: GCC_4.2.0 st_name: GCC_4.3.0 st_name: GCC_3.3 st_name: GCC_4.8.0 Time for me to poke at portmgr ;)
(In reply to Diane Bruce from comment #11) Putting this workaround in compiler.mk will not solve the issue, USE_GCC=yes or USES=fortran don't include compiler.mk
comment #17 good point.
If an executable depends on a library (including indirect dependencies) that needs a particular rpath then that executable should also be linked with that rpath. Here's an example that shows why: program links to libA which links to (old) libgcc_s links to libB which requires new libgcc_s If program does not have an rpath then rtld(1) will load old libgcc_s as part of loading libA and then fail when loading libB. Translated to Fortran ports this becomes: If a port installs an executable that depends on a library from another port (including indirect dependencies) that has USES=fortran then that port should also set USES=fortran. It doesn't matter what compiler that port is compiled with (including clang!) so there are no (simple) hacks you can add to files under Mk or to cmake to detect this case. Just add USES=fortran (perhaps with a comment that explains why). That said, I recently found out that gfortran, g++ and gcj call the gcc backend with -shared-libgcc which means they link pretty much every program and library with libgcc_s. Clang, clang++ and gcc don't do that and instead link with "-lgcc -Wl,--as-needed -lgcc_s -Wl,--no-as-needed". Because libgcc (static library) contains all symbols from libgcc_s except _Unwind_*, libgcc_s is almost never needed, only for code that needs stack unwinding (for instance to throw and catch exceptions). Because Fortran as far as I know doesn't support exceptions, patching gfortran to remove -shared-libgcc would remove pretty much all links to libgcc_s from Fortran libraries. They would still link to libgfortran but there's no libgfortran in base to cause trouble. There could still be trouble when mixing libraries compiled with different versions of gfortran, which may happen on user systems when the default gcc version has been changed. In this case it would still be good if ports that depend on ports that have USES=fortran also set USES=fortran.
In comment #19 "It doesn't matter what compiler that port is compiled with (including clang!) so there are no (simple) hacks you can add to files under Mk or to cmake to detect this case. Just add USES=fortran (perhaps with a comment that explains why)." which brings us back to part of the original problem. ;) cmake subsystem is not truly honouring the spirit of USES=fortran as it is. Re-read groot's comment #15 "Personally I think that the build-system should DTRT as much as possible to deliver a working executable, and that the rpath-fix for gcc-compilers should be added in cmake." This suggests the proper fix would be in Modules/CheckFortranCompilerFlag.cmake to ensure the rpath is honoured. However, it would then miss the USES_GCC flag which also sets rpath in Mk/bsd.gcc.mk. I would suggest the fix needs to be applied to both Mk/bsd.gcc.mk and Mk/Uses/fortran.mk Something like the fix mentioned in comment #10 CMAKE_ARGS+= -DCMAKE_INSTALL_RPATH:STRING="${LOCALBASE}/lib/gcc${_GCC_VER}" I agree with the last part of comment #19 "Because Fortran as far as I know doesn't support exceptions, patching gfortran to remove -shared-libgcc would remove pretty much all links to libgcc_s from Fortran libraries. They would still link to libgfortran but there's no libgfortran in base to cause trouble. There could still be trouble when mixing libraries compiled with different versions of gfortran, which may happen on user systems when the default gcc version has been changed. In this case it would still be good if ports that depend on ports that have USES=fortran also set USES=fortran." with the caveat that we still have a problem when a program references libgcc_s and is running with base libgcc_s then dlopen's a module which was compiled against another libgcc_s not in base. In the case of a gfortran compiled module, it will "want" libgfortran which will "need" a later libgcc_s version than we currently support in base and *then* fail. ;) And as groot mentions we still do not DTRT without the make system 'helping'. (We cannot due to the name clash) I discussed this in depth with a few others from toolchains on IRC. The proposed fix I suggest is merely a stopgap until our libgcc_s can be brought up to date. We are missing (from the gfortran viewpoint) libquadmath. We could "lie" in our libgcc_s and it would be perfectly fine (BTW I've briefly tested this), but the better solution is not to bump the claimed version. e.g. readelf -a /usr/local/lib/gcc49/libgcc_s.so Version definition section '.gnu.version_d' contains 13 entries: Addr: 0x0000000000001fb8 Offset: 0x001fb8 Link: 3 (.dynstr) 000000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: libgcc_s.so.1 0x001c: Rev: 1 Flags: none Index: 2 Cnt: 1 Name: GCC_3.0 ... I don't have the final answer. All I want to do now is ensure this problem is well documented so others know the workaround. ;)
What do you mean with "spirit of USES=fortran"? What do you think cmake is doing wrong exactly? The example port in comment 7 shows that cmake is working correctly. dlopen libraries are the same as normal libraries. If a port needs to dlopen a library that depends on newer libgfortran/libgcc_s, the port needs USES=fortran.
I see a lot of talk here about fortran and USES=fortran as some sort of fix. I'd just like to remind folks that this is not a fortran problem, it's a generalized toolchain problem that has at its root our deficient libgcc_s in base. See comment #3 for details of how/why this isn't a fortran problem. An actual solution, whatever that might be, will have nothing to do with fortran per se, and will somehow fix the problem of ports finding the right copy of the compiler support libraries for the compiler that built the port.
(In reply to groot from comment #14) I caught someone using this libmap trick at work recently for numpy. This is not something we should be doing in production and it will break anyway when default gcc changes, which is now GCC 4.9 in the ports tree. I'd also like to see the ports tree ensuring this problem does not exist.
Created attachment 179810 [details] remove -shared-libgcc from gfortran Here's a patch for lang/gcc that removes use of -shared-libgcc from gfortran and libgfortan. It means libgcc_s is only used for _Unwind_* functions which the base system libgcc_s provides as well so use of -rpath becomes less important. This makes gfortran behave the same as gcc, clang and clang++. g++ and probably also gcj still use -shared-libgcc.
(In reply to Tijl Coosemans from comment #24) I like this idea the best. It solves our current problem in all cases.
I like solution from #24, but unfortunately, libgfortran is still linked with GCC version of libgcc_s.so. And GCC version of libgcc_s.so exports _Unwind_Backtrace with GCC_4.3.0 namespace/version, while base version provides it within GCC_3.3 namespace.
Hmm, it seems that symbol version problem is ARM specific. It's introduced by this commit: https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=128088 Unfortunately, commit log doesn't give any information why :( In all cases, I can fix this in your base libgcc_s, so please don't take the my previous comment into account.
cmake doesn't appear to be the right place for a solution, because the problem isn't related to cmake. The core of the problem is the presence of two versions of libgcc in the system. This can't be changed in cmake. One of the versions needs to be eliminated. Either the base libgcc should be deleted and some other implementation of the Unwind interface should be adopted, or fortran's libgcc.so should be deleted, and replaced with statically linked version if this is at all possible.
(In reply to Yuri Victorovich from comment #28) See my various notes on this subject. https://people.freebsd.org/~db/libgcc.txt https://people.freebsd.org/~db/libgcc_removal_proposal.log Agreed. It's not just a cmake problem. However, it appears cmake is DTRT although I thought groot@kde.org managed to duplicate my original error. There may never have been a problem and I got it wrong. No matter. It was never intended as a fix for the entire problem anyway. We have to as you noted again after I noted it months ago ;) we either need a replacement libgcc that works, or a working libquadmath that references our libgcc or a static libcc. The static libgcc was looked at (I'll have to check my emails on this) but a conflict was found with libunwind. (Which you have noted is a problem) What I now believe to be happening is the following scenario. A program such as python is compiled. In python2.7 case, there is no reference to a libgcc at all hence no libgcc is linked. It then loads a module that *does* reference libgcc, however it is the "wrong" libgcc. e.g. ldd -a /usr/local/lib/libwx_gtk2u_stc-3.0.so|grep gcc libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x80931f000) ... Then the python program loads another module *which was* compiled against gfortran or even gcc. e.g. openblas or atlas ldd /usr/local/lib/libblas.so /usr/local/lib/libblas.so: libgfortran.so.3 => /usr/local/lib/gcc5/libgfortran.so.3 (0x801252000) libm.so.5 => /lib/libm.so.5 (0x801574000) libgcc_s.so.1 => /usr/local/lib/gcc5/libgcc_s.so.1 (0x80179f000) libquadmath.so.0 => /usr/local/lib/gcc5/libquadmath.so.0 (0x8019b5000) libc.so.7 => /lib/libc.so.7 (0x800823000) and. boom. hilarity results. One possible solution that would work in the interim for many ports is a non gfortran version of libblas. This is the "stick head in sand" approach since whether we like it or not, fortran is *still* something we must support properly.
I'm closing this as obsolete please see https://wiki.freebsd.org/libgcc%20problem
A commit references this bug: Author: gerald Date: Mon Apr 15 23:08:04 UTC 2019 New revision: 499061 URL: https://svnweb.freebsd.org/changeset/ports/499061 Log: 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 MFH: 2019Q2 (important user visible improvement) Changes: head/lang/gcc8/Makefile head/lang/gcc8/files/patch-gfortran-libgcc
A commit references this bug: Author: gerald Date: Sat Apr 27 14:47:53 UTC 2019 New revision: 500211 URL: https://svnweb.freebsd.org/changeset/ports/500211 Log: 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 Changes: _U branches/2019Q2/ branches/2019Q2/lang/gcc8/Makefile branches/2019Q2/lang/gcc8/files/patch-gfortran-libgcc
A commit references this bug: Author: gerald Date: Wed May 8 07:13:49 UTC 2019 New revision: 501002 URL: https://svnweb.freebsd.org/changeset/ports/501002 Log: Update to the 20180503 snapshot of GCC 8.3.1. On the way forward port r499061 | gerald | 2019-04-15 from lang/gcc8 [1]: 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 [1] Submitted by: tijl [1] Changes: head/lang/gcc8-devel/Makefile head/lang/gcc8-devel/distinfo head/lang/gcc8-devel/files/patch-gfortran-libgcc
A commit references this bug: Author: gerald Date: Sun May 12 19:17:10 UTC 2019 New revision: 501438 URL: https://svnweb.freebsd.org/changeset/ports/501438 Log: Forward port r499061 | gerald | 2019-04-15 from lang/gcc8 and gcc8-devel: 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. Do not bump PORTREVISION, since we'll shortly update to a newer snapshot, just need a consistent baseline when branching the new lang/gcc9 now that GCC 9.1 has been released. PR: 208120 Submitted by: tijl Changes: head/lang/gcc9-devel/files/patch-gfortran-libgcc
A commit references this bug: Author: gerald Date: Wed May 15 10:02:38 UTC 2019 New revision: 501705 URL: https://svnweb.freebsd.org/changeset/ports/501705 Log: Update to the 20190512 snapshot of GCC 10.0.0. This brings a new binary bin/lto-dump which may be helpful if you employ link-time optimization (LTO). Forward port r499061 | gerald | 2019-04-15 from lang/gcc8 and gcc8-devel [1]: 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 [1] Submitted by: tijl [1] Changes: head/lang/gcc10-devel/Makefile head/lang/gcc10-devel/distinfo head/lang/gcc10-devel/files/patch-gfortran-libgcc head/lang/gcc10-devel/pkg-plist