Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
ports:libgcc_linking_problem [2017/10/24 16:31] – Initial summary of libgcc_s problems DianeBruceports:libgcc_linking_problem [2021/04/25 02:56] (current) – Add CategoryPorts KubilayKocak
Line 1: Line 1:
-If you compile with gcc and use our base libgcc it should DTRT +===== See Related PR's all the same problem =====
-*provided* our libgcc has defined functions that are up to date +
-with current libgcc +
-We compile with gcc, it needs foo() from libgcc to run +
-doesn't matter what foo() is (A typical function would be T __multi3)__+
  
-So our libgcc provides a foo() and gcc is happy+An early PR filed that erroneously pointed at CMake as the cause. N.B. Comment 24
  
-This means in theory, we can interchangeably use gcc and clang in ports. +https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=208120#c24
-This also means it made the initial port work from from gcc in base +
-to clang in base a lot easier.+
  
-The problems come when we try to use architectures not fully +  * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=217459 
-supported by our libgcc_s.so or when we use fortran.+  * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=210199 
 +  * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=229489
  
-However, our libgcc lies in two ways +===== Also See =====
-1) our libgcc is mostly not GPL code anymore, though there are +
-bits and pieces of GPL depending on what we don't have.+
  
-This includes (or did) some of the work ian@ was trying to do with arm, +  * https://reviews.freebsd.org/D11482
-various bits that arm libgcc provides from gcc were missing.+
  
-2) It claims to be only up to date with GCC 4.2.4+===== The TLDR; Interim Workaround =====
  
-Everything is peachy keen until someone references a symbol which is in +export LD_PRELOAD=/usr/local/lib/gcc8/libgcc_s.so
-anything gcc compiled using a newer > GCC 4.2.4 compiler.+
  
-The moment you load libgfortran, it has a requirement for GCC_4.6 or better, +====== The Why ======
-and if our libgcc is already loaded things fail.+
  
-The reason ports gcc now has this requirment on 4.6 or better is +If you compile with g++ and use our base libgcc it should DTRT //provided// our libgcc has defined functions that are up to date 
-GNU changed gfortran to always support quad math (*8) and hence needs +with current libgcc. We compile with g++, it needs foo() from libgcc to run (A typical function would be __multi3) and__ 
-/usr/local/lib/gccXX/libquadmath.so They then changed the dependancy stated in libgfortran to always require a later libgcc.+__so our **libgcc** provides a foo() and g++ is happy.__
  
-We *could* lie in our libgcc_s and claim to be 4.6 which would simply +This means in theory, we can interchangeably use g++ and clang++ in ports. This also means it made the initial port work from from gcc in base to clang in base a lot easier.
-mean libgfortran would not complain and simply load the missing libquadmath.+
  
-If we updated the claimed GCC version in our libgcc_s.so to claim +The problems come when we try to use architectures not fully supported by our libgcc_s.so or when we use Fortran. 
-GCC_4.6, we really also should provide a libquadmath subsitute.+Fortran (gnu fortran) like g++ also uses libgcc.
  
-The other approach is to rename our libgcc_s.so to libclang_s.so or +Our libgcc lies in two ways:
-some such and link base with it instead of libgcc_s.so+
  
-I frankly think this in the long term is the cleaner solution.+1) our libgcc is mostly not GPL code anymore, though there are bits and pieces of GPL depending on what we don't have.
  
-In the ports world, we have papered over this problem by adding +This includes (or did) some of the work ian@ was trying to do with arm, various bits that arm libgcc provides from gcc were missing.
--Wl,-rpath=${_GCC_RUNTIME} or similar to force programs to link +
-against /usr/local/lib/gcc${GCCVERSION}/libgcc_s.so +
-cmake does DTRT but programs that run python will not have +
-prior knowledge that a binary module they are going to load during +
-execution will be gfortran built and need libquadmath therefore asking for a later libgcc than in base. +
-Hence if one forces the pre load of gfortran libgcc or LD_PATH +
-it so it comes first, everything works just peachy. I'm guessing python +
-is the biggest user of loaded gfortran binary modules but the problem +
-could come up in other interpreters.+
  
