How to modify options being passed to ld , without recompiling gcc - c++

I'm trying to compile shared library on solaris 2.7 using gcc 3.4.6 and
which is linking to a statically linked c .a and .o files.
Please note that it is using Sun ld from path "/usr/ccs/bin/ld"
At linking time i got a long list of symbols and following error
ld: fatal: relocations remain against allocatable but non-writable sections
collect2: ld returned 1 exit status
Then i tried to build it passing -z textoff option to ld. but i'm getting follwing error
ld: fatal: option -ztextoff and -ztext are incompatible
ld: fatal: Flags processing errors
Is there any other way where i don't need to recompile gcc and still modify the options getting passed to ld.

The errors are the result of linking position-dependent code into a shared library. Such code will result in the library not being shareable, and thus wasting RAM.
If you can rebuild all the objects you are trying to link into the shared library, the simplest (and most correct) solution is to rebuild all of them with -fPIC flag.
However, sometimes you really must link non-PIC object code which you can't rebuild into a shared library, and therefore you need to get rid of the -ztext option. To do that, add -mimpure-text option to your link line.

Run the ld executable from the command line (not via gcc) - you can then pass it whatever parameters you want. I don't think that will solve your underlying problems though - you might want to post a question about them.

Are you using make or some other build system to invoke the compiler?
If you change the options in the build system to specifically use the linker during the link phase rather than using the compiler.
Step 1: Find flags passed by gcc
Add the -v flag. It makes gcc verbose.
CXXFLAGS += -v
Step 2: Modify the link stage to explicitly use the tool that gcc was invoking.

Related

Facebook warpdrive build - D Programming language

Of late, facebook opensourced warp, C/C++ preprocessor.
https://github.com/facebook/warp
I'm trying to build it using dmd and stuck with some build errors.
I downloaded dmd.2.065.0.zip for dmd compiler - dmd2/linux/bin64/dmd
I also see a bunch of libraries, for example libphobos2.a
Then when I build warp, I see some errors from ld, that keep complaining that phobos2.a could not be found. I exported LD_LIBRARY_PATH to the dir where this library is stored but no luck.
I compiled in verbose mode, and it doesn't give more info.
Command:
/path/to//building_stuff/dmd2/linux/bin64/dmd -O -inline -release -ofwarp cmdline.d constexpr.d context.d directive.d expanded.d file.d id.d lexer.d loc.d macros.d main.d number.d outdeps.d ranges.d skip.d sources.d stringlit.d textbuf.d -v
Error excerpt:
function textbuf.Textbuf!char.Textbuf.length
function textbuf.Textbuf!char.Textbuf.resize
gcc warp.o -o warp -m64 -L/path/to/building_stuff/dmd2/linux/bin64/../lib64 -Xlinker --export-dynamic -l:libphobos2.a -lpthread -lm -lrt
/usr/bin/ld: cannot find -l:libphobos2.a
collect2: ld returned 1 exit status
--- errorlevel 1
I was hoping the D language experts here, or those who know about warp already could give me some hint.
I was not on CentOS, as warp demands. I wonder if that could anyway be the reason.
I was not using gcc 4.7.x as warp demands, but, to me, the library could just not be located doesn't look like a problem from old gcc I have.
I was on redhat5.5 machine with 4.1 gcc.
CentOS is basically a RedHat, so everything should work OK. As people commented, your real problem is the -l:libphobos2.a in your link line. Remember, GNU/Linux allows colons in file-names, so :libphobos2.a is a perfectly valid file, and GNU ld won't find it in the library search paths.
Note that they've added a make file to easy on your compilation, I managed to compile it using "make -j" and only editing the dmd command line in the make.
just rename "libphobos2.a" to "lib:libphobos2.a.a"
I faced a similar problem with ld version 2.17, but with version 2.20 this 'l:<libfilename>' kinda syntax works fine.

Error when static linking g++

