Using asio but link error in pthread

asked 2020-02-03 22:39:05 -0600

frpunzalan gravatar image

updated 2020-02-05 00:31:33 -0600

Hi guys,

I am trying to compile a simple UDP server in ROS 2. I am using the async library ASIO as stand-alone. It's a header only library so I don't need to link to it. I tried to compile the code but I got the following link errors for pthread

--- stderr: oam_api                                                                          
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
CMakeFiles/udp_server_main.dir/src/udp_server_main.cpp.o: In function `asio::detail::posix_event::posix_event()':
udp_server_main.cpp:(.text._ZN4asio6detail11posix_eventC2Ev[_ZN4asio6detail11posix_eventC5Ev]+0x4d): undefined reference to `pthread_condattr_setclock'
CMakeFiles/udp_server_main.dir/src/udp_server_main.cpp.o: In function `asio::detail::posix_thread::~posix_thread()':
udp_server_main.cpp:(.text._ZN4asio6detail12posix_threadD2Ev[_ZN4asio6detail12posix_threadD5Ev]+0x26): undefined reference to `pthread_detach'
CMakeFiles/udp_server_main.dir/src/udp_server_main.cpp.o: In function `asio::detail::posix_thread::join()':
udp_server_main.cpp:(.text._ZN4asio6detail12posix_thread4joinEv[_ZN4asio6detail12posix_thread4joinEv]+0x2b): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
make[2]: *** [udp_server_main] Error 1
make[1]: *** [CMakeFiles/udp_server_main.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [all] Error 2

I am not sure what is the problem since I added the -pthread option to the compiler flags. Here are the CMakeLists.txt and package.xml file:

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(oam_api)

# Default to C99
if(NOT CMAKE_C_STANDARD)
    set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
    set(CMAKE_CXX_STANDARD 14)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# for compiling asio
add_compile_options(-DASIO_STANDALONE -pthread)

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)

include_directories(include)

set(CONFIGURATOR_LIB_SRC
    src/oam_api.cpp
)

add_library(${PROJECT_NAME} SHARED
    ${CONFIGURATOR_LIB_SRC}
)


add_executable(udp_server_main src/udp_server_main.cpp)
target_include_directories(udp_server_main PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

install(TARGETS udp_server_main
    EXPORT export_${PROJECT_NAME}
    DESTINATION lib/${PROJECT_NAME})

if(BUILD_TESTING)
    find_package(ament_lint_auto REQUIRED)
    find_package(ament_cmake_gtest REQUIRED)

    # exclude some default linters from ament_lint
    list(APPEND AMENT_LINT_AUTO_EXCLUDE
        ament_cmake_uncrustify
    )
    list(APPEND AMENT_LINT_AUTO_EXCLUDE
        ament_cmake_copyright
    )
    ament_lint_auto_find_test_dependencies()

    # Add a gtest executables
    ament_add_gtest(${PROJECT_NAME}-test
        test/test_oam_api.cpp
    )
    target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})

endif()    # BUILD_TESTING

ament_package()

The package.xml file

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
    <name>oam_api</name>
    <version>0.0.0</version>
    <description>TODO: Package description</description>
    <maintainer email="root@todo.todo">root</maintainer>
    <license>TODO: License declaration</license>

    <buildtool_depend>ament_cmake_auto</buildtool_depend>
    <depend>rclcpp</depend>

    <test_depend>ament_cmake</test_depend>
    <test_depend>ament_cmake_gtest</test_depend>
    <test_depend>rclcpp</test_depend>
    <test_depend>ament_lint_auto</test_depend>
    <test_depend>ament_lint_common</test_depend>

    <export>
        <build_type>ament_cmake</build_type>
    </export>
</package>

Edit

I found the reason for the

undefined reference to `main'

error. I put the main() function inside a namespace so there was no global main. newbie mistake

edit retag flag offensive close merge delete

Comments

undefined reference to `main'

ignoring all the rest: you don't seem to be including any object file which contains a main(..) function.

That would be something to fix as well.

And:

# for compiling asio
add_compile_options(-DASIO_STANDALONE -pthread)

please don't abuse add_compile_options(..) to link to additional libraries. That's really not very nice.

If you really must add pthread, use FindThreads.

You also don't appear to find_package(..) Asio anywhere. You may not need to link against it, but you should certainly make sure the system you're attempting to build your source code on actually has it installed and add its location to the include path.

gvdhoorn gravatar imagegvdhoorn ( 2020-02-04 04:31:57 -0600 )edit

@gvdhoorn

Thanks for the reply. Would I still need to add the find_package(..) part even if the Asio library is all-header? I already included the asio library in the include directories so I guess it will find it there.

Am i overusing the add_compile_options(..)? Sorry, didn't know. What do you suggest I do instead?

For the main() part. I have a main() function in the src/udp_server_main.cpp file so I am not sure what is causing the undefined main error.

frpunzalan gravatar imagefrpunzalan ( 2020-02-04 20:32:15 -0600 )edit

I got the error for undefined reference to 'main'.

I put the main function inside a namespace declaration. sorry, newbie mistake

frpunzalan gravatar imagefrpunzalan ( 2020-02-05 00:28:30 -0600 )edit

This is really more of a generic CMake question than a ROS one, but:

  • re: asio header-only: true, but you still need to find_package(..) it. Search for "cmake header only" and you'll find a ton of references
  • re: add_compile_options(..): just don't use it at all for this. Use FindThreads, as I linked above
gvdhoorn gravatar imagegvdhoorn ( 2020-02-05 02:29:25 -0600 )edit