Including boost libraries in make files - boost

I'm learning Boost and am having trouble with my makes files.
Here is my basic makefile:
accesstimer: acctime.o btimer.o
g++ acctime.o btimer.o -o accesstimer
acctime.o: acctime.cpp btimer.h
g++ -c acctime.cpp
bentimer.o: btimer.cpp btimer.h
g++ -c btimer.cpp
When acctime.cpp has no boost filesystem elements in it this m,ake file works fine.
As soon as I add boost filesystem elements I obviously need to make references to the boost libray in the make file this is where I am having issues.
The following line works for a single file compilation:
g++ -I /usr/local/boost/boost_1_39_0 boosttest1.cpp -o bt1 /usr/local/boost/boost_1_39_0/stage/lib/libboost_filesystem-gcc41-mt.a /usr/local/boost/boost_1_39_0/stage/lib/libboost_system-gcc41-mt.a
Now I'm trying to integrate this into the make file. I've tried many based on what information I can find on the web but none are working this is my latest:
accesstimer: acctime.o bentimer.o
g++ acctime.o bentimer.o -o accesstimer
acctime.o: acctime.cpp bentimer.h
g++ -c -I /usr/local/boost/boost_1_39_0 acctime.cpp /usr/local/boost/boost_1_39_0/stage/lib/libboost_filesystem-gcc41-mt.a /usr/local/boost/boost_1_39_0/stage/lib/libboost_system-gcc41-mt.a
bentimer.o: bentimer.cpp bentimer.h
g++ -c bentimer.cpp
Unfortunately it stlill can't find the Boost libraries, can anyone help?
thanks
Having read the advice of the people who've answered I've now got this:
accesstimer: acctime.o bentimer.o
g++ -L /usr/local/boost/boost_1_39_0 acctime.o /usr/local/boost/boost_1_39_0/stage/lib/libboost_filesystem-gcc41-mt.a /usr/local/boost/boost_1_39_0/stage/lib/libboost_system-gcc41-mt.a bentimer.o -o accesstimer
acctime.o: acctime.cpp bentimer.h
g++ -c acctime.cpp
bentimer.o: bentimer.cpp bentimer.h
g++ -c bentimer.cpp
But this still fails to link.
This is the error message I'm getting:
g++ -L /usr/local/boost/boost_1_39_0/stage/lib/libboost_filesystem-gcc41-mt.a /usr/local/boost/boost_1_39_0/stage/lib/libboost_system-gcc41-mt.a acctime.o bentimer.o -o accesstimer
acctime.o: In function boost::enable_if<boost::filesystem::is_basic_path<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >, bool>::type boost::filesystem::exists<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)':
acctime.cpp:(.text._ZN5boost10filesystem6existsINS0_10basic_pathISsNS0_11path_traitsEEEEENS_9enable_ifINS0_13is_basic_pathIT_EEbE4typeERKS7_[boost::enable_if<boost::filesystem::is_basic_path<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >, bool>::type boost::filesystem::exists<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0x26): undefined reference to `boost::filesystem::detail::status_api(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&)'
collect2: ld returned 1 exit status
make: *** [accesstimer] Error 1
Following orsogufo's advice (thanks! much appreciated) now have this:
accesstimer: acctime.o bentimer.o
g++ -L/usr/local/boost/boost_1_39_0/stage/lib -llibboost_filesystem-gcc41-mt.a -llibboost_system-gcc41-mt.a acctime.o bentimer.o -o accesstimer
acctime.o: acctime.cpp bentimer.h
g++ -c acctime.cpp
bentimer.o: bentimer.cpp bentimer.h
g++ -c bentimer.cpp
Looking better, but still can't quite find the library:
g++ -L/usr/local/boost/boost_1_39_0/stage/lib -llibboost_filesystem-gcc41-mt.a -llibboost_system-gcc41-mt.a acctime.o bentimer.o -o accesstimer
/usr/bin/ld: cannot find -llibboost_filesystem-gcc41-mt.a
collect2: ld returned 1 exit status
make: *** [accesstimer] Error 1
I've double checked that location and the library is definately at:
/usr/local/boost/boost_1_39_0/stage/lib/libboost_filesystem-gcc41-mt.a
STill no joy, usimg this now:
accesstimer: acctime.o bentimer.o
g++ -L/usr/local/boost/boost_1_39_0 -lboost_filesystem-gcc41-mt acctime.o bentimer.o -o accesstimer
acctime.o: acctime.cpp bentimer.h
g++ -I /usr/local/boost/boost_1_39_0 -c acctime.cpp
bentimer.o: bentimer.cpp bentimer.h
g++ -c bentimer.cpp
Getting:
g++ -L/usr/local/boost/boost_1_39_0/stage/lib/ -llibboost_filesystem-gcc41-mt acctime.o bentimer.o -o accesstimer
/usr/bin/ld: cannot find -llibboost_filesystem-gcc41-mt
collect2: ld returned 1 exit status
make: *** [accesstimer] Error 1
It's working with this:
accesstimer: acctime.o bentimer.o
g++ -L/usr/local/boost/boost_1_39_0/stage/lib -lboost_filesystem acctime.o bentimer.o -o accesstimer
acctime.o: acctime.cpp bentimer.h
g++ -I /usr/local/boost/boost_1_39_0 -c acctime.cpp
bentimer.o: bentimer.cpp bentimer.h
g++ -c bentimer.cpp
Thanks for all your help

When you link the object files to create the executable (your first makefile rule) you must pass the location of the boost libraries with the -L flag and the names of the libraries with the -l flag.
accesstimer: acctime.o bentimer.o
g++ -L/usr/local/boost/boost_1_39_0/stage/lib -lboost_filesystem acctime.o bentimer.o -o accesstimer
where /usr/local/boost/boost_1_39_0/stage/lib is the directory containing the libraries and boost_filesystem the file name of the library without the beginning lib (modify those two as appropriate).
The .a file you're trying to link is the wrong one... the library should have no extension.

Hi Following is the full procedure to add boost to cmake/make file. This answer is specially developed for the novice programmer in cpp.
If you want to add the boost library support with help of Makefile you need to specify library path (with -L option) and libraries (with -l option).
-L path/to/the/libraries
-l llibrary
**Now how to find path to libraries **
Following is the trick:
Open terminal and fire command
$ locate boost > libboost.txt
$ gedit libboost.txt
This command opens a text file which contains all boost library paths.
Now find ("ctr+F") libboost, which highlights the library files of boost with extension .a and .so in this text file.
Copy the path in which this .so files are present.
eg: If .so file present as on /usr/lib/x86_64-linux-gnu/libboost_filesystem.so
then specify path as : -L /usr/lib/x86_64-linux-gnu/
Now how to find respective library?
This depends on what boost functionalities/modules you are using
for example: If you are using boost threading, you will require following libraries
libboost_filesystem.so
libboost_thread.so
libboost_system.so
Add above libraries as follows with -l option:
-l lboost_filesystem
-l lboost_thread
-l lboost_system
Hope this will helps you, further If there is more easy way, please suggest

You need to add the boost libraries to the linking phase (the accesstimer target line) and not to the compilation phase (where only the include path is needed).

Related

How to modify makefile for openMP inclusion

HI everybody I am a beginner for both openMP and makefile. Here is my problem.
I usually compile simple openMP code via terminale using:
g++-10 -o file.exe -fopenmp file.cxx
Now I want to modify a code, which consists in many file linked together, adding openMP libraries. Indeed I have to change the already existing makefile and I have no idea how to do it. The openMP libraries are used only in the file "esercizio1.1.cxx".
Here the makefile:
esercizio1.1 : esercizio1.1.o random.o
g++ -o esercizio1.1 esercizio1.1.o random.o
esercizio1.1.o : esercizio1.1.cxx funzioni.h random.h
g++ -c -o esercizio1.1.o esercizio1.1.cxx
random.o : random.cxx random.h
g++ -c -o random.o random.cxx
clean:
rm esercizio1.1
Here an example of how I tried to modify my makefile. I renamed my file and I added
g++-10 -fopenmp
to all the line at the same time, to all the line one per time. but still does not work. Here an example:
esercizio : esercizio.o random.o
g++-10 -fopenmp esercizio.o random.o -o esercizio
esercizio.o : esercizio.cc funzioni.h random.h
g++-10 -fopenmp esercizio.cc -o esercizio.o
random.o : random.cc random.h
g++ random.cc -o random.o
clean:
rm esercizio
Here is the error:
Undefined symbols for architecture x86_64:
"__ZN6Random6RannyuEv", referenced from:
_main._omp_fn.0 in ccA635Wn.o
"__ZN6Random8SaveSeedEv", referenced from:
_main in ccA635Wn.o
"__ZN6Random9SetRandomEPiii", referenced from:
_main in ccA635Wn.o
"__ZN6RandomC1Ev", referenced from:
_main in ccA635Wn.o
"__ZN6RandomD1Ev", referenced from:
_main in ccA635Wn.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [esercizio.o] Error 1
Does it exist a guide for makefile beginner?
Anyway I would appreciate if someone helped me. Thanks in advance.
"C++ compilers are picky and may come with different ABIs, thus mixing different C++ compilers in the same project isn't advised. You are compiling random.cc with g++, which on macOS is a symlink to Apple's clang++. Use g++-10 instead. Also, g++ -o random.o random.cc produces an executable file, not an object file. Leave it as g++-10 -c -o random.o random.cc."
credits to Hristo Iliev. Thank you.

How to run manually produce an elf executable using ld?

I'm trying to get my head around how the linking process works when producing an executable. To do that I'm reading Ian Taylor's blog series about it, but a lot of it is beyond me at the moment - so I'd like to see how it works in practice.
At the moment I produce some object files and link them via gcc with:
gcc -m32 -o test.o -c test.c
gcc -m32 -o main.o -c main.c
gcc -m32 -o test main.o test.o
How do I replicate the gcc -m32 -o test main.o test.o stage using ld?
I've tried a very naive: ld -A i386 ./test.o ./main.o
But that returns me these errors:
ld: i386 architecture of input file `./test.o' is incompatible with i386:x86-64 output
ld: i386 architecture of input file `./main.o' is incompatible with i386:x86-64 output
ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
./test.o: In function `print_hello':
test.c:(.text+0xd): undefined reference to `_GLOBAL_OFFSET_TABLE_'
test.c:(.text+0x1e): undefined reference to `puts'
./main.o: In function `main':
main.c:(.text+0x15): undefined reference to `_GLOBAL_OFFSET_TABLE_
I'm most confused by _start and _GLOBAL_OFFSET_TABLE_ being missing - what additional info does gcc give to ld to add them?
Here are the files:
main.c
#include "test.h"
void main()
{
print_hello();
}
test.h
void print_hello();
test.c
#include <stdio.h>
void print_hello()
{
puts("Hello, world");
}
#sam : I am not the best people to answer your question because I am a beginner in compilation. I know how to compile programs but I do not really understand all the details (https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools)
So, I decided this year to try to understand how compilation works and I tried to do, more or less, the same things as you tried a few days ago. As nobody has answered, I am going to expose what I have done but I hope an expert will supplement my answer.
Short answer : It is recommended to not use ld directly but to use gcc directly instead. Nevertheless, it is, as you write, interesting to know how the linking process works. This command works on my computer :
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o /usr/lib/crtn.o
Very Long answer :
How did I find the command above ?
As n.m suggested, run gcc with -v option.
gcc -v -m32 -o test main.o test.o
... /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 ... (many
options and parameters)....
If you run ld with these options and parameters (copy and paste), it should work.
Try your command with -m elf_i386 (cf. collect2 parameters)
ld -m elf_i386 test.o main.o
ld: warning: cannot find entry symbol _start; ....
Look for symbol _start in object files used in the full ld command.
readelf -s /usr/lib/crt1.o (or objdump -t)
Symbol table '.symtab' contains 18 entries: Num: Value Size
Type Bind Vis Ndx Name... 11: 00000000 0 FUNC
GLOBAL DEFAULT 2 _start
Add this object to your ld command :ld -m elf_i386 test.o main.o /usr/lib/crt1.o
... undefined reference to `__libc_csu_fini'...
Look for this new reference in object files. It is not so obvious to know which library/object files are used because of -L, -l options and some .so include other libraries. For example, cat /usr/lib/libc.so. But, ld with --trace option helps. Try this commandld --trace ... (collect2 parameters)At the end, you should findld -m elf_i386 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc_nonshared.a /lib/libc.so.6 /usr/lib/crti.oor shorter (cf. cat /usr/lib/libc.so) ld -m elf_i386 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o
It compiles but it does not run (Try to run ./test). It needs the right -dynamic-linker option because it is a dynamically linked ELF executable. (cf collect2 parameters to find it) ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o But, it does not run (Segmentation fault (core dumped)) because you need the epilogue of the _init and _fini functions (https://gcc.gnu.org/onlinedocs/gccint/Initialization.html). Add the ctrn.o object. ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o /usr/lib/crtn.o./test
Hello, world

make error) Undefined reference to std::__cxx11::basic_string

When I command make, I got errors like this:
filter_block.cc:(.text+0x1c4): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_append(char const*, unsigned long)'
I found some solutions for this error, like adding -D_GLIBCXX_USE_CXX11_ABI=0, but I don't know how to add the command for make command.
The Makefile is written as:
.SUFFIXES: .c .cpp
CC = g++ -fopenmp
CFLAGS = -c -O2 -Wall -D_I386 -D_UNIX -fPIC -Wno-unused-result -std=c++11 -Wno-sign-compare
LFLAGS = -shared -O2 -o
LIBS = -llmi -lblas -lboost_regex -lpthread -lleveldb
How can I add -D_GLIBCXX_USE_CXX11_ABI=0 into Makefile?
*Ubuntu version = 14.04
*libstdc++ version
$ /sbin/ldconfig -p | grep stdc++
libstdc++.so.6 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
*gcc version
$ gcc --version
gcc (Ubuntu 5.4.1-2ubuntu1~14.04) 5.4.1 20160904
*ld version
$ ld --version
GNU ld (GNU Binutils for Ubuntu) 2.26.1

Gcc /usr/bin/ld compiler error

I got this error when I do make
gcc -o tests/simple_test tests/simple_test.o -L. libtraceback.a -Wall -Werror -gdwarf-2 -O0 -m32 -fno-stack-protector -fno-omit-frame-pointer -Itraceback/ -mpreferred-stack-boundary=2 -static
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_eh.a when searching for -lgcc_eh
/usr/bin/ld: cannot find -lgcc_eh
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
I read one post and tried
sudo ln -s /usr/lib/x86_64-linux-gnu /usr/lib64
But it doesn't help, is there any reason for this?
Im running on a surface pro 2 using vmware running 64bits ubuntu 13.10.
If you do not have any parcticular reason to build a 32bit application on a 64bit machine just do not use the option -m32.
In case you are following this tutorial then fixed make file code is below working on Ubuntu 20
# $# = target file
# $< = first dependency
# $^ = all dependencies
# First rule is the one executed when no parameters are fed to the Makefile
all: run
kernel.bin: kernel-entry.o kernel.o
ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary --entry main
kernel-entry.o: kernel-entry.asm
nasm $< -f elf -o $#
kernel.o: kernel.c
gcc -m32 -ffreestanding -c $< -o $# -fno-pie
mbr.bin: mbr.asm
nasm $< -f bin -o $#
os-image.bin: mbr.bin kernel.bin
cat $^ > $#
run: os-image.bin
qemu-system-i386 -fda $<
clean:
$(RM) *.bin *.o *.dis
To run make file
make run
to clean all output files
make clean

GCC suppress flags

I'm trying to create a shared library with my gcc. It's a gcc for vxworks (thats probably the problem...).
I use the gcc as following:
./gcc -shared -B/path/to/gnutools/bin -o test.so test.c
Result:
/path/to/ld: -r and -shared may not be used together
collect2: ld returned 1 exit status
If I try the same with the linux gcc, there's no problem. So i guess the gcc for VxWorks automatically passes the -r (or -i, which is the same and results in the same) flag to the linker. Is there a way to suppress this?
Greetz
marty
PS: making it static is not really an alternative...
Try compile object file separately with -fPIC and then link:
gcc -Wall -fPIC -c -o test.o test.c
gcc -Wall -shared -o test.so test.o
Another suggestion is to use libtool (at least to figure out the correct flags).
A workaround may be to go directly with ld:
ld -shared -o test.so test.o -lc

Resources