Usage of -l for arm-none-eabi-gcc - c++

I am trying to use a arm-none-eabi-gcc to compile some mbed code offline and ran into trouble when I tried to move the mbed folder outside the directory. The command that comes out of the make file is
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -T../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/MKL25Z4.ld -L./mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM -o Example.elf main.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/retarget.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/board.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/cmsis_nvic.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/mbed_overrides.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/system_MKL25Z4.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/startup_MKL25Z4.o -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
The folder named mbed contains all the headers and .o files required for basic mbed programming. However, when I try to move the mbed folder to a different folder and address it relatively, I get an error saying:
cannot find -l../libraries/mbed
Is it wrong to give relative paths to the -l option? If yes, how do I work around this problem?

Use the -L option to gcc to indicate where libraries are to be looked for. See the manual:
The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
The directories searched include several standard system directories plus any that you specify with -L.

I was able to get this working. The problem was that -L was not taking in relative paths. The new command looks something like this:
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -T/<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/MKL25Z4.ld -o Example.elf main.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/retarget.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/board.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/cmsis_nvic.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/mbed_overrides.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/system_MKL25Z4.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/startup_MKL25Z4.o -L/<path-to-folder>/workspace/mbed/libraries/mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM -L/<path-to-folder>/workspace/mbed/libraries/mbed -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
I'm not exactly sure why the relative path didn't work. One of my friends suggested that it may be because '..' is a symbolic link in some sense.

Related

make command error: ld cannot find libraries that exist

I'm running make and ld will not find libraries that I have verified to exist using dnf provides '*/libpthread.so' for example. I get the following error code:
g++ -fopenmp -static -lpthread -o bayescan_2.1 start.o beta.o dirichlet.o RJupdates.o MHupdates.o likelihood.o read_write.o anyoption.o
/bin/ld: cannot find -lpthread
/bin/ld: cannot find -lm
/bin/ld: cannot find -ldl
/bin/ld: cannot find -lpthread
/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
make: *** [Makefile:4: bayescan_2.1] Error 1
These libraries all are found in /usr/lib64 on my chair's computing cluster. However the ld.so.conf file does not include a path that only goes to /usr/lib64 and I don't have admin permissions to create a new .conf file in /etc/ld.so.conf.d/.
Is there any way I can force make to search for the libraries in /usr/lib64?
Here is the actual Makefile in question:
# BayeScan makefile
bayescan_2.1: start.o beta.o dirichlet.o RJupdates.o MHupdates.o likelihood.o read_write.o anyoption.o
g++ -fopenmp -static -lpthread -o bayescan_2.1 start.o beta.o dirichlet.o RJupdates.o MHupdates.o likelihood.o read_write.o anyoption.o
start.o: start.cpp errors.cpp anyoption.h global_defs.h
g++ -fopenmp -c start.cpp errors.cpp
beta.o: beta.cpp global_defs.h
g++ -fopenmp -c beta.cpp
dirichlet.o: dirichlet.cpp global_defs.h
g++ -fopenmp -c dirichlet.cpp
RJupdates.o: RJupdates.cpp global_defs.h
g++ -fopenmp -c RJupdates.cpp
MHupdates.o: MHupdates.cpp global_defs.h
g++ -fopenmp -c MHupdates.cpp
likelihood.o: likelihood.cpp global_defs.h
g++ -fopenmp -c likelihood.cpp
read_write.o: read_write.cpp errors.cpp global_defs.h
g++ -fopenmp -c read_write.cpp errors.cpp
anyoption.o: anyoption.cpp anyoption.h
g++ -fopenmp -c anyoption.cpp
clean:
rm *.o bayescan_2.1
EDIT:
Turns out ld was trying to find static libraries with the -static flag. Removing this flag from the Makefile fixed the issue.
Simply add -L/usr/lib64 to the link command. See Directory Options in the GCC manual:
-Ldir
Add directory dir to the list of directories to be searched for -l.
If you can't or don't want to edit the Makefile, you can supply additional search directories through an environment variable
LIBRARY_PATH
The value of LIBRARY_PATH is a colon-separated list of directories, much like PATH. When configured as a native compiler, GCC tries the directories thus specified when searching for special linker files, if it cannot find them using GCC_EXEC_PREFIX. Linking using GCC also uses these directories when searching for ordinary libraries for the -l option (but directories specified with -L come first).
For example, run this in your shell before invoking make:
$ export LIBRARY_PATH="$LIBRARY_PATH:/usr/lib64"

