Link static libs to dynamic libs: -mimpure-text in G++ / Ubuntu - linker

I'm trying to link some 3rd party static libraries into a dynamic library. However I get the error -
relocation R_X86_64_32 against `TMC_END' can not be used when
making a shared object; recompile with -fPIC
On Solaris, you can tell GCC/ G++ to allow linking with code that wasn't compiled with -fPIC, through the option -mimpure-text. (Found via great answer here) However this option isn't recognized on Ubuntu (16.04, g++ version 5.4.0):
g++: error: unrecognized command line option ‘-mimpure-text’
Is there any equivalent option, or any other solution except for compiling the 3rd parties static libraries with -fPIC enabled?
Thanks!
P.S Excellent explanation on relocations here

Related

Linkage error when using static library in executable

I am trying to build an executable which should be linked with the
mosquitto (libmosquitto.a)
json-c (libjson-c.a)
Also, there is a custom C API built as a static library as well: myCAPI.a
My linux is Ubuntu 18.04 running under virtual machine. Also, I am using cmake tool.
So, when I'm trying to build an executable I am getting the following linking errors:
myCAPI.a(some_client.c.o): relocation R_X86_64_32S against symbol 'valueTypes' can not be used when making a PIE object; recompile with -fPIC
libmosquitto.a(connect.c.o): relocation R_X86_64_32 against '.rodata' can not be used when making a PIE object; recompile with -fPIC
// etc.
libjson-c.a(strerror_override.c.o): relocation R_X86_64_32S against '.data' can not be used when making a PIE object; recompile with -fPIC
// etc.
I have a googled a lot and find some articles where it is said that the issue is connected to gcc's version (either PIE or PIC is selected as an option). So, I tried to build my environment as follows:
cmake -no-pie ../
Also in this way as well:
cmake -fPIC ../
Here is my CMakelists.txt
cmake_minimum_required(VERSION 3.10)
set(EXAMPLE_NAME "PublishValues")
project(${EXAMPLE_NAME})
file(GLOB SOURCES "src/*.c")
include_directories(include ../../include )
set(PROJECT_LINK_LIBS libtvcmiclient.a libmosquitto.a libcares.a libjson-c.a libssl.a libcrypto.a libpthread.so libdl.so)
link_directories(../../3rdparties ../../libs)
add_executable(${EXAMPLE_NAME} ${SOURCES})
target_link_libraries(${EXAMPLE_NAME} ${PROJECT_LINK_LIBS})
Unfortunately, the linking errors still there.

undefined reference to symbol 'CERT_GetDefaultCertDB##NSS_3.2'

I recently added libcurl dependency to my c++ library. I statically compiled libcurl with-nss for https support. I use Debian 7 for compilation.
I create two builds for my library - static and shared
Shared version is linking fine with binaries built on any Linux distro, but the static build only links with binaries when compiled on Debian 7.
I tried static linking on Ubuntu 16.04, Debian Stretch but all are reporting following error during compilation:
g++ -Wall -o Sample Sample.cpp -Wl,-Bstatic -L. -lMyLibrary -Wl,-Bdynamic -lssl3
/usr/bin/ld: ./libMyLibrary.a(libcurl_la-nss.o): undefined reference to symbol 'CERT_GetDefaultCertDB##NSS_3.2'
//usr/lib/x86_64-linux-gnu/libnss3.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Makefile:22: recipe for target 'Sample' failed
make: *** [Sample] Error 1
Static compilation now only works on Debian 7 which is a big problem.
Static libraries are just archives of object files. As one consequences, they don't carry any dependency information. So, if you link a static library which depends on some other libraries, you have to add these explicitly in your linking command.
In your case, this means:
find whoever defines CERT_GetDefaultCertDB##NSS_3.2 -- some answers to this FAQ could help here
add this library to your linker command (with -l, after your static library)

gcc: Not able to create .so from object files

I am trying to create .so dynamic library from *.o files and facing below issue.
LOG:
[nptemp-static]$ gcc -shared *.o -o libexample.so
/usr/bin/ld: bindings_hubbub_parser.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
bindings_hubbub_parser.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
Any idea? Do I need to recompile my whole source code with the option specified?
Actually, I am not aware of the source code which I compiled because all the source code is open source which I downloaded and compiled by following instructions in README.
I am trying to create .so dynamic library from *.o files and facing below issue.
This is not that simple. In practice, you should compile specifically when making a shared library, at least on Linux.
(Perhaps you might need to edit your Makefile or configure somehow your build automation if it was not designed for building a shared library; if building some free software library, you might ask help from its authors or community)
Shared libraries want to have position independent code. So you need to compile their source code with the -fPIC flag passed to g++ or gcc (see this). You could also want to explicit the rpath.
Read Drepper's paper: How To Write Shared Libraries.

undefined reference to gzdopen, gzclose, gzread

I have compiled and installed the 2.2.7.2 version of libxml. While compiling, I have this error: Makefile:755: recipe for target 'install-data-local' failed. But the lib files are correctly generated (libxml2.a and libxml2.so).
I'd like to use libxml2 in a C project so I edited my makefiles in order to integrate lib files (libxml2.a and libxml2.so).
The problem is that when I compile my project I get the followings errors:
/libxml2.a(xmlIO.o): In function xmlGzfileRead': undefined reference togzdopen'
/libxml2.a(xmlIO.o): In function xmlGzfileRead': undefined reference togzclose'
/libxml2.a(xmlIO.o): In function xmlGzfileRead': undefined reference togzread'
...etc
It seems that I have to install the zlib library in order to resolve this linker errors. I installed the zlib library and edited the LD_LIBRARY_PATH in order to add the path where are the zlib libraries.
I recompiled my project, but I still always having the same linker errors.
Would you please help me to resolve those linker errors.
Regards.
See the libxml2 FAQ:
Troubles compiling or linking programs using libxml2
Usually the problem comes from the fact that the compiler doesn't get the right compilation or linking flags. There is a small shell script xml2-config which is installed as part of libxml2 usual install process which provides those flags. Use
xml2-config --cflags
to get the compilation flags and
xml2-config --libs
to get the linker flags. Usually this is done directly from the Makefile as:
CFLAGS=`xml2-config --cflags`
LIBS=`xml2-config --libs`
On my current system, the output from xml2-config --libs is
-lxml2 -lz -lpthread -licucore -lm

ALSA Library and Cross Compiling for ARM

I'm trying to make an "C" application for my NXP(Freescale) imx6 that Debian OS installed on it. My host machine is Ubuntu 16.04. I'm using eclipse as an IDE and I can manage to cross compile until today. I use arm-linux-gnueabihf-gcc as an compiler and arm-linux-gnueabihf-ld as an linker. I added -lasound option to my linker parameter, but still can not build the application. I get an error
arm-linux-gnueabihf-ld: cannot find -lasound
I think I don't have the libasound.so file on my Ubuntu (Host) machine and my linker couldn't link to library to my application.
I copied the libasound.so file from my ARM machine to my host machine to the /home/user/Downloads folder, but still couldn't compile.
Is there a step to use ALSA library in Cross Compilation project before build?
Here is the output of build operation
Building target: tihc_linux_application
Invoking: GCC C Linker
/usr/bin/arm-linux-gnueabihf-ld -static -L/home/user/Downloads -pthread -lasound -o "main" ./src/main.o
/usr/bin/arm-linux-gnueabihf-ld: mode armelf_linux_eabi
/usr/bin/arm-linux-gnueabihf-ld: cannot find -lasound
You ask for static link (via -static) but provide shared library so ld probably ignores it (to be sure you can run with -Wl,--verbose). One option is to cross-compile libalsa from scratch and then use resulting static lib to link your app. Another option is to search for pre-compiled gnueabihf libalsa somewhere...

Resources