Linker undefined references error when cross-compiling

Hello everyone,

I am trying to compile my project for arm using using CMake and a rootfs (Debian 9) using a docker-compose.

The project was compiling fine with OpenCV 3.4.3 cross-compiled also using the OpenCV guide.

I’ve cross-compiled OpenCV version 4.5.1 following the OpenCV guide and added it to my rootfs, all compiles fine, but then the linker throws this error:

Note: cross-builder is the name of the docker container.

cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()@GLIBCXX_3.4.26'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `pthread_cond_clockwait@GLIBC_2.30'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `__cxa_init_primary_exception@CXXABI_1.3.11'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `std::__exception_ptr::exception_ptr::exception_ptr(void*)@CXXABI_1.3.11'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `powf@GLIBC_2.27'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `std::logic_error::logic_error(std::logic_error&&)@GLIBCXX_3.4.26'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `pow@GLIBC_2.29'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `log2f@GLIBC_2.27'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `std::runtime_error::runtime_error(std::runtime_error&&)@GLIBCXX_3.4.26'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `exp@GLIBC_2.29'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `log@GLIBC_2.29'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `fcntl@GLIBC_2.28'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `expf@GLIBC_2.27'
cross-builder    | /rootfs/usr/local/lib/libopencv_world.so.4.5.1: undefined reference to `logf@GLIBC_2.27'

When I configure CMake this is the output:

cross-builder    | -- The C compiler identification is GNU 6.3.0
cross-builder    | -- The CXX compiler identification is GNU 6.3.0
cross-builder    | -- Check for working C compiler: /usr/local/bin/arm-linux-gnueabihf-gcc
cross-builder    | -- Check for working C compiler: /usr/local/bin/arm-linux-gnueabihf-gcc -- works
cross-builder    | -- Detecting C compiler ABI info
cross-builder    | -- Detecting C compiler ABI info - done
cross-builder    | -- Detecting C compile features
cross-builder    | -- Detecting C compile features - done
cross-builder    | -- Check for working CXX compiler: /usr/local/bin/arm-linux-gnueabihf-g++
cross-builder    | -- Check for working CXX compiler: /usr/local/bin/arm-linux-gnueabihf-g++ -- works
cross-builder    | -- Detecting CXX compiler ABI info
cross-builder    | -- Detecting CXX compiler ABI info - done
cross-builder    | -- Detecting CXX compile features
cross-builder    | -- Detecting CXX compile features - done
cross-builder    | -- Found OpenCV: /rootfs/usr/local (found version "4.5.1")
cross-builder    | -- Configuring done
cross-builder    | -- Generating done

So it detects OpenCV and compiles everything fine, but at the moment of the linker it fails.

I’ve searched a lot about the problem, and someone points that the problem can be solved adding -lpthread to the linked libraries in the CMakeLists.txt, but -lpthread is already defined in the target_link_libraries section of CMakeLists.txt.

This is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(ProcessApp VERSION 1.1.0)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_VERBOSE_MAKEFILE ON)

set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)

set(CMAKE_BINARY_DIR ../release)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(QT_MOC_EXECUTABLE /usr/bin/moc)
add_executable(Qt5::moc IMPORTED)
set_property(TARGET Qt5::moc PROPERTY IMPORTED_LOCATION ${QT_MOC_EXECUTABLE})


set(CMAKE_PREFIX_PATH ${ROOTFS}/usr/lib/arm-linux-gnueabihf/cmake/Qt5)
find_package(Qt5 COMPONENTS Xml Qml Network Core REQUIRED)
find_package(OpenCV REQUIRED)

set(CURL_LIBRARY ${ROOTFS}/usr/lib/arm-linux-gnueabihf)
set(CURL_INCLUDE_DIR ${ROOTFS}/usr/include/curl)

add_compile_options(-fvisibility=hidden)
add_compile_definitions(VER="${PROJECT_VERSION}")

add_executable(process)

target_include_directories(process
    PUBLIC
    $ENV{ROOTFS}/usr/include/arm-linux-gnueabihf/
    $ENV{ROOTFS}/usr/include/arm-linux-gnueabihf/qt5
    $ENV{ROOTFS}/usr/include/arm-linux-gnueabihf/qt5/QtCore
    $ENV{ROOTFS}/usr/include/arm-linux-gnueabihf/qt5/QtXml
    $ENV{ROOTFS}/usr/include/arm-linux-gnueabihf/qt5/QtNetwork
    $ENV{ROOTFS}/usr/include/arm-linux-gnueabihf/qt5/QtQml
    $ENV{ROOTFS}/usr/local/include/qhttp
    $ENV{ROOTFS}/usr/local/include/ProcessShared
    ${OpenCV_INCLUDE_DIRS}
    PRIVATE
    ./EmbeddedApplication ./drivers)

target_sources(.... all the cpp/h here...
)

target_link_libraries(process
    -lcurl
    -lrt -lresolv -lpthread
    -lProcessShared
    -lqhttp
    -lQt5Core -lQt5Xml -lQt5Network -lQt5Qml
    -laugeas -lxml2 -lfa
    -lmodbus
    -lquazip5
    ${OpenCV_LIBS}
    )

install(TARGETS process DESTINATION bin)

file(WRITE "${CMAKE_SOURCE_DIR}/QtCreatorDeployment.txt" "release\n")

I am wondering if there could be some incompatibility between newer versions of OpenCV and the compiler/distro that I am using. Could that be possible?

Any help would be appreciated, thank you very much.

Hello, I’ve solved the error.

The error was caused simply because I was cross-compiling using my Ubuntu 20.04 linux as host system, whereas the target system was an armhf Debian 9, so the building was linking to a version of GLIBC that didn’t exist in the rootfs.

I’ve setup a Dockerfile with Debian 9 expecting to compile OpenCV with the correct GLIBC version and worked.

Novice errors I think… But I hope this could help any other novices not getting stucked with this error.

2 Likes