I'm trying to install GHC with -fPIC support in Fedora.
I've grabbed a source tarball since it seems no binary one has this.
In Build.mk i've changed the quick build type to
ifeq "$(BuildFlavour)" "quick"
SRC_HC_OPTS = -H64m -O0 -fasm -fPIC
GhcStage1HcOpts = -O -fasm -fPIC
GhcStage2HcOpts = -O0 -fasm -fPIC
GhcLibHcOpts = -O -fasm -fPIC
SplitObjs = NO
HADDOCK_DOCS = NO
BUILD_DOCBOOK_HTML = NO
BUILD_DOCBOOK_PS = NO
BUILD_DOCBOOK_PDF = NO
endif
unfortunately, when compiling i still get the ld error
ghc -fglasgow-exts --make -shared -oHs2lib.a /tmp/Hs2lib924498/Hs2lib.hs dllmain.o -static -fno-warn-deprecated-flags -O2 -package ghc -package Hs2lib -i/home/phyx/Documents/Haskell/Hs2lib -optl-Wl,-s -funfolding-use-threshold=16 -optc-O3 -optc-ffast-math
Linking a.out ...
/usr/bin/ld: /tmp/Hs2lib924498/Hs2lib.o: relocation R_X86_64_32 against `ghczmprim_GHCziUnit_Z0T_closure' can not be used when making a shared object; recompile with -fPIC
/tmp/Hs2lib924498/Hs2lib.o: could not read symbols: Bad value
So it seems that GHC-prim still isn't compiled with -FPIC
I've also told cabal to build any packages with -fPIC and shared.
Anyone have any ideas?
EDIT:
Thanks to dcouts I've been able to make some progress. But now i'm at the point where I thnk libffi isn't compiled with -fPIC. I've edited the makefile(.in) for it but so far, no luck.
The new command is:
ghc -fPIC -shared dllmain.o Hs2lib.o /usr/local/lib/ghc-7.0.3/libHSrts.a -o Hs2lib.so
where dllmain.c and Hs2lib.hs have both been compiled using -fPIC.
The error I get is:
/usr/bin/ld: /usr/local/lib/ghc-7.0.3/libHSffi.a(closures.o): relocation R_X86_64_32
against `.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/ghc-7.0.3/libHSffi.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
After you see this error, do the following:
cd /tmp/Hs2lib924498/
ghc -fglasgow-exts --make -shared -oHs2lib.a /tmp/Hs2lib924498/Hs2lib.hs dllmain.o -static -fno-warn-deprecated-flags -fPIC -O2 -package ghc -package Hs2lib -i/home/phyx/Documents/Haskell/Hs2lib -optl-Wl,-s -funfolding-use-threshold=16 -optc-O3 -optc-ffast-math
Note I added -fPIC to the failed ghc command.
Once the command succeeds, continue the compilation from within the tmp directory without cleaning already compiled files. It should skip them and continue where it ended.
There's an FAQ entry on this topic on the Haskell Stack page.
It basically says the problem is environment related and sometimes non-deterministic.
The issue may be related to the use of hardening flags in some cases, specifically those related to producing position independent executables (PIE).
There's also a work around suggestion for Arch Linux:
On Arch Linux, installing the ncurses5-compat-libs package from AUR resolves this issue.
Related
I'm writing a dynamic library that's loaded at runtime as a plugin. At runtime, the library fails to load with the following message:
dlerror:/path/to/so: undefined symbol: fstat
The dynamic library consists of a bunch of static libraries linked together, including libsodium. I've tracked down libsodium as the only place that fstat() is used in the library.
As I understand it, fstat() should be part of libc, and should not require additional libraries to be installed. What am I missing?
EDIT1:
I've found some additional information about how linking to fstat() is different than most functions, but I'm not sure exactly how it applies to my situation. I am compiling/linking libsodium with the provided makefiles for their distribution, and the dynamic library is being compiled with the compiler driver as recommended in that answer.
EDIT2: here's the linker command, generated by CMake:
/usr/bin/c++ -fPIC -O3 -DNDEBUG -rdynamic -nodefaultlibs -undefined_warning -fPIC -fvisibility=hidden -shared -Wl,-soname,lin.xpl -o src/xplane_plugin/lin.xpl src/path/to/object/file1.cpp.o src/path/to/object/file2.cpp.o src/plugin/libplugin.a /usr/local/lib/libpng16.a -lz src/plenty/of/dependencies.a lib/glew/libglew.a src/another/library.a /usr/local/lib/libsodium.a /usr/lib/x86_64-linux-gnu/libcurl.so lib/json11/libjson11.a -lpthread deps/some/library.a /usr/local/lib/libzip.a -lbz2 -llzma -lssl -lcrypto -lstdc++fs -lz
The project I am attempting compile is not in any way complex, and references nothing but the standard library and one self-contained library (everything compiles fine on another system). As indicated by the title, it can't even link against something in the standard library, due to things in there not having been compiled with -fPIC, supposedly. I didn't build it myself, nor do I want to, and reinstalling things with apt didn't seem to resolve the "recompile with -fPIC" issue.
I will say that I think one possible source of the issue is due to gcc-multilib or something being installed earlier, but I think that was purged. I don't know, maybe something was overwritten or a conflict arose. Might not even be related. Any ideas?
Running Ubuntu 18.04
g++ -I inc -I /usr/include/mono-2.0 -MMD -MF dep/Nonsense.d -std=c++17 -O3 -fno-stack-protector -fno-unroll-loops -fomit-frame-pointer -Wno-ignored-optimization-argument -c -o obj/Nonsense.o src/Nonsense.cpp
g++ -I inc -I /usr/include/mono-2.0 -MMD -MF dep/Socket.d -std=c++17 -O3 -fno-stack-protector -fno-unroll-loops -fomit-frame-pointer -Wno-ignored-optimization-argument -c -o obj/Socket.o src/Socket.cpp
g++ -shared -flto -o libNonsense.so obj/Nonsense.o obj/Socket.o -Llib -lenet
/usr/bin/x86_64-linux-gnu-ld: obj/Socket.o: relocation R_X86_64_PC32 against symbol `_ZTISt13runtime_error##GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/bin/x86_64-linux-gnu-ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
makefile:22: recipe for target 'libNonsense.so' failed
make: *** [libNonsense.so] Error 1
Apparently, it is compulsory to compile with the -fPIC flag in 64bits platform. If you are making a 32-bits project with linkink with 32-bits library; you don't need -fPIC.
Indeed, without -fPIC, the dynamic linker recalculates adresses for global variables and functions (which are not known in advance in the step of compilation). However, in a 64-bits system, it is not possible to use this technique as it is required to guess in advance the size of adress.
PIC (Position Independent Code), a more sophisticated and complicated process is used. https://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64 for explanations.
As the error message says, you need to recompile with -fPIC. Your current compiler command does not show the -fPIC option:
g++ -I inc -I /usr/include/mono-2.0 -MMD -MF dep/Socket.d -std=c++17 -O3 -fno-stack-protector -fno-unroll-loops -fomit-frame-pointer -Wno-ignored-optimization-argument -c -o obj/Socket.o src/Socket.cpp
Same for -flto by the way—this flag also has to be specified when compiling in order to be effective.
I want to check whether a shared library was compiled with the -fPIC flag. What are the possible ways (on Linux, x86_64) to check this?
Is -fPIC implied (thus making the check redundant?)
Yes, GCC wouldn't allow you to link shared library without -fPIC so you don't need to check anything:
$ gcc tmp.c -shared
/usr/bin/ld: /tmp/ccqQVR9Y.o: relocation R_X86_64_32 against `compare' can not be used when making a shared object; recompile with -fPIC
/tmp/ccqQVR9Y.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
$ gcc tmp.c -shared -fPIC
EDIT
Technically speaking you can compile shared library without -fPIC if none of it's functions calls other functions or accesses global variables. But in that case generated code would be the same as with -fPIC.
Some architectures (not necessarily "modern" ones) just don't have absolute addressing modes, all code is position independent there.
I am trying to compile libedit on linux using GCC 5.3 and am getting a cryptic error message.
/home/mybin/libgcc/x86_64-unknown-linux-gnu/5.3.0/../../../libcurses.a(lib_termcap.o): relocation R_X86_64_32 against `_nc_globals' can not be used when making a shared object; recompile with -fPIC
/home/mybin/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../libcurses.a: could not read symbols: Bad value
To what does the recompile with -fPIC refer, ncurses or libedit? and then how do I pass the -fPIC flag. I have tried adding CFLAGS=-fPIC to the configure of ncurses & libedit but still did not work.
I have found may posts on SO about what -fPIC is, but none on how to set the flag.
thanks Art
Perhaps you ran afoul of the changes outlined in Fedora's Changes/Harden All Packages which use a linker spec that only works if you have compiled using either -fPIC or -fPIE. The linker message is almost useless; only the part about -fPIC has any usefulness.
To address this problem, you can add/modify the compiler flags in several ways. One of the simplest is to set it in the CFLAGS environment variable, e.g.,
export CFLAGS='-O -fPIC'
If you happen to be building ncurses, this means that you would have to also be configuring to build only shared libraries, e.g.,
configure --with-shared --without-normal --without-debug
Of course that all works best if you do not have a previous set of makefiles, etc.
You're looking at the wrong part of the error message. The "relocation R_X86_64_32" means that you're trying to build 32-bit code against a 64-bit library or vice versa. Make sure you have selected the same architecture for both.
-fPIC is used to generate position independent code, it is used to create shared libraries. the make file has a problem, to fix it:
edit the Makefile, line 98 :
.c.o:
${CC} ${CFLAGS} -c $<
after CC add -fpic after CC like this :
.c.o:
${CC} -fpic ${CFLAGS} -c $<
also in line 103:
libedit.so: ${OOBJS}
${CC} --shared -o $# ${OOBJS}
add -fpic after --shared:
libedit.so: ${OOBJS}
${CC} --shared -fpic -o $# ${OOBJS}
if you are wondering what is the difference between -fPIC and -fpic note that they both do the same thing but -fpic is more efficient, check this for more informations What is the difference between `-fpic` and `-fPIC` gcc parameters?.
I need some help with a linker error I get during installation of an Rcpp package on a linux system where I don't have admin rights. In a nutshell, I get this error:
relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
I have a file solve.cpp that uses external library interp2d, which in turn has a GSL dependency. I specify my dependencies via [[Rcpp::depends(RcppArmadillo,RcppGSL)]] and in the DESCRIPTION. My Makevars is like the one from the RcppGSL package, with the addition of the linterp2d flag:
PKG_CPPFLAGS = -W $(GSL_CFLAGS) $(LOCAL_INCLUDE)
PKG_LIBS += $(GSL_LIBS) $(LOCAL_LIBS) -linterp2d $(RCPP_LDFLAGS)
where I define the environement variables
export LOCAL_INCLUDE="-I/data/uctpfos/local/include/"
export LOCAL_LIBS="-L/data/uctpfos/local/lib/"
on the system.
I do R CMD INSTALL bkPackage and see:
g++ -I/cm/shared/apps/R/3.0.1/lib64/R/include -DNDEBUG -W -I/cm/shared/apps/gsl/1.15/include -I/data/uctpfos/local/include -fPIC -I/usr/local/include -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppGSL/include" -fpic -O3 -fPIC -c RcppExports.cpp -o RcppExports.o
g++ -I/cm/shared/apps/R/3.0.1/lib64/R/include -DNDEBUG -W -I/cm/shared/apps/gsl/1.15/include -I/data/uctpfos/local/include -fPIC -I/usr/local/include -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppGSL/include" -fpic -O3 -fPIC -c solve.cpp -o solve.o
The problems appears after that in the linking step:
g++ -shared -L/usr/local/lib64 -o bkPackage.so RcppExports.o solve.o -L/cm/shared/apps/gsl/1.15/lib -lgsl -lgslcblas -lm -L/data/uctpfos/local/lib -linterp2d -L/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/lib -lRcpp -Wl,-rpath,/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/lib
The error follows as:
/usr/bin/ld: /data/uctpfos/local/lib/libinterp2d.a(interp2d_spline.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/data/uctpfos/local/lib/libinterp2d.a: could not read symbols: Bad value
As you can see I compiled this with -fPIC, so that can't be it.
It's complaining that libinterp2d.a was not compiled with -fPIC; are you sure that was also compiled with -fPIC on?
Also, it seems you both have -fpic and -fPIC in your flags; you probably just want -fPIC. I think R actually ensures that's on by default.