-N.B. at this time clang does not realise flang is a valid fortran compiler.+2) It claims to be only up to date with GCC 4.2.4
  
-Mixing gfortran and flang .obj's seem to work until I/O is involved.+Everything is peachy keen until someone references a symbol which is in anything g++ compiled using a newer > GCC 4.2.4 compiler.
  
-$ more m.f +The moment you load libgfortran, it has a requirement for GCC_4.6 or better, and if our libgcc is already loaded things fail.
-print*,'a= ',a() +
-print*,'b= ',b() +
-end+
  
-$ more a.f +The reason ports g++ now has this requirement on 4.6 or better is GNU changed gfortran to always support quad math (REAL(16%%))%% and hence needs 
-function a()+/usr/local/lib/gccXX/libquadmath.so They then changed the dependancy stated in libgfortran to always require a later libgcc.
  
-print*,'hello from a' +We *could* lie in our libgcc_s and claim to be 4.6 which would simply mean libgfortran would not complain and simply load the missing libquadmath.
-a=5.0 +
-return +
-end+
  
-$ more b.f +If we updated the claimed GCC version in our libgcc_s.so to claim GCC_4.6, we really also should provide a libquadmath substitute.
-function b()+
  
-print*,'hello from b' +The other approach is to rename our libgcc_s.so to libclang_s.so or some such and link base with it instead of libgcc_s.so 
-b=15.0 +I frankly think this in the long term is the cleaner solution.
-return +
-end+
  
-$ flang -o m m.f a.f b.f +====== Workaround we do ======
-$ ./m +
-a= hello from a    5.000000 +
-b= hello from b    15.00000+
  
-$ gfortran5 -o m m.f a.f b.f +In the ports world, we have papered over this problem by adding -Wl,-rpath=${_GCC_RUNTIME} or similar to force programs to link 
-$ ./m +against /usr/local/lib/gcc${GCCVERSION}/libgcc_s.so 
-/lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc5/libgfortran.so.3 not found+Cmake does DTRT.
  
-# compile with flang only a.f+====== Why our workaround fails ======
  
