Patrick
Patrick

Reputation: 1066

C++ undefined reference for libtins library

I installed the libtins package for C++, by building it as described and adding #include <tins/tins.h> to the header of the example file. I ran ldconfig but building always throws a Undefined reference error:

CMakeFiles/lts.dir/main.cpp.o: In function `main':
/home/patrick/ClionProjects/lts/main.cpp:6: undefined reference to `Tins::EthernetII::EthernetII(Tins::HWAddress<6ul, unsigned char> const&, Tins::HWAddress<6ul, unsigned char> const&)'
/home/patrick/ClionProjects/lts/main.cpp:7: undefined reference to `Tins::IPv4Address::IPv4Address(char const*)'
/home/patrick/ClionProjects/lts/main.cpp:7: undefined reference to `Tins::IPv4Address::IPv4Address(char const*)'
/home/patrick/ClionProjects/lts/main.cpp:7: undefined reference to `Tins::IP::IP(Tins::IPv4Address, Tins::IPv4Address)'
/home/patrick/ClionProjects/lts/main.cpp:8: undefined reference to `Tins::TCP::TCP(unsigned short, unsigned short)'
/home/patrick/ClionProjects/lts/main.cpp:10: undefined reference to `Tins::PDU::inner_pdu(Tins::PDU*)'
/home/patrick/ClionProjects/lts/main.cpp:12: undefined reference to `Tins::PDU::inner_pdu(Tins::PDU*)'
CMakeFiles/lts.dir/main.cpp.o: In function `Tins::EthernetII::~EthernetII()':
/usr/local/include/tins/ethernetII.h:46: undefined reference to `vtable for Tins::EthernetII'
/usr/local/include/tins/ethernetII.h:46: undefined reference to `Tins::PDU::~PDU()'
collect2: error: ld returned 1 exit status
make[3]: *** [lts] Error 1

I am using CLion as IDE and the following cmake file:

cmake_minimum_required(VERSION 3.5)
project(lts)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -ltins")

set(SOURCE_FILES main.cpp)

add_executable(lts ${SOURCE_FILES})

Any Idea what could be the problem?

Upvotes: 1

Views: 2072

Answers (4)

Rabeeb Ibrat
Rabeeb Ibrat

Reputation: 1

From the Download page of libtins:

In order to link your application with libtins on GCC or clang, use the -ltins flag

Simply add the following line in your CMake file:

target_link_libraries(PROJECT_NAME -ltins)

Upvotes: 0

Craig Scott
Craig Scott

Reputation: 10137

There's a couple of things to address in your question. First, let CMake find the location of the libtins library for you, then use target_link_libraries() to add it to your lts executable. In the CMake sample in your question, you are specifying library options in the compiler flags variable (CMAKE_CXX_FLAGS). The other thing is to also let CMake handle setting the appropriate compiler flags for C++11 instead of manually adding them to CMAKE_CXX_FLAGS (which would only take care of the compiler part but not the linker). The following should do what you want in a robust, platform independent way:

cmake_minimum_required(VERSION 3.5)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(lts)

find_library(TINS_LIBRARY tins)

set(SOURCE_FILES main.cpp)
add_executable(lts ${SOURCE_FILES})

target_link_libraries(lts "${TINS_LIBRARY}")

I recommend you read the CMake docs for find_library() and target_link_libraries() to understand what those commands do. For the C++11 stuff, I recommend this blog article for a more cohesive explanation than what the CMake docs give you (disclosure: I wrote the article).

Upvotes: 2

Some programmer dude
Some programmer dude

Reputation: 409166

The CMake variable CMAKE_CXX_FLAGS is for the compiler flags, not for libraries.

To add a library you should use target_link_libraries:

target_link_libraries(lts tins)

If you want all targets to link to the same library, you should add it to the list CMAKE_STANDARD_LIBRARIES.


A small tip on debugging these kind of things: Either set CMAKE_VERBOSE_MAKEFILE or use make VERBOSE=1 to inhibit the normal CMake build output, and instead display the normal make output, which will show you all commands make runs, and all flags and options used for each and every program. That way you will be able to see the -ltins flag being passed as a compiler flag, but not as a linker flag or library.

Upvotes: 3

bipll
bipll

Reputation: 11940

The compiler should -ltins. Refer to CMake manual on how to add library dependencies.

Upvotes: 0

Related Questions