You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Yocto配方中std::atomic相关的链接器错误

问题:Yocto构建含std::atomic的源码包时链接器错误

初始错误现象

构建时出现链接器未定义引用错误,具体日志:

/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/bar/git-r0/recipe-sysroot-native/usr/bin/x86_64-poky-linux/../../libexec/x86_64-poky-linux/gcc/x86_64-poky-linux/11.2.0/ld: src/CMakeFiles/FooImpl.dir/xxx.cpp.o: in function `std::atomic<xxx_handle>::load(std::memory_order) const':
/usr/include/c++/11.2.0/atomic:285: undefined reference to `__atomic_load_16'
/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/bar/git-r0/recipe-sysroot-native/usr/bin/x86_64-poky-linux/../../libexec/x86_64-poky-linux/gcc/x86_64-poky-linux/11.2.0/ld: src/CMakeFiles/FooImpl.dir/xxx.cpp.o: in function `std::atomic<xxx_handle>::store(xxx_handle, std::memory_order)':
/usr/include/c++/11.2.0/atomic:271: undefined reference to `__atomic_store_16'
/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/bar/git-r0/recipe-sysroot-native/usr/bin/x86_64-poky-linux/../../libexec/x86_64-poky-linux/gcc/x86_64-poky-linux/11.2.0/ld: /usr/include/c++/11.2.0/atomic:271: undefined reference to `__atomic_store_16'
/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/bar/git-r0/recipe-sysroot-native/usr/bin/x86_64-poky-linux/../../libexec/x86_64-poky-linux/gcc/x86_64-poky-linux/11.2.0/ld: /usr/include/c++/11.2.0/atomic:271: undefined reference to `__atomic_store_16'
/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/bar/git-r0/recipe-sysroot-native/usr/bin/x86_64-poky-linux/../../libexec/x86_64-poky-linux/gcc/x86_64-poky-linux/11.2.0/ld: src/CMakeFiles/FooImpl.dir/xxx.cpp.o: in function `std::atomic<xxx_handle>::load(std::memory_order) const':
/usr/include/c++/11.2.0/atomic:285: undefined reference to `__atomic_load_16'

尝试的配方修改

查阅资料得知需添加-latomic链接参数,于是修改Yocto配方:

SUMMARY = "FooImpl"
DESCRIPTION = "FooImpl Recipe"
LICENSE = "CLOSED"

DEPENDS = "fooInterface googletest framework"

SRC_URI = "git://FooImpl;protocol=ssh;branch=mainline;"
SRCREV = "yyyy"

S = "${WORKDIR}/git"

inherit cmake

TARGET_LDFLAGS += " -latomic "
LDFLAGS += " -latomic "
TARGET_CFLAGS += " -march=native "
CFLAGS += " -march=native "

后续更新信息

  1. 构建日志显示-latomic和-march=native参数已被传递,但链接错误仍存在:
[buildfarm-ssh] l/git-r0=/usr/src/debug/fooimpl/git-r0                      -fdebug-prefix-map=/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/fooimpl/git-r0/recipe-sysroot=                      -fdebug-prefix-map=/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/fooimpl/git-r0/recipe-sysroot-native=   -latomic  -Wl,-z,relro,-z,now  -latomic  -Wl,-zdefs -Wl,-zrelro -Wl,-znow -Wl,--whole-archive,/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/fooimpl/git-r0/fooimpl-git/src/libFooInterface.a,--no-whole-archive -T/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/fooimpl/git-r0/recipe-sysroot/usr/share/ff/ff.ld -shared -Wl,-soname,libFooImpl.so -o src/libFooImpl.so src/CMakeFiles/FooImpl.dir/xxx.cpp.o src/CMakeFiles/FooImpl.dir/discovery_ipc.cpp.o  -Wl,-rpath,"\$APMF-/opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/fooimpl/git-r0/fooimpl-git/_ff_components:"  src/libFooInterface.a  /opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/fooimpl/git-r0/recipe-sysroot/usr/lib/libip.so.0.1.0  /opt/workspace/foo/build-sim-debug/tmp/work/core2-64-poky-linux/fooimpl/git-r0/recipe-sysroot/usr/lib/libff.so && :
FAILED: src/libFooImpl.so 
  1. 直接在源码的CMakeLists.txt中给target_link_libraries添加atomic即可正常构建,但希望通过Yocto配方实现该修改,避免改动源码。
  2. 源码中FooImpl/src/CMakeLists.txt的关键内容:
set(lib FooImpl)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 17)

find_package(xxx CONFIG REQUIRED)


add_library(${lib} SHARED
  yyy.cpp
  zzz.cpp
)

target_include_directories(${lib} PUBLIC ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(${lib} PUBLIC FooInterface xxx) # 添加atomic此处可正常构建

解决方案

方法1:通过EXTRA_OECMAKE传递CMake链接器参数

在Yocto配方中,删除原来的TARGET_LDFLAGS和LDFLAGS设置,改用EXTRA_OECMAKE向CMake传递链接参数:

inherit cmake

EXTRA_OECMAKE += " -DCMAKE_SHARED_LINKER_FLAGS='${CMAKE_SHARED_LINKER_FLAGS} -latomic' "
TARGET_CFLAGS += " -march=native "
CFLAGS += " -march=native "

原理:CMake在生成共享库的链接命令时,会优先使用CMAKE_SHARED_LINKER_FLAGS中的参数,并且会将其放在正确的链接顺序位置,确保-latomic能正确解析依赖的符号。

方法2:通过配方修改CMakeLists.txt(备选方案)

如果无法通过CMake变量解决,可以在配方中添加预配置步骤,自动修改源码的CMakeLists.txt:

do_configure_prepend() {
    sed -i 's/target_link_libraries(${lib} PUBLIC FooInterface xxx)/target_link_libraries(${lib} PUBLIC FooInterface xxx atomic)/' ${S}/src/CMakeLists.txt
}

原理:在配置阶段开始前,通过sed命令修改源码中的target_link_libraries行,添加atomic库依赖,效果和手动修改一致。

为什么直接设置LDFLAGS无效?

链接库的顺序对链接器至关重要,依赖库需要放在引用它的目标文件之后。直接在配方中设置LDFLAGS会让-latomic被放在链接命令的前面,而CMake生成的链接命令中,目标文件和依赖库在后面,导致链接器无法找到__atomic_load_16等符号。而通过CMake的target_link_libraries或CMAKE_SHARED_LINKER_FLAGS设置,能保证-latomic出现在正确的位置,从而解决未定义引用问题。

内容的提问来源于stack exchange,提问作者bourne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:59:55