mingw g++ is unable to link with libraries

I'm trying to use X86_64-w64-mingw32-g++ (packaged in Archlinux's MingW package) to cross compile some C++ code into an Windows executable, however I'm having trouble getting past some issues.
I'm calling
x86_64-w64-mingw32-g++ -o build_win/asm build_win/asm.o build_win/asm_lib.o build_win/socket_boost.o -I../extra/etc -fopenmp -lrt -std=c++11 -g -lboost_system -lboost_serialization
from a makefile, but I get thrown the errors:
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lrt
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lboost_system
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lboost_serialization
This works fine with native g++, so exactly do I have to change for mingw to compile?
EDIT: I have mingw-w64-boost package installed, which includes boost libraries pre-compiled and ready to be linked. However, it seems the naming convention is a bit different, and -lboost_system for example becomes -llibboost_system-mt (not exactly sure what the -mt suffix entails).
Problem is I can't find the mingw counterpart for -lrt. I've tried with both -lrtm and -lrtutils but in both cases I get:
[...]
undefined reference to `__imp_getsockopt'
Are you sure that -lboost_system and other libraries are present in the same directory as makefile ?
If not then please include -L flag which indicates the location of your library.
For example:
-L /path_openmp -fopenmp -L /path_boost_system/ -lboost_system -L /path_serialization -lboost_serialization
Moreover, you need not include -I and -g flag when creating an executable from .o files. These are needed when you create .o from .cpp files.
There is no rt library on Windows.
You are missing -lws2_32.
$ x86_64-w64-mingw32-nm -A /usr/x86_64-w64-mingw32/lib/*.a 2>/dev/null | grep getsockopt | grep " T "

C++: linker cannot find -lcrypto, but the library is in the path

I am compiling a C++ application using GNU g++. The project takes advantage of OpenSSL libraries.
Background
On my machine (a 64 bit CentOS quad core) I compile and link my files.
g++ -g -c -L/usr/local/lib/ -L/usr/lib64/
-I/usr/local/include/ -I/usr/local/ssl/include/
-lcrypto mysrc1.cpp mysrc2.cpp mysrc3.cpp
g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
My application uses function MD5 which is contained in libcrypto.so. As you can see I specify to g++ the dirs where to search using the -L, -I options and which libraries to look for with the -l<lib-name> option. There are some trivial paths like /usr/local/lib which can be omitted of course, but I specified them because the makefile is parametric.
The problem
My problem is that I can successfully compile my stuff (first command), but linking fails (second command):
/usr/bin/ld: cannot find -lcrypto
collect2: ld returned 1 exit status
make: * [cppsims_par] Error 1
But I did check folders and everything... libcrypto.so is inside /usr/lib64/. What is going on?
It may help if you try strace to find why it failed the file lookup
strace -f -e trace=file g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
I did find the problem and it is related to this question: ld cannot find an existing library
Actually I had no symlink libcrypto.so and the compiler was not able to find the library...
I had related issue, and resolved it after inspecting the trace.
I had
-L<my/path/to/lib> -llib_some_library
when it should have been
-L<my/path/to/lib> -lsome_library

Static linking failed although the name exists

I'm trying to link to a static library, libcovis.a. Everything looks fine but I still have
undefined reference to `CoViG_PublicDemo::MoInS::reset()'
I checked that the name exists in the library
$nm libcovis.a | grep reset
...
_ZN16CoViG_PublicDemo5MoInS5resetEv
...
I'm using linking arguments -L/path/to/libcovis.a -lcovis
What am I doing wrong ?
Edit:
The error might be something else, if do
gcc main.cpp -I/usr/include/opencv -I/usr/include/cairo -I../../Source -o slam -rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo ../../Source/libcovis.a ../../Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps
It works !
But when I'm in KDevelop using cmake, I doesn't work anymore. I use
CMAKE_EXE_LINKER_FLAGS:STRING=-rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo /usr/local/src/CoViS-0.0.0-1/Source/libcovis.a /usr/local/src/CoViS-0.0.0-1/Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps
CMAKE_CXX_FLAGS:STRING=-I/usr/local/src/CoViS-0.0.0-1/Source -I/usr/include/opencv -I/usr/include/cairo
The only difference I can see is that the paths are absolute and not relative, but if he couldn't find the libs, he would say it...
There are two different issues there, the first of which is the simplest, you have used the wrong compiler options. The -L option tells the linker to also look in the directory when looking for a library. The -l tells it to link the specific library. To link you would then use:
g++ -o test test.o -L/path/to -lcovis
or
g++ -o test test.o -l/path/to/libcovis.a
To force static linking if the same library is present as a dynamic library in the same directory.
The second potential issue is that the order of static libraries in the linker command line does matter, so that might also be an issue if there is a dependency on different static libs.
g++ -o test tests.o -ldependent -lprovider
The linker will process the libraries in order as they are in the command line, and from each static lib it will only pull those symbols that are required (with as much information as the linker has at that time). In the command line above, the linker will extract from dependent the symbols it needs for test.o, and that might in turn add new undefined symbols to the program (the dependencies of dependent). When it processes provider it will fill in those symbols. If the order was reversed in the command line, the symbols that are required by dependent but not by test.o would not be added to the executable, as the linker does not know that those symbols will be needed when processing provider.
Should the arguments be like -L/path/to/ -lcovis?
Besides, object files should be placed before libs, for example
g++ obj1.o obj2.o -L/path/to/ -lcovis.
If you see the link succeeding in one context but not another, I suspect the problem may be caused by the order in which the link operation is executed as the linker will discard symbols in a library if they're not needed at the point in which the library is referenced.
Here is a link explaining: http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html
I've run into similar situations in the past the linking order was found to be the cause of the problem.

