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++
Related
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 use mingw from here: http://sourceforge.net/projects/mingwbuilds/files/host-windows/releases/4.7.2/32-bit/threads-posix/sjlj/x32-4.7.2-release-posix-sjlj-rev2.7z/download
And I've sucessfully managed to link statically libstdc++-6.dll and libgcc_s_sjlj-1.dll by using -static-libgcc -static-libstdc++ parameters, but I cannot find a command for doing the same with libwinpthread-1.dll.
If your toolchain includes the static winpthreads, adding the option
-static
Will pull in static versions of all libraries it can.
Alternatively, you can remove libwinpthread.dll.a and the DLL itself from the toolchain directories. This might mess up programs linking with libstdc++ and libgcc DLLs though, so be careful.
A third option is to use -Wl,-Bdynamic and -Wl,-Bstatic to select which version you want linked in (which is what -static internally does when ld is called). An example:
gcc -o someexec someobject.o -Wl,-Bdynamic -lsomelibIwantshared -Wl,-Bstatic -lsomelibIwantstatic
If you run your link command with -v added, you should see these options appearing in the ld/collect2 invocation when you use -static-libgcc and -static-libstdc++.
Try this:
-static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic
Notice the -lstdc++ before -lpthread. It worked for me.
Make sure to add this to the very end of your g++ command line.
You should probably check command line options documentation for GCC.
These's no '-static-something' command, only standard libraries (libgcc and libstdc++) can be set to static linking with one command. For other libraries, you first switch to static linking with "-static" and then list the libraries to include with separate commands, ie "-lpthread".
To statically link winpthread even if threading isn't used in the program, pass the -Bstatic and --whole-archive parameters to the linker:
g++ -o hello.exe hello.cpp -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive
Note the following:
The "whole archive" option should be disabled immediately afterwards.
You don't need to do this hack if your program actually uses symbols from the library (i.e. you use <thread> from C++11), in which case the library won't get dropped when you statically link it.
This hack is intended for MinGW-w64, to fix the libwinpthread-1.dll dependencies.
For anyone working in CMake, this solution is readily implemented in your CMakeLists.txt file as follows...
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
Apparently, CMake does some weird stuff with how the -Wl compiler flags are handled, making the -Wl,-Bstatic -lstdc++ -lwinpthread -Wl,-Bdynamic solution not work, with only two other options seemingly left: the bad compiler flag -static and the ugly compiler flag -Wl,--whole-archive.
Meanwhile, the good option that actually works in CMake, yet seems rather undocumented, is to directly use the linker flags. Hence, in CMake, this seems to be the best way to statically link to all the mingw-w64 C++ dependencies:
target_link_libraries (MyVeryAwesomeApp -static gcc stdc++ winpthread -dynamic)
It should be noted that even if there isn't a library explicitly following -dynamic, it should still be applied in order to ensure that the standard, implicitly linked libraries get linked correctly.
I circumvented this problem by using win32 variant of the mingw toolchain instead of the posix variant. With the win32 variant, -static-libgcc -static-libstdc++ is sufficient for an independent build.
If you are using toolchains from MSys2 (tested with gcc version 12) ,the only way to use winpthread statically is standard -static (forces all library to be static) or simply delete/rename the libwinpthread.dll.a && libpthread.dll.a imp libs.
Other methods like "Bstatic", "-l:libwinpthread.a" will no longer work (due to dependency hell, especially in CMake). The one with whole archive still works but it overrides the program properties.
You may also want static link libgcc and libstdc++ if the dependency comes from them.
Just link with -l:libwinpthread.a
Just add -static to your CFLAGS.
For example: ./configure CFLAGS="-static".
This will link all static libraries to your executable file.
I am trying to build some code that uses the EVP_* functions in Ubuntu, however when I build, I get the dreaded "undefined reference" errors.
I am using Ubuntu 11.10.
The following line is how I compile:
g++ -lcrypto -lssl *.cpp -o IOService
[...]
crypto.cpp:(.text+0x8): undefined reference to `EVP_md5'
[...]
The cpp files include openssl/evp.h.
I have installed the libssl1.0.0-dbg package, but those libraries get installed in /usr/lib/debug/lib/i386-linux-gnu/ where my linker doesn't seem to find them. I tried softlinking and copying the .so files, to no avail (and I have the feeling this is not the way to go).
ld is a one-pass linker, meaning that you have to add libraries after the object files that use them: g++ *.cpp -o IOService -lcrypto (I think libssl is not needed if all you need is md5)
I'm trying to build some code. Here is the error I'm getting:
main.o: In function `__static_initialization_and_destruction_0':
/home/jmbeck/Downloads/boost_1_48_0/boost/system/error_code.hpp:214: undefined reference to `boost::system::generic_category()'
There is more, but I don't think it's relevant.
Here is the build command:
g++ -I/home/jmbeck/Downloads/boost_1_48_0
-L/home/jmbeck/Downloads/boost_1_48_0/stage/lib
-lm
-lboost_system
-lboost_thread
-lboost_regex
main.cpp
The /home/jmbeck/Downloads/boost_1_48_0/stage/lib directory contains the expected files:
libboost_system.a
libboost_system.so#
libboost_system.so.1.48.0*
libboost_thread.a
libboost_thread.so#
libboost_thread.so.1.48.0*
libboost_regex.a
libboost_regex.so#
libboost_regex.so.1.48.0*
... etc...
I've tried building a quick program that didn't use the pre-compiled libraries, and it compiled just fine. It finds the appropriate headers, but not the libraries.
What am I doing wrong?
Try putting the libraries after main.cpp.
I've experienced some weirdness in the past when GCC ignores libraries because it doesn't think they're used, before reaching my source files.
Often linkers require that libraries be ordered as most dependent to least dependent (I believe MS does not). In this case probably thread or regex depends on system, so you'd need to list the -lsystem after the other boost library that depends on it.
I have this assignment due that requires the usage of FLTK. The code is given to us and it should compile straight off of the bat, but I am having linking errors and do not know which other libraries I need to include.
I currently have "opengl32", "fltk_gl", "glu32", and "fltk" included (-l), each of which seem to reduce the number of errors. I compiled FLTK using make with no specified options. Including all of the produced library files doesn't fix the problem, and I'm convinced that it's just some Windows specific problem.
Compile log:
**** Build of configuration Debug for project CG5 ****
make all
Building target: CG5.exe
Invoking: Cygwin C++ Linker
g++ -o"CG5.exe" ./src/draw_routines.o ./src/gl_window.o ./src/my_shapes.o ./src/shape.o ./src/shapes_ui.o ./src/tesselation.o -lopengl32 -lfltk_z -lfltk_gl -lglu32 -lfltk
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libfltk_gl.a(Fl_Gl_Window.o):Fl_Gl_Window.cxx:(.text+0x197): undefined reference to `_SelectPalette#12'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libfltk_gl.a(Fl_Gl_Window.o):Fl_Gl_Window.cxx:(.text+0x1a7): undefined reference to `_RealizePalette#4'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libfltk_gl.a(Fl_Gl_Window.o):Fl_Gl_Window.cxx:(.text+0x1fe): undefined reference to `_glDrawBuffer#4'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libfltk_gl.a(Fl_Gl_Window.o):Fl_Gl_Window.cxx:(.text+0x20d): undefined reference to `_glReadBuffer#4'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libfltk_gl.a(Fl_Gl_Window.o):Fl_Gl_Window.cxx:(.text+0x23a): undefined reference to `_glGetIntegerv#8'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libfltk_gl.a(Fl_Gl_Window.o):Fl_Gl_Window.cxx:(.text+0x2c3): undefined reference to `_glOrtho#48'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libfltk_gl.a(Fl_Gl_Window.o):Fl_Gl_Window.cxx:(.text+0x2f3): undefined reference to `_SwapBuffers#4'
...and lots more
Thanks a ton for the help.
EDIT: These first few lines are obviously OpenGL related, although I'm still not sure what additional libraries need to be included.
Just a guess: your makefile was written for Linux, and on Cygwin some libraries are either missing or in a different place. You're going to have to examine the makefile, locate the missing libraries, and either move the libs to where the makefile expects them or change the makefile to look in the right place.
The libraries it needs are listed on the line starting g++ (prepend 'lib' to the names after the -l flags)
Sorry for the lack of closure, but I just booted into my Linux netbook and got it working.
-lfltk -lfltk_gl -lGLU -lGL -lXext -lX11 -lm