opencv: Undefined reference to __atomic_xxx

System information (version)

OpenCV => 4.1.1 OS => Raspbian Buster (Debian 10)

Detailed description

When compiling OpenCV 4.1.1 on Raspbian, i get various undefined references to __atomic_xxx calls. See #15192. Adding -DOPENCV_EXTRA_EXE_LINKER_FLAGS=-latomic to cmake allows OpenCV to compile and install, but the generated libraries are missing the atomic library reference:

[dev] [mav@maverick-raspberry ~]$ ldd -r /srv/maverick/software/opencv/lib/libopencv_core.so.4.1.1
	linux-vdso.so.1 (0xbec57000)
	/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0xb6c77000)
	libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xb6c41000)
	libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6c17000)
	librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xb6c00000)
	libtbb.so.2 => /srv/maverick/software/tbb/lib/libtbb.so.2 (0xb6bca000)
	libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0xb6b9f000)
	libopenblas.so.0 => /srv/maverick/software/openblas/lib/libopenblas.so.0 (0xb6269000)
	libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0xb6122000)
	libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xb60a0000)
	libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6073000)
	libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb5f25000)
	/lib/ld-linux-armhf.so.3 (0xb6fac000)
	libgfortran.so.5 => /usr/lib/arm-linux-gnueabihf/libgfortran.so.5 (0xb5e4c000)
undefined symbol: __atomic_compare_exchange_8	(/srv/maverick/software/opencv/lib/libopencv_core.so.4.1.1)
undefined symbol: __atomic_fetch_sub_8	(/srv/maverick/software/opencv/lib/libopencv_core.so.4.1.1)
undefined symbol: __atomic_load_8	(/srv/maverick/software/opencv/lib/libopencv_core.so.4.1.1)
undefined symbol: __atomic_store_8	(/srv/maverick/software/opencv/lib/libopencv_core.so.4.1.1)
undefined symbol: __atomic_fetch_add_8	(/srv/maverick/software/opencv/lib/libopencv_core.so.4.1.1)

This means anything compiled against opencv also then has these same undefined errors.

I would expect cmake to detect if atomic library is needed and add it automatically, and it should be linked into the core library, and others where necessary.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 3
  • Comments: 37 (7 by maintainers)

Commits related to this issue

Most upvoted comments

@MKK-a try this workaround:

LD_PRELOAD=<path_to_libatomic.so> python

Thanks @alalek for the workaround, works fine on pi zero w:

pi@piz02:/opt/opencv-4.1.1/bin $ sudo find / -type f -name '*atom*.so*'
/usr/lib/arm-linux-gnueabihf/libatomic.so.1.2.0
pi@piz02:/opt/opencv-4.1.1/bin $ LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1.2.0 python3
Python 3.7.3 (default, Apr  3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> print(cv2.__version__)
4.1.1

Turns out adding -DCMAKE_CXX_FLAGS=-latomic -DOPENCV_EXTRA_EXE_LINKER_FLAGS=-latomic to cmake fixes this. It correctly links atomic lib into the opencv libs, so no further changes necessary to other code that links into opencv. Still I guess opencv should detect if this is necessary and add -latomic where necessary?

Looks to me like this remains an open issue. Compiling opencv-4.x as of 16-Sep-2023 on RaspberryPi 4 32 bit, following instructions for Ubuntu as shown at https://docs.opencv.org/4.x/d7/d9f/tutorial_linux_install.html

 mkdir -p build && cd build
 cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.x/modules ../opencv-4.x
 cmake --build .

the compile dies at about 54% with below message.
uname reports " 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux"

ransac_solvers.cpp:(.text._ZZN2cv4usac6Ransac3runERNS_3PtrINS0_12RansacOutputEEEENKUlRKNS_5RangeEE1_clES8_.isra.0[_ZNSt17_Function_handlerIFvRKN2cv5RangeEEZNS0_4usac6Ransac3runERNS0_3PtrINS5_12RansacOutputEEEEUlS3_E1_E9_M_invokeERKSt9_Any_dataS3_]+0xfdc): undefined reference to `__atomic_load_8'
collect2: error: ld returned 1 exit status
gmake[2]: *** [modules/calib3d/CMakeFiles/opencv_calib3d.dir/build.make:787: lib/libopencv_calib3d.so.4.8.0] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:5990: modules/calib3d/CMakeFiles/opencv_calib3d.dir/all] Error 2
gmake: *** [Makefile:182: all] Error 2

EDIT: The compile appears to be working after the workaround of redoing cmake with the additional flag: -DOPENCV_FORCE_LIBATOMIC_COMPILER_CHECK=1 as described in the issue here: https://github.com/opencv/opencv/pull/24031#issuecomment-1645620490

@msshabunin, thanks for the prompt. It works! I have just taken the latest opencv-master (4.1.2-pre) and added the 15540 patch/delta (raspipi4 buster). I used cmake …, followed by make -j4, and the compile continued to the end without any error. The link.txt checks reveal that latomic has been added. I also noted that the atomic_check.cpp now gives me a HAVE_CXX_ATOMICS_WITH_LIB - Success (HAVE_CXX_ATOMICS_WITHOUT_LIB - Failed). That is a totally different result from before.

In conclusion that has fixed the issue subject to continuing with the install, which I expect to be successful and give me a working opencv without specifying =latomics at the cmake stage… To be thorough I will repeat the compile with the usual cmake options and revert.

Now the big question - how does that little change,i.e. from defining integer variables of standard to very long length, make the big difference to the atomic flag check?

Martin

Hello @alalek yes the “-latomic” flags are in the build commands and it all builds for me.

Here is the edit I have to the OpenCVDetectCXXCompiler.cmake

if((HAVE_CXX11
        AND NOT MSVC
        AND NOT (X86 OR X86_64)
    AND NOT OPENCV_SKIP_LIBATOMIC_COMPILER_CHECK)
    OR OPENCV_FORCE_LIBATOMIC_COMPILER_CHECK
)
  ocv_check_compiler_flag(CXX "" HAVE_CXX_ATOMICS_WITHOUT_LIB "${OpenCV_SOURCE_DIR}/cmake/checks/atomic_check.cpp")
  if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
    list(APPEND CMAKE_REQUIRED_LIBRARIES atomic)
    ocv_check_compiler_flag(CXX "" HAVE_CXX_ATOMICS_WITH_LIB "${OpenCV_SOURCE_DIR}/cmake/checks/atomic_check.cpp")
    if(HAVE_CXX_ATOMICS_WITH_LIB)
      list(APPEND OPENCV_LINKER_LIBS atomic)
    else()
      message(FATAL_ERROR "C++11 compiler must support std::atomic")
    endif()
  endif()
endif()