119

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?

1
  • 6
    That's not a compiler error, it's a linker error. You need to link to the Boost.System library.
    – ildjarn
    Commented Mar 15, 2012 at 16:19

9 Answers 9

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.

9
  • 3
    I am using a g++ Makefile for the compilation. Where does one usually put such flags? Commented Mar 15, 2012 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_
    Commented Mar 15, 2012 at 17:15
  • 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... Commented Mar 15, 2012 at 17:54
  • 1
    Still the same error? Did you run autoreconf afterwards? Also, this post and this one might help you with your autotools configuration.
    – hc_
    Commented Mar 15, 2012 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! Commented Mar 16, 2012 at 16:06
76

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.

11
  • 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 Commented Jul 19, 2015 at 7:25
  • 6
    Actually what you may want is -DBOOST_ERROR_CODE_HEADER_ONLY Commented Sep 9, 2017 at 20:25
  • 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 github.com/PointCloudLibrary/pcl/pull/2236 for example
    – pixelbeat
    Commented Mar 1, 2018 at 6:19
  • 3
    If you use CMake just add 'add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)'
    – nickolay
    Commented Jun 8, 2018 at 20:24
  • 2
    The only fixed that worked for me with Boost 1.68 was to define BOOST_ERROR_CODE_HEADER_ONLY.
    – sakra
    Commented Aug 23, 2018 at 14:13
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).

2
  • 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
    Commented Jan 22, 2019 at 8: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
    Commented Jan 22, 2019 at 9: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
2
  • 5
    the space between -l and the library name is incorrect. you should use -lboost_system
    – benathon
    Commented Aug 24, 2013 at 21:45
  • 1
    I found that centos didnt care about the position of -l but ubuntu did, has to be at the end. Commented Jan 3, 2015 at 4:00
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 ...

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?

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
    Commented Mar 23, 2015 at 6: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.

2
  • 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
    Commented Mar 14, 2018 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
    Commented Sep 9, 2018 at 6: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 !"

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.