This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 5 years ago.
There are linker errors to Symbols defined by SFML, but i cannot see how they occur despite that I linked the lib.
I'm using make, which I currently learn and I want to build a minimalistic dev-environment with it.
Give a holler if you need anymore information than the following. I'd just like to minimize the questions size.
XXX#XXX ~/Documents/dev/cpp/proj/beep $ make clean
rm -f build/*.o build/release/*.o build/debug/*.o build/test/*.o
XXX#XXX ~/Documents/dev/cpp/proj/beep $ make tests
//test obj first
g++ -std=c++14 -Wall -pthread -Iinclude -c test/Packager.ut.cpp -o build/test/Packager.ut.o -g3
//now the src obj
g++ -std=c++14 -Wall -pthread -Iinclude -c src/ClientAddress.cpp -o build/debug/ClientAddress.o -g3
g++ -std=c++14 -Wall -pthread -Iinclude -c src/Packager.cpp -o build/debug/Packager.o -g3
g++ -std=c++14 -Wall -pthread -Iinclude -c src/Package.cpp -o build/debug/Package.o -g3
Built debug object files.
//now the first test itself
g++ -std=c++14 -Wall -pthread -Iinclude -lsfml-network build/test/Packager.ut.o build/debug/ClientAddress.o build/debug/Packager.o build/debug/Package.o -g3 -o bin/test/Packager.ut
build/test/Packager.ut.o: In function `main':
/home/XXX/Documents/dev/cpp/proj/beep/test/Packager.ut.cpp:69: undefined reference to `sf::IpAddress::IpAddress(char const*)'
build/debug/ClientAddress.o: In function `nw::udp::ClientAddress::ClientAddress()':
/home/XXX/Documents/dev/cpp/proj/beep/src/ClientAddress.cpp:21: undefined reference to `sf::IpAddress::IpAddress(char const*)'
build/debug/ClientAddress.o: In function `nw::udp::operator==(nw::udp::ClientAddress const&, nw::udp::ClientAddress const&)':
/home/XXX/Documents/dev/cpp/proj/beep/src/ClientAddress.cpp:33: undefined reference to `sf::operator==(sf::IpAddress const&, sf::IpAddress const&)'
...
and so on ... every mentionings of sf:: inside the files are quoted
I get the same error pattern if I try to compile the other tests (for ClientAddress for example)
Of course i now want to know what i linked wrong how there. As you can see the lib is linked with -lsfml-network. I also checked the SMFL installation, so it is at least less likely a lib file gone missing from standard directory.
I guess there is an error in my usage of g++ , compiling and linking orders or smth.
My project tree:
>bin
----mainexec
--->test
----.ut
>build
--->debug
----.o
--->release
----.o
--->test
----.ut.o
>src
---- .cpp
>include
---- .h
>test
---- .ut.cpp
As a second part of the question, I'd like to ask if there is a better way to build tests, because I simply link every src-obj with my test-obj, even if there are way more src-obj linked than it actually needs. It should work and I do not have to maintain my test dependencies all the time, which later would be very cumbersome. What is common ?
sfml-network has a dependency on sfml-system. Try add -lsfml-system before -lsfml-network in your linker command in your makefile
Related
I am trying to get the Cplex basic LP example to work. The code can be found here. I am completely new with c++, but hope to be able to get this running.
I am trying to compile it on linux. I am using the following command to run it
g++ -D IL_STD -I /opt/ibm/ILOG/CPLEX_Studio1271/opl/include ilolpex1.cpp
The -D IL_STD was put there to solve an error as found here. The -I ... was put there to specify the location of the header files. I came up with this myself after a lot of trying and googling, so i am in no way sure this is correct.
Anyway, i when i run it i get errors of undefined references:
/tmp/ccl9O1YF.o: In function `populatebyrow(IloModel, IloNumVarArray, IloRangeArray)':
ilolpex1.cpp:(.text+0x18f): undefined reference to `IloNumVar::IloNumVar(IloEnv, double, double, IloNumVar::Type, char const*)'
I did not make any changes in the file, so i assume the only thing which can be wrong is how the files are linked. I have the feeling it probably just is a simple setting, but after hours of looking i still have no idea how to fix it.
The easiest way to compile the ilolpex1.cpp example is to use the Makefile that is included with the installation. For example, you should do the following:
$ cd /opt/ibm/ILOG/CPLEX_Studio1271/cplex/examples/x86-64_linux/static_pic
$ make ilolpex1
This will produce output, like the following:
g++ -O0 -c -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include ../../../examples/src/cpp/ilolpex1.cpp -o ilolpex1.o
g++ -O0 -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include -L../../../lib/x86-64_linux/static_pic -L../../../../concert/lib/x86-64_linux/static_pic -o ilolpex1 ilolpex1.o -lconcert -lilocplex -lcplex -lm -lpthread
This will tell you everything you'll need to know if you choose to compile your own application by hand in the future. The details about this are described in the documentation (e.g., here).
Obviously, the iloplex1.cpp file is just a demo how to use IloCplex.
What you yet need is IloCplex itself. This should come either as (a) further source file(s) you have to compile with the demo or as a library you link against.
Have a look at your cplex directories, you might find a lib[...].a file somewhere there, possibly in /opt/ibm/ILOG/CPLEX_Studio1271/opl/lib.
You can link against using GCC's (clang's) -l and -L options. Be aware that when using -l, you leave out lib and .a (-l [...] with above (invalid) sample name).
I'm trying to build some example c++ code that use boost library. I use this as reference example of static linking.
And everything is fine when I build with dynamic libs.
g++ -Wall -std=c++0x -O3 -Wfatal-errors -I/usr/include/boost/include -c -o src/main.o src/main.cpp
g++ -Wall -std=c++0x -O3 -Wfatal-errors -I/usr/include/boost/include -c -o src/ThreadExample.o src/ThreadExample.cpp
g++ -Wall -std=c++0x -O3 -Wfatal-errors -I/usr/include/boost/include -c -o src/Utils.o src/Utils.cpp
g++ src/main.o src/ThreadExample.o src/Utils.o -lboost_thread -lboost_filesystem -lboost_system -lboost_timer -o ThreadExampleBinary
But when I use static libs I get lots of undefined reference errors:
g++ -Wall -std=c++0x -O3 -Wfatal-errors -I/usr/include/boost/include -c -o src/main.o src/main.cpp
g++ -Wall -std=c++0x -O3 -Wfatal-errors -I/usr/include/boost/include -c -o src/ThreadExample.o src/ThreadExample.cpp
g++ -Wall -std=c++0x -O3 -Wfatal-errors -I/usr/include/boost/include -c -o src/Utils.o src/Utils.cpp
g++ -static src/main.o src/ThreadExample.o src/Utils.o -lboost_thread -lboost_filesystem -lboost_system -lboost_timer -o ThreadExampleBinary
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_timer.a(cpu_timer.o): In function `boost::timer::cpu_timer::start()':
(.text+0x7fd): undefined reference to `boost::chrono::steady_clock::now()'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_timer.a(cpu_timer.o): In function `boost::timer::cpu_timer::stop()':
(.text+0x94c): undefined reference to `boost::chrono::steady_clock::now()'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_timer.a(cpu_timer.o): In function `boost::timer::cpu_timer::elapsed() const':
(.text+0xa59): undefined reference to `boost::chrono::steady_clock::now()'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_timer.a(cpu_timer.o): In function `boost::timer::cpu_timer::resume()':
(.text+0xb60): undefined reference to `boost::chrono::steady_clock::now()'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_timer.a(cpu_timer.o): In function `boost::timer::auto_cpu_timer::auto_cpu_timer(std::ostream&, short)':
(.text+0xca5): undefined reference to `boost::chrono::steady_clock::now()'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_timer.a(cpu_timer.o):(.text+0xd4e): more undefined references to `boost::chrono::steady_clock::now()' follow
collect2: error: ld returned 1 exit status
make: *** [ThreadExampleBinary] Error 1
Seems this can be fixed adding additional -lboost_chrono library.
But why it works in dinamic setting?
With static linking, you have to also statically link to any libraries depended on by the libraries you are linking to.
The difference is that shared libraries have an entry in the ELF header, called NEEDED that lists other shared libraries that are to be included when you link in this one.
You can see them with this command:
$ objdump -p /usr/lib/libboost_timer.so | grep NEEDED
NEEDED libboost_chrono.so.1.60.0
NEEDED libboost_system.so.1.60.0
NEEDED librt.so.1
NEEDED libstdc++.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
But for static libraries there is no such system, as they are simply collection of object files.
It is worth noting that the NEEDED entry in the shared objects are entirely optional, and if they are not available, then they will behave exactly like the static ones. But most shared libraries include them.
Many libraries use the pkg-config infrastructure to provide the full command line needed, but AFAIK boost is not one of them.
How to automate this process? Well, you do not. You just include what is needed and follow the linker errors to discover further needs.
You can find which static library includes a symbol with something like:
$ nm --print-file-name --defined-only --demangle /usr/lib/*.a 2> /dev/null | \
grep -q 'boost::chrono::steady_clock::now()'
/usr/lib/libboost_chrono.a:chrono.o:0000000000000090 T boost::chrono::steady_clock::now()
But why it works in dinamic setting?
Most of my make files have the following notes (from when I found the answer back when I needed it ... sorry, I don't know where I found it.)
Note - when a build using '-l' finds the .so version of that library (so - shared object) and the same .a archive is also there, g++ prefers the .so over the .a.
However, you can still achieve static link by fully specifying the path to .a.
Example:
$(CC) $(CC_FLAGS) $< /usr/local/lib/libboost_chrono.a -o $# ...
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sometimes, archive code refers to symbols in yet another archive.
i.e. -lyyy_i686 uses some function from -lxxx_i686, and xxx was listed first in the build command. It is possible that a symbol might remain unresolved and the linker fails.
When this happens, try adding xxx a second time to the end of the archive list
from: -lxxx_i686 -lyyy_i686 -lrt -pthread
becomes -lxxx_i686 -lyyy_i686 -lrt -pthread -lxxx_i686
^^^^^^^^^_____________________________^^^^^^^^^^
The preceeding presumes only .a libraries are findable (no xxx.so)
Another alternative, you can command the linker to search an archive multiple times
-lyyy_i686 -lrt -pthread -(-lxxx_i686-)
tell gcc to link this library as many times as needed __^^__________^^
Again, only .a is findable
Finally, if you choose to link with the .so, note that this does not pull in the entire lib into the current build target. Instead, at runtime, the .so is loaded into memory, if it is not already there. This happens after the program starts. For most applications, this is considered a 'small' start-up performance hit as the program adjusts its memory map (automagically behind the scenes). I believe I once found that the app itself can control when to load the .so.
The use of .so pulls in the entire library to memory (if not already installed). Thus, there would not be any missing symbols, in my xxx vs yyy scenario above, the .so pulls all the symbols, whether used or not.
And once again, when trying to load xxx using "-lxxx_i686", the linker prefers to pull in libxxx_i686.so even when the libxxx_i686.a is in the same directory.
I'm trying to use the JsonCpp library. I'm on Windows, using MinGW and CodeBlocks.
When I include anything from the json headers, my linker implodes and gives out this two errors. I've started to look around and I found these two other questions which basically describe my problem:
problem with g++ and "undefined reference to `__gxx_personality_v0'"
What is __gxx_personality_v0 for?
And if I declare the two missing variables as void pointers, like below, the problem goes away:
void * __gxx_personality_v0=0;
void * _Unwind_Resume =0;
However, I don't understand why this error happens. CodeBlocks is set up so that it uses migw32-g++ for cpp files, and also adding the -lstdc++ option does not fix the problem. Neither does the option -fno-exception ( I want exceptions, mind you, I was just trying ).
I'm also including a boost library in the same file and that does not cause any problems.
EDIT:
The error output is exactly what I said in my title: I get a total of 22 undefined references to _Unwind_Resume and __gxx_personality_v0 during the linking. My code is:
#include <boost/algorithm/string.hpp>
#include <include/json/value.h>
//void * __gxx_personality_v0=0;
//void * _Unwind_Resume =0;
int main () {
std::string str1("Hello world!");
boost::to_upper(str1);
Json::Value k;
return 0;
}
The error is there only when I include/use the JsonCPP library. Uncommenting the commented lines fixes the problem.
The command line output is this:
mingw32-g++.exe -Wall -fexceptions -g -DSFML_DYNAMIC -IC:\Users\Svalorzen\Documents\Projects\boost_1_49 -IC:\Users\Svalorzen\Documents\Projects\jsoncpp-src-0.5.0 -IC:\Users\Svalorzen\Documents\Projects\SFML-1.6\include -IC:\Users\Svalorzen\Documents\Projects\hge181\include -c C:\Users\Svalorzen\Documents\Projects\test\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -LC:\Users\Svalorzen\Documents\Projects\jsoncpp-src-0.5.0 -LC:\Users\Svalorzen\Documents\Projects\SFML-1.6\lib -LC:\Users\Svalorzen\Documents\Projects\hge181\lib -o bin\Debug\test.exe obj\Debug\main.o -fno-exceptions -lsfml-graphics -lsfml-window -lsfml-system C:\Users\Svalorzen\Documents\Projects\jsoncpp-src-0.5.0\libs\mingw\libjson_mingw_libmt.a C:\Users\Svalorzen\Documents\Projects\hge181\lib\gcc\libhge.a C:\Users\Svalorzen\Documents\Projects\hge181\lib\gcc\libhelp.a
Output size is 1.22 MB
Process terminated with status 0 (0 minutes, 3 seconds)
0 errors, 0 warnings
SECOND EDIT:
I'm adding the command lines I use to compile the library:
g++ -o buildscons\mingw\src\lib_json\json_reader.o -c -DWIN32 -DNDEBUG -D_MT -Iinclude src\lib_json\json_reader.cpp
g++ -o buildscons\mingw\src\lib_json\json_value.o -c -DWIN32 -DNDEBUG -D_MT -Iinclude src\lib_json\json_value.cpp
g++ -o buildscons\mingw\src\lib_json\json_writer.o -c -DWIN32 -DNDEBUG -D_MT -Iinclude src\lib_json\json_writer.cpp
ar rc buildscons\mingw\src\lib_json\libjson_mingw_libmt.a buildscons\mingw\src\lib_json\json_reader.o buildscons\mingw\src\lib_json\json_value.o buildscons\mingw\src\lib_json\json_writer.o
ranlib buildscons\mingw\src\lib_json\libjson_mingw_libmt.a
For those coming to this from google (like i did), the real cause of the undefined references to _Unwind_Resume and __gxx_personality_v0 is "using a gcc that uses a different stack unwinding method than dwarf2" [1]
In my case it was attempting to link code compiled with GCC 4.9 upwards with a library compiled with GCC 4.8 or below. The solution is to recompile the library with the same compiler you're building with.
I encountered that same problem attempting to use g++ -g -std=c++17 ... . I removed that option and, once I had removed use of a C++17 feature, it compiled, linked and ran.
I finally fixed this by importing into Code::Blocks the source code of JsonCpp and creating the library myself. I am still baffled though as to why the library created with Scons didn't work, since it was using the same compiler that Code::Blocks uses, but at the same time it was not ( or the error wouldn't have been there ).
This is my first time trying to make a simple library. I worked in Ubuntu 12.04 with g++ 4.6.3. Here is the problem:
[[mylib.cpp]]
#include<sqlite3.h>
void Mylib::blahblah() {...}
void Mylib::evenmoreblah() {...}
...
[[mylib.h]]
#include <...>
class Mylib {
...
};
Then I made the lib by:
gcc -c -Wall -fpic mylib.cpp
gcc -shared -o libmylib.so mylib.o
I used the library in a single test.cpp which contains only the main(). I put libmylib.so in ./libdir, and compiled by using:
g++ -g test.cpp -o test -lpthread -L/usr/local/lib -lsqlite3 -L./libdir -lmylib
The error I got:
./libdir/libmylib.so: undefined reference to `sqlite3_close'
./libdir/libmylib.so: undefined reference to `sqlite3_exec'
./libdir/libmylib.so: undefined reference to `sqlite3_free'
./libdir/libmylib.so: undefined reference to `sqlite3_open'
You could link -lsqlite3 into your shared library with
gcc -shared mylib.o -o libmylib.so -lsqlite3
If you do that, you don't need to explicitly link -lsqlite3 to your program, but that won't harm.
and the order of linking arguments for your program is important:
g++ -Wall -g test.cpp -o mytest \
-L./libdir -lmylib -L/usr/local/lib -lsqlite3 -lpthread
it should go from higher-level libraries to lower-level (i.e. system) ones. And don't forget -Wall to get almost all warnings from the compiler, which is very useful.
Read the Program Library HowTo.
PS. Don't call your program test which is a shell builtin (and the standard /usr/bin/test). Use some other name.
If your library make references to sqlite3, you should link sqlite after linking your library :
g++ -g test.cpp -o test -lpthread -L/usr/local/lib -L./libdir -lmylib -lsqlite3
Otherwise ld won't find anything useful in libsqlite3 before linking your library and won't be able to find the requested symbols after that.
Since your library uses sqlite3, you need to add that AFTER your own library in the linker command. I think you could add it to the linking of your shared library too, but not certain.
The linker resolves libraries and their references in the order you list them, so the order is important.
I have to implement the machine translation system hence I am planning use moses but I facing following error while executing make command on Cygwin:
Administrator#diebold-69b7050 /cygdrive/c/JT/NewSetup/Moses/moses-2010-08-13/moses/scripts/training/memscore$ make
make all-am
make[1]: Entering directory `/cygdrive/c/JT/NewSetup/Moses/moses-2010-08-13/moses
scripts/training/memscore'
g++ -I/usr/include -Wall -ffast-math -ftrapping-math -fomit-frame-pointer -g -O2 -o memscore.exe phrasetable.o memscore.o scorer.o lexdecom.o -lz -lm
phrasetable.o: In function `_ZlsRSoRK15PhraseAlignment':
/cygdrive/c/JT/NewSetup/Moses/moses-2010-08-13/moses/scripts/training/memscore/phrasetable.cpp:111: undefined reference to `boost::system::system_category()'
phrasetable.o: In function `__tcf_0':
/cygdrive/c/JT/NewSetup/Moses/moses-2010-08-13/moses/scripts/training/memscore/datastorage.h:31: undefined reference to `boost::system::system_category()'
phrasetable.o: In function `_ZN14PhrasePairInfo12realloc_dataEj':
/usr/include/boost/pool/simple_segregated_storage.hpp:97: undefined reference to `boost::system::system_category()'
phrasetable.o: In function `_ZNK14PhrasePairInfo14get_alignmentsEv':
Please don't give me suggestion like linker error because I am completely fad up of trying linker option.
I think, I have some Cygwin->Boot library problem. Can you suggest me where I am wrong?
You are mssing -lboost_system on your compilation commands.
Some of the boost libraries are header only. Others need to be compiled. And the libraries sometimes depend on each other. In this case you are using some boost library which needs -lboost_system. Add it so that it gets linked with your project.
and it should be on this line. Where linking is done
g++ -I/usr/include -Wall -ffast-math -ftrapping-math -fomit-frame-pointer -g -O2 -o memscore.exe phrasetable.o memscore.o scorer.o lexdecom.o **-lboost_system** -lz -lm