I am trying to compile on a Ubuntu system where I have two different versions of boost instaled: 1.46.1 in /usr/lib/ and 1.61.0 in /usr/local/lib/.
I have stated that 1.61.0 is giving me some compilation issues, but I prefer not removing it to study the problem when I have more time. I supposed I could refer at the makefile to 1.46.1, using -I"/usr/include/boost" for 1.46.1 source, and then -L /usr/lib for the libraries. But still not working.
My suspicion is that the usage of -lboost_filesystem -lboost_system -lboost_date_time are somehow referencing to 1.61.0, even when used together with -L /usr/lib (which points to 1.46.1). But I have been unable to find information about this compilation flags for the linker.
How can I make sure those -l are referenced to the Boost version I want?
Here is an example of what the makefile is doing while linking (the part where it is failing):
Invoking: Cygwin C++ Linker
g++ -O0 -g3 -Wall -Wextra -o"../bin/MY_APP.exe" ../bin/objs/main.o ../bin/objs/FileLoad.o ../bin/objs/DatabaseLoad.o -L /usr/lib/mysql -L /usr/lib -lmysqlclient -lboost_filesystem -lboost_system -lboost_date_time
You can confirm or disprove your suspicions by getting the linker to confess which libraries it is actually using. Add the option -Wl,--verbose to your g++ link command line (in the makefile or try this directly). The linker will then spit out which exact file was matched for everything it was trying to link, including your boost libraries.
If it turns out it is in fact linking the wrong versions, it also gives you a clue as to why exactly, by specifying the exact order of paths which the linker tries in locating a given library. This should give you some ammo should you need to change around some of your options (e.g. ordering and/or content of -L... and -l... options)
Should this fail, you can also use the option -l:/path/to/exact/libboost_whatever.so. This will force to use the linker the given version. I would try this last though.
Related
I have some basic questions regarding linking against a C/C++ library. I am trying to understand the difference in using the two different usages -L/usr/local/lib -lm usage and /usr/local/lib/libm.a usage. E.g., when I compile and link an example from the [SUNDIALS] library, both of the following work
gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe -I/usr/local/include -L/usr/local/lib/ -lsundials_cvode -lsundials_nvecserial -lm
OR
gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe /usr/local/lib/libsundials_cvode.a /usr/local/lib/libsundials_nvecserial.a
However, to compile and link an example from the library [libsbml], the following works
g++ -Wall readSBML.cpp -o readSBML.exe -I/usr/local/include -L/usr/local/lib -lsbml
but the this does not
g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.a
If required, I can post the complete error message I get, but the last line of the message is as follows
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
My questions are as follows:
In the second style of linking (of the first example), there is no information regarding where to find the include files (header files), how does the compiler know the information supplied in -I/usr/local/include which is provided in the first style of the first example?
In the second style of first example there is no /usr/local/lib/libm.a (it actually gives an error message that libm.a cannot be found if I try to include it), then why -lm is required in the first style?
How do I compile the second example in the second style (i.e., using /usr/local/lib/libsbml.a)? I do see that there are files - libsbml.a and libsbml-static.a in the /usr/local/lib folder, but none of them work.
If it helps, I am on an OS X machine.
I would be very thankful if any one could help in this regard.
Just an update - I tried
g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.5.dylib
and that compiled and linked just fine.
Thanks
SN
In general
The -L option is meant to find where the libraries themselves are. Each library is a collection of one or more object code (machine language) files. There is no need to find the include files.
The -I option has nothing to with linker, it helps the compiler resolve the header files used in your driver programme( eg Roberts_dns.c). This happens during the pre-processing stage.
In the second style of linking (of the first example), there is no
information regarding where to find the include files (header files),..
If the compilation worked as you expected,it may be because /usr/local/include is in the default include path for gcc. To check the default include path for gcc do gcc -xc -E -v -.
In the second style of first example there is no
/usr/local/lib/libm.a(it actually gives an error message that libm.a
cannot be found if I try to include it), then why -lm is required in
the first style?
In Linux, some libraries like libc.a are directly linked to your execultable by default while libm.a is not. In Mac (your environment), though, libm is directly link to the executable by default. So you don't have to explicitly link it. It is less likely that libm.a is located in /usr/local/lib/. So you got an error. But why link it in the first place?
I'm trying to compile a program on Ubuntu 11.10 that uses the Boost libraries. I have the 1.46-dev Boost libraries from the Ubuntu Repository installed, but I get an error when compiling the program.
undefined reference to boost::system::system_category()
What is it that I do wrong?
The boost library you are using depends on the boost_system library. (Not all of them do.)
Assuming you use gcc, try adding -lboost_system to your compiler command line in order to link against that library.
Linking with a library that defines the missing symbol (-lboost_system) is the obvious solution, but in the particular case of Boost.System, a misfeature in the original design makes it use boost::system::generic_category() and boost::system::system_category() needlessly. Compiling with the flag -DBOOST_SYSTEM_NO_DEPRECATED disables that code and lets a number of programs compile without requiring -lboost_system (that link is of course still needed if you explicitly use some of the library's features).
Starting from Boost 1.66 and this commit, this behavior is now the default, so hopefully fewer and fewer users should need this answer.
As noticed by #AndrewMarshall, an alternative is to define BOOST_ERROR_CODE_HEADER_ONLY which enables a header-only version of the code. This was discouraged by Boost as it can break some functionality. However, since 1.69, header-only seems to have become the default, supposedly making this question obsolete.
Another workaround for those who don't need the entire shebang: use the switch
-DBOOST_ERROR_CODE_HEADER_ONLY.
If you use CMake, it's add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY).
The above error is a linker error... the linker a program that takes one or more objects generated by a compiler and combines them into a single executable program.
You must add -lboost_system to you linker flags which indicates to the linker that it must look for symbols like boost::system::system_category() in the library libboost_system.so.
If you have main.cpp, either:
g++ main.cpp -o main -lboost_system
OR
g++ -c -o main.o main.cpp
g++ main.o -lboost_system
When using CMAKE and find_package, make sure it is :
find_package(Boost COMPONENTS system ...)
and not
find_package(boost COMPONENTS system ...)
Some people may have lost hours for that ...
I got the same Problem:
g++ -mconsole -Wl,--export-all-symbols -LC:/Programme/CPP-Entwicklung/MinGW-4.5.2/lib -LD:/bfs_ENTW_deb/lib -static-libgcc -static-libstdc++ -LC:/Programme/CPP-Entwicklung/boost_1_47_0/stage/lib \
D:/bfs_ENTW_deb/obj/test/main_filesystem.obj \
-o D:/bfs_ENTW_deb/bin/filesystem.exe -lboost_system-mgw45-mt-1_47 -lboost_filesystem-mgw45-mt-1_47
D:/bfs_ENTW_deb/obj/test/main_filesystem.obj:main_filesystem.cpp:(.text+0x54):
undefined reference to `boost::system::generic_category()
Solution was to use the debug-version of the system-lib:
g++ -mconsole -Wl,--export-all-symbols -LC:/Programme/CPP-Entwicklung/MinGW-4.5.2/lib -LD:/bfs_ENTW_deb/lib -static-libgcc -static-libstdc++ -LC:/Programme/CPP-Entwicklung/boost_1_47_0/stage/lib \
D:/bfs_ENTW_deb/obj/test/main_filesystem.obj \
-o D:/bfs_ENTW_deb/bin/filesystem.exe -lboost_system-mgw45-mt-d-1_47 -lboost_filesystem-mgw45-mt-1_47
But why?
When I had this, problem, the cause was the ordering of the libraries. To fix it, I put libboost_system last:
g++ mingw/timer1.o -o mingw/timer1.exe -L/usr/local/boost_1_61_0/stage/lib \
-lboost_timer-mgw53-mt-1_61 \
-lboost_chrono-mgw53-mt-1_61 \
-lboost_system-mgw53-mt-1_61
This was on mingw with gcc 5.3 and boost 1.61.0 with a simple timer example.
in my case, adding -lboost_system was not enough, it still could not find it in my custom build environment. I had to use the advice at Get rid of "gcc - /usr/bin/ld: warning lib not found" and change my ./configure command to:
./configure CXXFLAGS="-I$HOME/include" LDFLAGS="-L$HOME/lib -Wl,-rpath-link,$HOME/lib" --with-boost-libdir=$HOME/lib --prefix=$HOME
for more details see Boost 1.51 : "error: could not link against boost_thread !"
...and in case you wanted to link your main statically, in your Jamfile add the following to requirements:
<link>static
<library>/boost/system//boost_system
and perhaps also:
<linkflags>-static-libgcc
<linkflags>-static-libstdc++
I installed Boost via sudo apt-get install libboost-all-dev on the most recent version of Ubuntu. Now I want to compile a project that uses the Boost.Serialization library, which needs to be linked.
I've tried many variants of the following, without success:
gcc -I /usr/lib code.cpp -o compiled /usr/lib/libboost_serialization.a
and
gcc -I /usr/lib code.cpp -o compiled -l libboost_serialization
The error message is:
error: ‘split_member’ is not a member of ‘boost::serialization
`
What am I missing?
You are having troubles with compiling your code, not linking. On that stage it has nothing to do with libraries. At that point the fact that you have to link against something is irrelevant.
Make sure you are including boost/serialization/split_member.hpp directly or indirectly and get your code compiled first.
On a side note, -I flag is used to specify path to include files and not libraries. For libraries, use -L. But if you have installed Boost from apt, then it should already be in the path and so no additional -I or -L should be required. And when you specify -l, you have to emit lib from the beginning of library name and not put a space between a flag and its argument. Assuming working code, something like this should do:
g++ code.cpp -o compiled -lboost_serialization
I'd also recommend you pass -Wall flag to make compiler be more verbose and warn you about possible mistakes in your code.
split member is a problem with compiling where boost is assuming there are split calls for serialize and deserialize.
http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/
I'm trying to compile a program on Ubuntu 11.10 that uses the Boost libraries. I have the 1.46-dev Boost libraries from the Ubuntu Repository installed, but I get an error when compiling the program.
undefined reference to boost::system::system_category()
What is it that I do wrong?
The boost library you are using depends on the boost_system library. (Not all of them do.)
Assuming you use gcc, try adding -lboost_system to your compiler command line in order to link against that library.
Linking with a library that defines the missing symbol (-lboost_system) is the obvious solution, but in the particular case of Boost.System, a misfeature in the original design makes it use boost::system::generic_category() and boost::system::system_category() needlessly. Compiling with the flag -DBOOST_SYSTEM_NO_DEPRECATED disables that code and lets a number of programs compile without requiring -lboost_system (that link is of course still needed if you explicitly use some of the library's features).
Starting from Boost 1.66 and this commit, this behavior is now the default, so hopefully fewer and fewer users should need this answer.
As noticed by #AndrewMarshall, an alternative is to define BOOST_ERROR_CODE_HEADER_ONLY which enables a header-only version of the code. This was discouraged by Boost as it can break some functionality. However, since 1.69, header-only seems to have become the default, supposedly making this question obsolete.
Another workaround for those who don't need the entire shebang: use the switch
-DBOOST_ERROR_CODE_HEADER_ONLY.
If you use CMake, it's add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY).
The above error is a linker error... the linker a program that takes one or more objects generated by a compiler and combines them into a single executable program.
You must add -lboost_system to you linker flags which indicates to the linker that it must look for symbols like boost::system::system_category() in the library libboost_system.so.
If you have main.cpp, either:
g++ main.cpp -o main -lboost_system
OR
g++ -c -o main.o main.cpp
g++ main.o -lboost_system
When using CMAKE and find_package, make sure it is :
find_package(Boost COMPONENTS system ...)
and not
find_package(boost COMPONENTS system ...)
Some people may have lost hours for that ...
I got the same Problem:
g++ -mconsole -Wl,--export-all-symbols -LC:/Programme/CPP-Entwicklung/MinGW-4.5.2/lib -LD:/bfs_ENTW_deb/lib -static-libgcc -static-libstdc++ -LC:/Programme/CPP-Entwicklung/boost_1_47_0/stage/lib \
D:/bfs_ENTW_deb/obj/test/main_filesystem.obj \
-o D:/bfs_ENTW_deb/bin/filesystem.exe -lboost_system-mgw45-mt-1_47 -lboost_filesystem-mgw45-mt-1_47
D:/bfs_ENTW_deb/obj/test/main_filesystem.obj:main_filesystem.cpp:(.text+0x54):
undefined reference to `boost::system::generic_category()
Solution was to use the debug-version of the system-lib:
g++ -mconsole -Wl,--export-all-symbols -LC:/Programme/CPP-Entwicklung/MinGW-4.5.2/lib -LD:/bfs_ENTW_deb/lib -static-libgcc -static-libstdc++ -LC:/Programme/CPP-Entwicklung/boost_1_47_0/stage/lib \
D:/bfs_ENTW_deb/obj/test/main_filesystem.obj \
-o D:/bfs_ENTW_deb/bin/filesystem.exe -lboost_system-mgw45-mt-d-1_47 -lboost_filesystem-mgw45-mt-1_47
But why?
When I had this, problem, the cause was the ordering of the libraries. To fix it, I put libboost_system last:
g++ mingw/timer1.o -o mingw/timer1.exe -L/usr/local/boost_1_61_0/stage/lib \
-lboost_timer-mgw53-mt-1_61 \
-lboost_chrono-mgw53-mt-1_61 \
-lboost_system-mgw53-mt-1_61
This was on mingw with gcc 5.3 and boost 1.61.0 with a simple timer example.
in my case, adding -lboost_system was not enough, it still could not find it in my custom build environment. I had to use the advice at Get rid of "gcc - /usr/bin/ld: warning lib not found" and change my ./configure command to:
./configure CXXFLAGS="-I$HOME/include" LDFLAGS="-L$HOME/lib -Wl,-rpath-link,$HOME/lib" --with-boost-libdir=$HOME/lib --prefix=$HOME
for more details see Boost 1.51 : "error: could not link against boost_thread !"
...and in case you wanted to link your main statically, in your Jamfile add the following to requirements:
<link>static
<library>/boost/system//boost_system
and perhaps also:
<linkflags>-static-libgcc
<linkflags>-static-libstdc++
I'm trying to use openssl in a gcc program but it isn't working.
g++ server.cpp /usr/lib/libssl.a -o server
gives an error message, as does anything with the -l option. What must I type on the command line to link with openssl? The file /usr/lib/libssl.a exists, but nevertheless I still get the linker error no such function MD5() exists.
Without knowing the exact errors you are seeing, it is difficult to provide an exact solution. Here is my best attempt.
From the information you provided, it sounds as though the linker is failing because it cannot find a reference to the md5 function in libssl.a. I believe this function is actually in libcrypto so you may need to specify this library as well.
g++ server.cpp -L/usr/lib -lssl -lcrypto -o server
You or others may find this article developerWorks article helpful.
Secure programming with the OpenSSL API
https://developer.ibm.com/technologies/linux/tutorials/l-openssl
It describes most things you need to know to get off the ground with OpenSSL and C/C++. If you find you are following most of the same steps, it might help you see what needs doing.
Good luck.
update
revised link: https://developer.ibm.com/technologies/linux/tutorials/l-openssl
Which has been shuffled around
original link: http://www.ibm.com/developerworks/linux/library/l-openssl.html
Which now goes to a digest page including the article.
Note: keeping both links because they be used to find new discoveries.
In Eclipse IDE select Your Project property --> c/c++ Build --> Settings gcc c linker(from tools settings)--> add to Library Search Path (-L)
/usr/lib -lssl -lcrypto
The location of the library is not fixed. In my case (Ubuntu 18.04), the .a files are located in /usr/lib/x86_64-linux-gnu/. So here are the complete steps:
1) install the library,
sudo apt install libss-dev
2) check the installed files,
dpkg-query -L libssl-dev
3) change the gcc flags -L(library directory) -l(library name), e.g.,
gcc XXX.c XXXXX.c -L/usr/lib/x86_64-linux-gnu/ -lcrypto -lssl
On top of the accepted answers, I could not make compile the OpenSSL example for AES-CCM:
https://github.com/openssl/openssl/blob/master/demos/evp/aesccm.c
To make it work I needed to add two more things:
The Dinamic Linking Library : -ldl
The PThread library to use POSIX threading support: -pthread (Adding directly the library with -lpthread is not recommended )