118

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?

user1049697
  • 2,479
  • 4
  • 29
  • 36
  • 6
    That's not a compiler error, it's a _linker_ error. You need to link to the Boost.System library. – ildjarn Mar 15 '12 at 16:19

9 Answers9

169

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.

hc_
  • 2,628
  • 1
  • 18
  • 19
  • 3
    I am using a g++ Makefile for the compilation. Where does one usually put such flags? – user1049697 Mar 15 '12 at 17:09
  • 2
    How the compiler/linker command line is assembled varies greatly from case to case. Why don't you paste your Makefile (or the relevant parts of it) into your question? That way, you could get an answer that works in your specific case. – hc_ Mar 15 '12 at 17:15
  • That Makefile is automatically generated by automake. So what you actually want to do is change your Makefile.am or configure.ac. – hc_ Mar 15 '12 at 17:35
  • 7
    Ok, I edited Makefile.am and added `-lboost_system`, so it looked like this: `sslsniff_LDFLAGS = -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp -lboost_system`. It didn't help though... – user1049697 Mar 15 '12 at 17:54
  • 1
    Still the same error? Did you run `autoreconf` afterwards? Also, [this post](http://stackoverflow.com/q/2270073/1269546) and [this one](http://stackoverflow.com/q/2057472/1269546) might help you with your autotools configuration. – hc_ Mar 15 '12 at 18:00
  • 2
    I replaced `sslsniff_LDFLAGS` with `sslsniff_LDADD` in Makefile.am and that did NOT work. Then I kept both `sslsniff_LDFLAGS` and added `sslsniff_LDADD = -lboost_system -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp`. Then I was able to compile. Thank you for the help! – user1049697 Mar 16 '12 at 16:06
  • This advice doesn't help me on cygwin. – Stepan Yakovenko Aug 12 '17 at 15:40
  • my target file had to first then the libraries – Adam Sep 22 '19 at 15:58
  • On some systems libboost_system needs to be installed separately. eg Raspbian `apt install libboost1.67-dev` only gets the header files; the .so files are in separate packages eg `apt install libboost-system1.67` (no need for the -dev suffix in that one as this is just for linking purposes) – Rodney Jul 03 '23 at 08:28
77

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.

Marc Glisse
  • 7,550
  • 2
  • 30
  • 53
  • 4
    thanks!!! nothing helped since I use boost 1.41 (Centos SL) the only thing that freed me, is using the -DBOOST_SYSTEM_NO_DEPRECATED – Roger Rabbit Jul 19 '15 at 07:25
  • 6
    Actually what you may want is -DBOOST_ERROR_CODE_HEADER_ONLY – Andrew Marshall Sep 09 '17 at 20:25
  • @Andrew it depends, but indeed both should work here. Whether BOOST_ERROR_CODE_HEADER_ONLY or BOOST_SYSTEM_NO_DEPRECATED is preferable depends on each use case. – Marc Glisse Sep 10 '17 at 17:08
  • 3
    Interestingly the new Boost 1.66 behavior of havinging _less_ references to system_category() etc. may introduce _new_ link issues in the presence of link ordering issues. See https://github.com/PointCloudLibrary/pcl/pull/2236 for example – pixelbeat Mar 01 '18 at 06:19
  • @pixelbeat Arguably that's a bug in boost or in the cmake module for boost, it should handle dependencies automatically. But yes, any fix can uncover latent issues :-( – Marc Glisse Mar 01 '18 at 10:45
  • 3
    If you use CMake just add 'add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)' – nickolay Jun 08 '18 at 20:24
  • 2
    The only fixed that worked for me with Boost 1.68 was to define `BOOST_ERROR_CODE_HEADER_ONLY`. – sakra Aug 23 '18 at 14:13
  • @sakra If `-lboost_system` fails, you are using it wrong. This answer was specifically about programs that do not use Boost.System, but where a bug still required linking with the library. Most likely you are actually using Boost.System (or a library that uses it). If that is not the case, I encourage you to post a new question with a testcase (or possibly report the issue to boost). – Marc Glisse Aug 23 '18 at 15:02
  • Linking boost_system last fixed the issue for me. Using boost 1.68 with cmake on Ubuntu 18.04. – Luis Sep 09 '18 at 06:32
  • @AndrewMarshall - I'm having a similar problem on MacOS with boost 1.70.0.. Are you saying that the compiled boost dynamic libraries libboost_system and libboost_filesystem must be recompiled with BOOST_ERROR_CODE_HEADER_ONLY or BOOST_SYSTEM_NO_DEPRECATED, or that the code that includes boost headers needs to be compiled with one of those defined? – SMGreenfield Aug 06 '19 at 05:16
  • @SMGreenfield Your code should define these before including the boost headers, either in an include file or (my personal preference) as part of your build system (eg CMake `target_compile_definitions`). – Andrew Marshall Aug 06 '19 at 13:42
28

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).

Vadim Berman
  • 1,932
  • 1
  • 20
  • 39
  • 2
    I recently came across this problem. Nothing works except this one. I wonder if this is still discouraged by boost as mentioned in Marc Glisse's answer. – John Z. Li Jan 22 '19 at 08:56
  • 2
    quote "Boost.System is now header-only. A stub library is still built for compatibility, but linking to it is no longer necessary." – John Z. Li Jan 22 '19 at 09:09
17

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
Adam Głowacki
  • 127
  • 1
  • 10
user1055604
  • 1,624
  • 11
  • 28
8

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 ...

Kriegalex
  • 423
  • 6
  • 17
6

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?

Tony Rad
  • 2,479
  • 20
  • 32
volker
  • 61
  • 1
  • 1
  • 1
    Can it be that somewhere was defined some debug flag, so you had other libs built in debug or g++ was producing debug obj ? – noonex Mar 23 '15 at 06:43
4

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.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Min Zhang
  • 41
  • 1
  • 1
    This was my problem too. I included it via CMake and, for whatever reason, assumed dependencies and ordering were worked out in the FindBoost script. Really, though, my problem was always using shared libraries and never paying attention, then moving to static libraries and getting build errors. Oops. – Anthony Mar 14 '18 at 15:07
  • This fixed it for me as well... previous to this solution the only thing that worked was defining BOOST_ERROR_CODE_HEADER_ONLY. On Ubuntu 18.04, boost 1.68, with cmake. My fix: target_link_libraries(executable pthread ssl crypto boost_system) – Luis Sep 09 '18 at 06:30
2

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 !"

Community
  • 1
  • 1
jcomeau_ictx
  • 37,688
  • 6
  • 92
  • 107
1

...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++
formiaczek
  • 385
  • 3
  • 7