Undefined boost reference despite correct linking - c++

I found a lot of similar problems, but I was not able to apply any given solution for me. A few months ago, I worked on a project using the boost library. I compiled simply in the command line, as described on the boost website.
g++ -I pathToBoost file.cpp -o file -lboost_system -lboost_filesystem
The two required linkings to boost_system and boost_filesystem were also done. This worked perfectly, but now suddenly an error occurs when i tried to compile it again.
/usr/bin/ld: /tmp/ccM2BzEo.o: in function `boost::system::generic_category()':
file.cpp:(.text._ZN5boost6system16generic_categoryEv[_ZN5boost6system16generic_categoryEv]+0x7):
undefined reference to `boost::system::detail::generic_category_instance'
Well, it seems to me that there is an error linking the boost_system library. Since the same thing worked before, is a problem with the compiler possible?
I used
Boost 1.68.0
g++ (GCC) 8.2.1
ManjaroLinux 18.0.3
I hope that somebody can help me here and that I was not just too stupid to see a solution in another thread.
Greetings!

The order of libraries in linker command line is important. boost_filesystem depends on boost_system, hence the fix:
-lboost_filesystem -lboost_system
Alternatively, you can surround the list of libraries with --start-group and --end-group to make the linker re-scan the libraries multiple times until it either fails or resolves all symbols, so that no specific ordering of libraries in the command line is necessary. However, it may take longer to link. E.g.:
g++ -I pathToBoost file.cpp -o file -Wl,--start-group -lboost_system -lboost_filesystem -Wl,--end-group
Since you specify -I pathToBoost you also need to specify -L<path-to-boost-libs> -Wl,-rpath=<path-to-boost-libs>. Otherwise it uses headers from one version of boost from pathToBoost, but links wrong libraries from your system boost.

Related

g++ cannot link stdc++ statically (windows)

I've been doing a simple c++ program with use of curlpp library. I can build and compile everything just right and I can run it if having MinGW in my PATH. When I delete it and copy all curlpp dlls in the directory, it says (of course):
The program can't start because libgcc_s_dw2-1.dll is missing from your computer. Try reinstalling the program to fix this problem.
I believe that the problem is that std libraries are not linked statically, but I tried all possibilities and it seems as they are not linked. I type:
g++ -o myApp.exe main.cpp -std=gnu++11 -L(curl,curlpp,opensll) -I(all includes) -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -lcurlpp -lcurl -Wl,--as-needed
with no errors, then I run it and I get error from above. Of course, if I have MinGW in my PATH, then everything works.
I tried to change the order of options in the command without any luck. Putting -static-libgcc -static-libstdc++ as advised elsewhere is not working.
Thanks in advance
Regards

g++ cannot find shared library

