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()':
CMakeFiles/udp_server_main.dir/src/udp_server_main.cpp.o: In function asio::detail::posix_thread::~posix_thread()':
CMakeFiles/udp_server_main.dir/src/udp_server_main.cpp.o: In function asio::detail::posix_thread::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")
endif()

# for compiling asio

# 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}
)

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"?>
<package format="3">
<name>oam_api</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="root@todo.todo">root</maintainer>

<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 close merge delete

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


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

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.

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

( 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

( 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
( 2020-02-05 02:29:25 -0600 )edit