-$ flang -c a.f -o a.o +The real problem comes when interpreters compiled with clang or gcc that do not use libgcc are run. The late binding that happens 
-clang-3.9: <sup>%%[[%%0;1;35mwarning: </sup>%%[[%%0m-lflang: 'linker' input unused^%%[[%%0m +when a binary module is loaded that //does// reference a //libgcc// is what can trigger this bug //at run time// and this is independent 
-clang-3.9: <sup>%%[[%%0;1;35mwarning: </sup>%%[[%%0m-lflangmain: 'linker' input unused^%%[[%%0m +of what our linker (not the run time linker rtld but ld/lld) 
-clang-3.9: <sup>%%[[%%0;1;35mwarning: </sup>%%[[%%0m-lflangrti: 'linker' input unused^%%[[%%0m +IFF a binary module is loaded with a libgcc reference it can pull in the //wrong// libgcc e.g. the base **/usr/lib/libgcc_.so**
-clang-3.9: <sup>%%[[%%0;1;35mwarning: </sup>%%[[%%0m-lompstub: 'linker' input unused^%%[[%%0m +
-clang-3.9: <sup>%%[[%%0;1;35mwarning: </sup>%%[[%%0m-lexecinfo: 'linker' input unused^%%[[%%0m +
-clang-3.9: <sup>%%[[%%0;1;35mwarning: </sup>%%[[%%0margument unused during compilation: '-L/usr/l +
-ocal/flang/lib'+
  
-# compile with gfortran only b.f +Usually it's a graphics package binary that is brought which are typically compiled with g++ or clang c++. Provided nothing 
-$ gfortran5 -c b.f -o b.o+needs libquadmath the two libraries are compatible enough.
  
-$ flang -o m m.f a.o b.o +====== Work around for this problem ======
-/usr/bin/ld: ESC[0;1;31merror: ESC[0mundefined symbol: _gfortran_st_write +
-%%>%%>> referenced by b.f +
-%%>%%>>               b.o:(b_)+
  
-/usr/bin/ld: ESC[0;1;31merror: ESC[0mundefined symbol: _gfortran_transfer_character_write +If one forces the pre load of the gfortran libgcc or LD_PATH it so it comes first, everything works just peachy. 
-%%>%%>> referenced by b.f +I'm guessing python is the most likely to fail in this way. Another work around (tried by me personally) is loading the modules 
-%%>%%>>               b.o:(b_)+requiring gfortran first which binds the "right" **libgcc_s** functions and symbols. 
 +This still has a problem which is easily worked around. IFF the package used provides separate libraries which can be used 
 +independently of the interpreter in question (e.g. python), then the programs compiled against these libraries //must// use USES+= fortran 
 +to preload the //right// libgcc
  
-/usr/bin/ld: ESC[0;1;31merror: ESC[0mundefined symbol: _gfortran_st_write_done +===== Final thoughts and future work =====
-%%>%%>> referenced by b.f +
-%%>%%>>               b.o:(b_) +
-clang-3.9: ESC[0;1;31merror: ESC[0mlinker command failed with exit code 1 (use -v to see invocation)ESC[0m +
-$ flang -o m m.f a.o b.o /usr/local/lib/gcc5/libgfortran.so +
-$ ./m +
-/lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc5/libgfortran.so.3 not found+
  
-$ gfortran -o m m.f a.o b.o /usr/local/lib/gcc5/libgfortran.soESC[60DgfortranESC[1@5 +N.B. at this time cmake does not realise flang is a valid fortran compiler.
-a.o: In function `a_': +
-/home/db/a.f:3: undefined reference to `f90io_src_info03' +
-/home/db/a.f:3: undefined reference to `f90io_print_init' +
-/home/db/a.f:3: undefined reference to `f90io_sc_ch_ldw' +
-/home/db/a.f:3: undefined reference to `f90io_ldw_end' +
-collect2: error: ld returned 1 exit status+
  
-$ gfortran5 -o m m.f a.o b.o /usr/local/lib/gcc5/libgfortran.so /usr/local/flang /lib/libflang.so +Mixing gfortran and flang .obj's seem to work until I/O is involved. 
-%%//%%usr/local/flang/lib/libflangrti.so: undefined reference to `backtrace_symbols' +I'll be investigating this further as time permits.
-%%//%%usr/local/flang/lib/libflangrti.so: undefined reference to `backtrace' +
-collect2: error: ld returned 1 exit status +
- +
-# Removing I/O from a.f and b.f +
- +
-$ cat a.b +
-cat: a.b: No such file or directory +
-$ cat a.f +
-function a() +
- +
-C      print*,'hello from a' +
-a=5.0 +
-return +
-end +
-$ cat b.f +
-function b() +
- +
-C     print*,'hello from b' +
-b=15.0 +
-return +
-end +
- +
-$ flang -c -o a.o a. +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lflang: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lflangmain: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lflangrti: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lompstub: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lexecinfo: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0margument unused during compilation: '-L/usr/local/flang/lib' +
-$ gfortran5 -c -o b.o b.f+
  
-C     print*,'hello from b' +----
-b=15.0 +
-return +
-end+
  
-$ flang -c -o a.o a. +{{tag>Ports}}
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lflang: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lflangmain: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lflangrti: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lompstub: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0m-lexecinfo: 'linker' input unused +
-clang-3.9: ESC[0;1;35mwarning: ESC[0margument unused during compilation: '-L/usr/local/flang/lib' +
-$ gfortran5 -c -o b.o b.f +
-$ flang -o m m.f a.o b.o +
-$ ./m +
-a=     5.000000 +
-b=     15.00000 +
-$ gfortran5 -o m m.f a.o b.o +
-$ ./m +
-/lib/libgcc_s.so.1: version GCC_4.6.0 required by /usr/local/lib/gcc5/libgfortran.so.3 not found+
  
  • ports/libgcc_linking_problem.1508862663.txt.gz
  • Last modified: 2017/10/24 16:31
  • by DianeBruce