Bug 208120

Summary: devel/cmake: Strips necessary rpath when installing any GNU compiler from ports
Product: Ports & Packages Reporter: Diane Bruce <db>
Component: Individual Port(s)Assignee: freebsd-kde (group) <kde>
Status: Closed FIXED    
Severity: Affects Many People CC: ardovm, emaste, feld, gerald, groot, hamradio, ian, jcfyecrayz, jeff, koobs, mmel, pi, rhurlin, thierry, tijl, vladimir.chukharev, yuri, zakharov.vv
Priority: Normal Keywords: needs-qa, patch
Version: LatestFlags: koobs: merge-quarterly?
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=210199
Bug Depends on:    
Bug Blocks: 196862, 204598, 205294, 207750, 211641    
Attachments:
Description Flags
Fix for RPATH bug with gfortran
none
Simple GNU Radio test network failure case
none
Self-contained fortran+CMake example
none
remove -shared-libgcc from gfortran none

Description Diane Bruce freebsd_committer freebsd_triage 2016-03-18 13:09:47 UTC
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.
Comment 1 Koop Mast freebsd_committer freebsd_triage 2016-03-18 13:25:15 UTC
tweak subject, and assign to cmake maintainers.
Comment 2 Diane Bruce freebsd_committer freebsd_triage 2016-03-18 15:57:35 UTC
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
Comment 3 Ian Lepore freebsd_committer freebsd_triage 2016-03-19 02:07:21 UTC
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.
Comment 4 Jeffrey Baitis 2016-03-30 19:11:32 UTC
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
Comment 5 groot 2016-03-30 21:40:51 UTC
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.
Comment 6 Diane Bruce freebsd_committer freebsd_triage 2016-03-30 22:08:23 UTC
It also affects gcc from ports as well and not just gfortran, though the bug is not as evident.
Comment 7 Raphael Kubo da Costa freebsd_committer freebsd_triage 2016-04-03 11:56:42 UTC
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?
Comment 8 groot 2016-04-06 09:07:54 UTC
(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.
Comment 9 groot 2016-04-06 11:26:39 UTC
.. 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.
Comment 10 Diane Bruce freebsd_committer freebsd_triage 2016-04-10 13:27:43 UTC
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?
Comment 11 Diane Bruce freebsd_committer freebsd_triage 2016-06-09 18:27:53 UTC
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
Comment 12 Diane Bruce freebsd_committer freebsd_triage 2016-06-12 11:30:42 UTC
See https://people.freebsd.org/~db/libgcc_summary.txt
Comment 13 Kubilay Kocak freebsd_committer freebsd_triage 2016-06-19 10:18:44 UTC
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
Comment 14 groot 2016-12-10 20:03:24 UTC
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.
Comment 15 groot 2016-12-10 20:27:23 UTC
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.
Comment 16 Diane Bruce freebsd_committer freebsd_triage 2016-12-10 23:32:19 UTC
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 ;)
Comment 17 Antoine Brodin freebsd_committer freebsd_triage 2016-12-11 15:02:05 UTC
(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 18 Diane Bruce freebsd_committer freebsd_triage 2016-12-11 15:46:44 UTC
comment #17 good point.
Comment 19 Tijl Coosemans freebsd_committer freebsd_triage 2016-12-11 17:02:07 UTC
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.
Comment 20 Diane Bruce freebsd_committer freebsd_triage 2016-12-12 15:04:44 UTC
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. ;)
Comment 21 Tijl Coosemans freebsd_committer freebsd_triage 2016-12-12 16:38:27 UTC
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.
Comment 22 Ian Lepore freebsd_committer freebsd_triage 2016-12-28 01:01:41 UTC
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.
Comment 23 Mark Felder freebsd_committer freebsd_triage 2017-02-09 19:49:40 UTC
(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.
Comment 24 Tijl Coosemans freebsd_committer freebsd_triage 2017-02-09 22:04:50 UTC
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.
Comment 25 Diane Bruce freebsd_committer freebsd_triage 2017-02-20 22:59:54 UTC
(In reply to Tijl Coosemans from comment #24)

I like this idea the best. It solves our current problem in all cases.
Comment 26 Michal Meloun freebsd_committer freebsd_triage 2017-03-01 08:51:30 UTC
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.
Comment 27 Michal Meloun freebsd_committer freebsd_triage 2017-03-01 09:38:04 UTC
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.
Comment 28 Yuri Victorovich freebsd_committer freebsd_triage 2017-04-22 01:32:53 UTC
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.
Comment 29 Diane Bruce freebsd_committer freebsd_triage 2017-04-22 19:49:06 UTC
(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.
Comment 30 Diane Bruce freebsd_committer freebsd_triage 2017-12-31 21:20:28 UTC
I'm closing this as obsolete please see https://wiki.freebsd.org/libgcc%20problem
Comment 31 commit-hook freebsd_committer freebsd_triage 2019-04-15 23:08:52 UTC
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
Comment 32 commit-hook freebsd_committer freebsd_triage 2019-04-27 14:48:12 UTC
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
Comment 33 commit-hook freebsd_committer freebsd_triage 2019-05-08 07:14:03 UTC
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
Comment 34 commit-hook freebsd_committer freebsd_triage 2019-05-12 19:17:24 UTC
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
Comment 35 commit-hook freebsd_committer freebsd_triage 2019-05-15 10:03:15 UTC
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