CUDA: Creating object with G++ linker and cuda object files

I compiled my normal cpp files to .o, and my cuda .cu files to .co
I want to link these so I can call the cuda stuff from my normal C++ file
Here is my linker command that Make is running:
g++ -I ../readers/ -I../writers -I../common/ -I /home/dcole/software/xerces-c-3.1.1/src -I /home/dcole/NVIDIA_GPU_Computing_SDK/C/common/inc/ -I /usr/local/cuda/include -O3 -fPIC -fopenmp -DFIX_PAULI -DFIX_YAMA -DUSING_CUDA -o YamaguchiGPU YamaguchiMain.o YamaguchiDecomp.o cuYamaguchi.co -L/usr/lib64/ ../../lib/IDT.a ../../lib/Linux/libxerces-c.a ../../lib/Linux/libfftw3f.a -lcurl -lidn -ldl -lssl -lm -lpthread -lcuda -L/usr/local/cuda/lib64/libcudart.so
So I am definitly linking cuda, and cudart, but yet I get this:
cuYamaguchi.co: In function `__sti____cudaRegisterAll_46_tmpxft_00003190_00000000_4_cuYamaguchi_cpp1_ii_init_gpu()':
tmpxft_00003190_00000000-1_cuYamaguchi.cudafe1.cpp:(.text+0x1b4): undefined reference to `__cudaRegisterFatBinary'
tmpxft_00003190_00000000-1_cuYamaguchi.cudafe1.cpp:(.text+0x20f): undefined reference to `__cudaRegisterFunction'
The Cuda file is being linked without problems but it looks like you might have forgotten to define some necessary function (like cudaRegisterFatBinary).
Upgrading to gcc 4.7.0 or higher should fix this horrid linker issue.
I was using an absolute search path in the linker to _libcudart.so_. I changed the -L to point to just the folder, then added -libcudart so it would search the folder for that lib.