referência indefinida para boost :: system :: system_category () ao compilar

105

Estou tentando compilar um programa no Ubuntu 11.10 que usa as bibliotecas Boost. Eu tenho as bibliotecas 1.46-dev Boost do repositório do Ubuntu instaladas, mas recebo um erro ao compilar o programa.

undefined reference to boost::system::system_category()

O que é que eu faço de errado?

user1049697
fonte
6
Isso não é um erro do compilador, é um erro do vinculador . Você precisa fazer um link para a biblioteca Boost.System.
ildjarn

Respostas:

160

A biblioteca boost que você está usando depende da biblioteca boost_system. (Nem todos eles fazem.)

Assumindo que você usa gcc, tente adicionar -lboost_systemà linha de comando do compilador para vincular a essa biblioteca.

hc_
fonte
3
Estou usando um Makefile g ++ para a compilação. Onde costumamos colocar essas bandeiras?
user1049697
2
Como a linha de comando do compilador / vinculador é montada varia muito de caso para caso. Por que você não cola seu Makefile (ou as partes relevantes dele) em sua pergunta? Dessa forma, você poderá obter uma resposta que funcione no seu caso específico.
hc_
7
Ok, editei Makefile.am e adicionei -lboost_system , por isso ficou assim: sslsniff_LDFLAGS = -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp -lboost_system. Mas não ajudou ...
user1049697
1
Ainda é o mesmo erro? Você correu autoreconfdepois? Além disso, este post e este podem ajudá-lo com a configuração das ferramentas automáticas.
hc_
2
Troquei sslsniff_LDFLAGScom sslsniff_LDADDno Makefile.am e que não funcionou. Então eu mantive ambos sslsniff_LDFLAGSe acrescentei sslsniff_LDADD = -lboost_system -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp. Então eu fui capaz de compilar. Obrigado pela ajuda!
user1049697
62

Vincular a uma biblioteca que define o símbolo ausente ( -lboost_system) é a solução óbvia, mas no caso particular de Boost.System, uma característica incorreta no design original o torna útil boost::system::generic_category()e boost::system::system_category()desnecessário. Compilar com o sinalizador -DBOOST_SYSTEM_NO_DEPRECATEDdesativa esse código e permite que vários programas sejam compilados sem exigir -lboost_system(esse link, é claro, ainda é necessário se você usar explicitamente alguns dos recursos da biblioteca).

A partir do Boost 1.66 e deste commit , esse comportamento agora é o padrão, então esperamos que cada vez menos usuários precisem desta resposta.

Como notado por @AndrewMarshall, uma alternativa é definir o BOOST_ERROR_CODE_HEADER_ONLYque habilita uma versão apenas de cabeçalho do código. Isso foi desencorajado pelo Boost, pois pode quebrar algumas funcionalidades. No entanto, desde 1.69, apenas o cabeçalho parece ter se tornado o padrão , supostamente tornando esta questão obsoleta.

Marc Glisse
fonte
4
obrigado!!! nada ajudou já que eu uso boost 1.41 (Centos SL) a única coisa que me liberou, foi usar o -DBOOST_SYSTEM_NO_DEPRECATED
Roger Rabbit
5
Na verdade, o que você pode querer é -DBOOST_ERROR_CODE_HEADER_ONLY
Andrew Marshall,
1
Curiosamente, o novo comportamento do Boost 1.66 de ter menos referências a system_category () etc. pode introduzir novos problemas de link na presença de problemas de ordenação de link. Consulte github.com/PointCloudLibrary/pcl/pull/2236 por exemplo
pixelbeat
3
Se você usar o CMake, basta adicionar 'add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)'
nickolay
1
A única solução que funcionou para mim com o Boost 1.68 foi definir BOOST_ERROR_CODE_HEADER_ONLY.
sakra
17

Outra solução alternativa para aqueles que não precisam de toda a coisa: use o switch

-DBOOST_ERROR_CODE_HEADER_ONLY.

Se você usar o CMake, é add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY).

Vadim Berman
fonte
1
Recentemente me deparei com esse problema. Nada funciona, exceto este. Eu me pergunto se isso ainda é desencorajado pelo impulso, conforme mencionado na resposta de Marc Glisse.
John Z. Li
1
quote "Boost.System agora é apenas cabeçalho. Uma biblioteca stub ainda é construída para compatibilidade, mas vincular a ela não é mais necessário."
John Z. Li
16

O erro acima é um erro do vinculador ... o vinculador um programa que pega um ou mais objetos gerados por um compilador e os combina em um único programa executável.

Você deve adicionar -lboost_systemsinalizadores de vinculador que indicam ao vinculador que ele deve procurar por símbolos como boost::system::system_category()na bibliotecalibboost_system.so .

Se você tiver main.cpp:

g++ main.cpp -o main -lboost_system

OU

g++ -c -o main.o main.cpp
g++ main.o -lboost_system
user1055604
fonte
5
o espaço entre -l e o nome da biblioteca está incorreto. você deve usar -lboost_system
portforwardpodcast
1
Eu descobri que centos não se importava com a posição de -l mas o ubuntu sim, tem que estar no final.
perguntou_io
7

Ao usar CMAKE e find_package, certifique-se de que seja:

find_package(Boost COMPONENTS system ...)

e não

find_package(boost COMPONENTS system ...)

Algumas pessoas podem ter perdido horas por isso ...

Kriegalex
fonte
6

Eu tenho o mesmo problema:

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): referência indefinida para `boost :: system :: generic_category ()

A solução foi usar a versão de depuração do lib do sistema:

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

Mas por que?

Volker
fonte
1
Pode ser que em algum lugar foi definido algum sinalizador de depuração, então você tinha outras bibliotecas construídas em debug ou o g ++ estava produzindo o obj de depuração?
noonex
4

Quando tive esse problema, a causa foi o pedido das bibliotecas. Para consertar, coloquei por libboost_systemúltimo:

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

Isso foi no mingw com gcc 5.3 e boost 1.61.0 com um exemplo de timer simples.

Min Zhang
fonte
1
Esse era o meu problema também. Eu o incluí por meio do CMake e, por qualquer motivo, as dependências assumidas e os pedidos foram resolvidos no script FindBoost. Porém, na verdade, meu problema foi sempre usar bibliotecas compartilhadas e nunca prestar atenção, e depois mudar para bibliotecas estáticas e obter erros de compilação. Opa.
Anthony
Isso também corrigiu para mim ... antes dessa solução, a única coisa que funcionava era definir BOOST_ERROR_CODE_HEADER_ONLY. No Ubuntu 18.04, aumente 1,68, com cmake. Minha correção: target_link_libraries (executável pthread ssl crypto boost_system)
Luis,
2

no meu caso, adicionar -lboost_systemnão foi suficiente, ainda não foi possível encontrá-lo em meu ambiente de compilação personalizado. Tive que usar o conselho em Livrar-se de "gcc - / usr / bin / ld: aviso lib não encontrado" e alterar meu ./configurecomando para:

./configure CXXFLAGS="-I$HOME/include" LDFLAGS="-L$HOME/lib -Wl,-rpath-link,$HOME/lib" --with-boost-libdir=$HOME/lib --prefix=$HOME

para obter mais detalhes, consulte Boost 1.51: "erro: não foi possível vincular ao boost_thread!"

jcomeau_ictx
fonte
1

... e caso você queira vincular seu principal estaticamente, em seu Jamfile adicione o seguinte aos requisitos:

<link>static
<library>/boost/system//boost_system

e talvez também:

<linkflags>-static-libgcc
<linkflags>-static-libstdc++
Formiaczek
fonte