I have a problem, i want to compile my application with static linking of mysql connector.
My command line:
g++ -o newserver stdafx.cpp ... -lboost_system -lboost_thread
-lpthread -lmysqlcppconn -static /usr/lib/libmysqlcppconn-static.a -std=c++0x
But i have error:
/usr/bin/ld: cannot find -lmysqlcppconn
/tmp/ccxpOfdZ.o: In function `IsEqualsDns(unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
Server.cpp:(.text+0x356e): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
collect2: ld returned 1 exit status
How can i fix this?
Thanks!
Where is the library libsqlcppconn.a or libsqucppconn.so
(static or dynamic)? The compiler is looking for it, and
doesn't find it.
Presumably, this is the same library as
/usr/lib/mysqlcppconn-static.a. If so, just drop the
-lmysqlcppconn. Or just use -lmysqlcppconn-static (no
spaces), and forget about the /usr/lib/libmysqlconn-static.a.
With a name like that, there shouldn't be a corresponding .so,
which means that g++ will link it statically, even without the
-static. You only need the -static if there is both
a libmysqlconn-static.so and a libmysqlconn-static.a in the
same directory.
With regards to the second error (which is just a warning, but
will cause problems if you try to run the linked program on
other machines, or even after an upgrade of your machine): if
you use -static anywhere in your command line (as you
currently do), then it applies to all files linked afterwards.
Including the system libraries, which you don't want to link
statically. My guess is that the -static isn't necessary (see
above); if it is, place it immediately before the library you
want to link statically, and place a -dynamic immediately
after (so that any following libraries, including the system
libraries, will be dynamically linked).
You could try g++ -static YOUR ARGUMENTS.
If you are coming from a Windows platform, linking against Boost can give a few surprises. The typicall Boost installation (e.g. after ./b2 install) will make both dynamic and static libraries and put them in the same directory. Typically, the two library forms only differ in their extension (.so or .a).
Windows supports auto-linking, which basically means that library files contain some flags in their first few bytes indicating whether they are for dynamic or for static linking. On Linux platforms, this is not the case and the linker gets confused which file to load (since you don't provide the extension of the library name). Therefore, you need to tell your linker which form of linking you want.

How to recompile with -fPIC

I was trying to reinstall my ffmpeg, following this guide, on my ARM Ubuntu machine. Unfortunately, when I compile a program which uses this lib I get the following failure:
/usr/bin/ld: /usr/local/lib/libavcodec.a(amrnbdec.o): relocation R_ARM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libavcodec.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
Now I would like to recompile it with -fPIC like the compiler is suggesting but I have no idea how. Any help is appreciated.
Briefly, the error means that you can't use a static library to be linked w/ a dynamic one.
The correct way is to have a libavcodec compiled into a .so instead of .a, so the other .so library you are trying to build will link well.
The shortest way to do so is to add --enable-shared at ./configure options. Or even you may try to disable shared (or static) libraries at all... you choose what is suitable for you!
Have a look at this page.
you can try globally adding the flag using: export CXXFLAGS="$CXXFLAGS -fPIC"
I had this problem when building FFMPEG static libraries (e.g. libavcodec.a) for Android x86_64 target platform (using Android NDK clang). When statically linking with my library the problem occured although all FFMPEG C -> object files (*.o) were compiled with -fPIC compile option:
x86_64/libavcodec.a(h264_qpel_10bit.o):
requires dynamic R_X86_64_PC32 reloc against 'ff_pw_1023'
which may overflow at runtime; recompile with -fPIC
The problem occured only for libavcodec.a and libswscale.a.
Source of this problem is that FFMPEG has assembler optimizations for x86* platforms e.g. the reported problem cause is in libavcodec/h264_qpel_10bit.asm -> h264_qpel_10bit.o.
When producing X86-64 bit static library (e.g. libavcodec.a) it looks like assembler files (e.g. libavcodec/h264_qpel_10bit.asm) uses some x86 (32bit) assembler commands which are incompatible when statically linking with x86-64 bit target library since they don't support required relocation type.
Possible solutions:
compile all ffmpeg files with no assembler optimizations (for ffmpeg this is configure option: --disable-asm)
produce dynamic libraries (e.g. libavcodec.so) and link them in your final library dynamically
I chose 1) and it solved the problem.
Reference: https://tecnocode.co.uk/2014/10/01/dynamic-relocs-runtime-overflows-and-fpic/
After the configure step you probably have a makefile. Inside this makefile look for CFLAGS (or similar). puf -fPIC at the end and run make again. In other words -fPIC is a compiler option that has to be passed to the compiler somewhere.
If you're building a shared library but need to link with static libavcodec add linker flags:
-Wl,-Bsymbolic
In case of cmake:
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
I hit this same issue trying to install Dashcast on Centos 7. The fix was adding -fPIC at the end of each of the CFLAGS in the x264 Makefile. Then I had to run make distclean for both x264 and ffmpeg and rebuild.
In addirion to the good answers here, specifically Robert Lujo's.
I want to say in my case I've been deliberately trying to statically compile a version of ffmpeg. All the required dependencies and what else heretofore required, I've done static compilation.
When I ran ./configure for the ffmpeg process I didnt notice --enable-shared was on the commandline. Removing it and running ./configure is only then I was able to compile correctly (All 56 mbs of an ffmpeg binary). Check that out as well if your intention is static compilation
I'm building ffmpeg 5.1.2 on CentOS7 with gcc4.8.5.
As mentioned in ${ffmpegRoot}/doc/platform.texi:
1)configure with option
"--enable-pic"
2)add the following option to your project LDFLAGS
"-Wl,-Bsymbolic"
Before compiling make sure that "rules.mk" file is included properly in Makefile or include it explicitly by:
"source rules.mk"

CodeBlocks cannot find shared libraries even when search paths are setup

I have a very basic C++ project in code blocks that makes use of glfw.so and two other libraries that are compiled to .so files from another project, libHorde3D.so and libHorde3DUtils.so. The latter are placed in the project root folder, while glfw is somewhere in my /usr/lib (I think).
I have added the project folder to the linker and compiler search paths in code blocks. I have added the libHorde3D.so and libHorde3DUtils.so as well as glfw.so to the Link Libraries in the Linker Settings tab. I thought that this would be enough based on the previous similar questions here on stackoverflow.
However when I press build:
ld cannot find -lHorde3D.so
ld cannot find -lHorde3DUtils.so
ld cannot find -lglfw.so
My system is Arch Linux 64 and I am using GCC.
I also tried bopying libHorde3D.so and libHorde3DUtils.so in /usr/lib and /usr/lib64 with no success.
P.S. All search paths are copied across the Debug and Release target.
Say, if the library name is libmylibrary.so, then linker option to link against that library would look like -lmylibrary. Note that lib prefix and .so suffix are not there — they are added automatically by the linker. In your case it seems like you specified the wrong name. Try removing .so from it, that should solve the problem.
Here is a simple demonstration of how to trigger the failure by making a similar mistake:
$ echo 'int main() { return 0; }' > test.c
$ gcc -o test ./test.c -lc
$ gcc -o test ./test.c -lc.so
/usr/bin/ld: cannot find -lc.so
collect2: ld returned 1 exit status
$
The first command succeeds and the second one (with incorrect library name) fails.
You must not pass ".so". The linker options are
-lHorde3D -lHorde3DUtils -lglfw
This way the linker will search for "libHorde3D.so" etc. in the library path(s).

Boost::Thread linking error on OSX?

So I'm going nuts trying to figure this one out. Here's my basic setup:
I'm compiling a shared library with a bunch of core functionality that uses a lot of boost stuff. We'll call this library libpf_core.so. It's linked with the boost static libraries, specifically the python, system, filesystem, thread, and program_options libraries. This all goes swimmingly.
Now, I have a little test program called test_socketio which is compiled into a shared library (it's loaded as a plugin at runtime). It uses some boost stuff like boost::bind and boost::thread, and it's linked again libpf_core.so (which has the boost libraries included remember).
When I go to compile test_socketio though, out of all my plugins it gives me a linking error:
[ Building test_socketio ]
g++ -c -pg -g -O0 -I/usr/local/include -I../include test_socketio.cc -o test_socketio.o
g++ -shared test_socketio.o -lpy_core -o test_socketio.so
Undefined symbols:
"boost::lock_error::lock_error()", referenced from:
boost::unique_lock<boost::mutex>::lock() in test_socketio.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
And I'm going crazy trying to figure out why this is. I've tried explicitly linking boost::thread into the plugin to no avail, tried ensuring that I'm using the boost headers associated with the libraries linked into libpf_core.so in case there was a conflict there.
Is there something OSX specific regarding boost that I'm missing? In my searching on google I've seen a number of other people get this error but no one seems to have come up with a satisfactory solution.
Edit: Figured it out, OSX comes with boost 1.40 in /usr/local/include. Needed to put the headers for my version of boost somewhere and make sure that my plugins sees those first.
You need to link to libboost_thread. Add the -lboost_thread switch.
When you link libpf_core.so against the static boost libraries, it's only going to get copies of the functions it actually uses. The linker doesn't bother to pull in functions that aren't referenced by the code in your library.
You need to link your test program against the boost libraries as well. You can't reliably "chain" the linkages.