I apologize that this is redundant, but none of the answers available seem to be able to solve my problem. I am attempting to compile an executable using a shared object library. The shared object library is called libsession.so and is found in the same directory that I am compiling the executable. To compile and link, I use the following command
g++ test_main.cpp -o program -std=c++11 -I ../src/base -L. -lsession
Unforutanely, I get the cannot find -lsession error when linking. If I change the command to directly reference the shared library as follows
g++ test_main.cpp -o program -std=c++11 -I ../src/base libsession.so
then the executable compiles/links and all is well. Does anyone have any thoughts as to what I may be doing wrong?
The only difference between using an '-l' option and specifying a file
name is that '-l' surrounds library with 'lib' and `.a' and searches
several directories.
https://gcc.gnu.org/onlinedocs/gcc-3.0/gcc_3.html#SEC16

Linking libraries in GCC

there are some files that I am trying to compile in ubuntu using makefile.
I have added the following lines in my makefile after several searches on web.
run: hellocode.cpp
g++ -c hellocode.cpp -lssl -lcrypto
Still while compiling it creates the object files and then throws this error:
undefined reference to 'SSL_write'....
on the contrary if remove the '-c' and use it like this
run: hellocode.cpp
g++ hellocode.cpp -lssl -lcrypto
Then I dont see the previous errors of linking but it shows different errors not related to openssl linking but related to other files in the code. I have already browsed through many questions on this forum related to this none seem to have helped me in this.
Kindly tell me whether my makefile is wrong or is there some problem with my machine that its not able to link to my library.
Here's a simple Makefile that you could adopt. Note that compilation and linking are 2 steps. If needed you can use -I for additional include paths and -L for additional link paths.
.PHONY : all
all : hellocode
hellocode : hellocode.o
g++ -o hellocode hellocode.o -lssl -lcrypto
hellocode.o : hellocode.cpp
g++ -c hellocode.cpp -o hellocode.o
Here are some basics of makefiles if it helps.
library linking should be done at final stage - linking :)
-c means "compile only" - it just builds .o object file, without any reference resolution (so -lXXX is just ignored there).
-lXXX options should be added to last call to gcc (without -c) which produces executable, where all .o files are gathered to link together with libraries to resolve all references.

Why do I have to link these libraries twice for LLVM?

I'm trying to compile a sample LLVM program. The linker step uses this command.
llvm-config-3.2 --ldflags --libs
That results in the following command.
g++ -o bin/Debug/test-llvm obj/Debug/main.o -L/usr/lib/llvm-3.2/lib -lpthread -lffi -ldl -lm (a boat load of LLVM libraries here)
However, it fails to link. I get errors like this.
undefined reference to ffi_type_float
So, I added -lffi and -ldl to the end.
g++ -o bin/Debug/test-llvm obj/Debug/main.o -L/usr/lib/llvm-3.2/lib -lpthread -lffi -ldl -lm (a boat load of LLVM libraries here) -lffi -ldl
So, yes, they show up TWICE in the command... but it works this way. Why? They are clearly referenced earlier in the arguments.
One or more of the libraries appearing on the command line after -lffi and -ldl refer to symbol(s) defined in one of those libraries. But the linker has already finished scanning libffi and libdl and does not rescan them for these symbols. This circular dependency can be resolved by forcing the linker to scan those libraries again by re-listing their names at the end of the list.
A more scalable solution is to use --start-group archives --end-group option to list the libraries to link to. Quoting from the man page:
-( archives -)
--start-group archives --end-group
The archives should be a list of archive files. They may be either explicit file names, or -l options.
The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched
only once in the order that it is specified on the command line. If a
symbol in that archive is needed to resolve an undefined symbol
referred to by an object in an archive that appears later on the
command line, the linker would not be able to resolve that reference.
By grouping the archives, they all be searched repeatedly until all
possible references are resolved.
Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between
two or more archives.
So your command line would look like this:
g++ -o bin/Debug/test-llvm obj/Debug/main.o -L/usr/lib/llvm-3.2/lib --start-group -lpthread -lffi -ldl -lm ... --end-group
Ah, I found the solution. Swapping the flags didn't actually change the order. I had to break it out into two separate calls.
llvm-config-3.2 --libs
llvm-config-3.2 --ldflags
And yeah, this is technically answered in that other question: Why does the order in which libraries are linked sometimes cause errors in GCC?
I still just think this question is relevant because doing what the docs told me to do led me into danger. :(
Why do I have to link these libraries twice
Because the order of archive libraries on command line matters, and yours is wrong.

Static linking with Boost and ncurses

I am in the process of making a basic role-playing game. I want to include the Boost libraries statically so that the people who run my game do not need to have them. I researched and looked-up that all you have to do is add -static to the command-line compile, so my command is like this:
$ g++ -static -o karthas *.o -lncurses -lmenu -lboost_system -lboost_filesystem
But apparently the -static is affecting ncurses. I am getting a whole bunch of errors, most of which are undefined reference to 'SP'.
Is it possible to just do a static link to Boost and not ncurses? How would I go about doing that?
You can choose which libraries will be linked statically and which will be linked dynamically by putting either -Wl,-static or -Wl,-Bdynamic before their name.
For example, with:
g++ -o karthas *.o -Wl,-static -lmenu -lboost_system -lboost_filesystem -Wl,-Bdynamic -lncurses
The menu, boost_system and boost_filesystem libraries will be linked statically and ncurses dynamically.
(But you can also distribute the boost dlls with your executable, and not link anything statically).
But looking at this, it seems that you are not alone, either that, or I found your issue. But this, might have your solution, either way, good luck.
Btw, some boost libraries are little more than inline functions that are imported when included in the file.