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

Yocto-QNX构建时CMake未传递-Wl,-rpath-link问题

问题:Yocto-QNX构建时CMake未传递-Wl,-rpath-link参数导致链接失败

本地Linux构建时,CMake能正常给目标添加-Wl,-rpath-link参数,但在Yocto-QNX(BitBake配方)流水线构建时,生成的构建命令里缺失该参数,链接阶段提示找不到依赖库libcjson.so.1。


CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(app)

include(GNUInstallDirs)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(${PROJECT_NAME}
    src/main.cpp
    src/abc.cpp
)

target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)

# 为安装目标启用RPATH
set(CMAKE_SKIP_INSTALL_RPATH FALSE)  # 不跳过已安装目标的RPATH
set(CMAKE_SKIP_BUILD_RPATH FALSE)  # 不跳过构建目标的RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)  # 避免与${ORIGIN}冲突

# 设置已安装可执行文件的RPATH
set_target_properties(${PROJECT_NAME} PROPERTIES
    INSTALL_RPATH "\${ORIGIN}/../lib"  # 用\转义$以保留原义
)

# 在Yocto中QNX_SYSROOT_LIB_PATH设为${RECIPE_SYSROOT}${libdir}/proj
if(${QNX})
    target_link_directories(${PROJECT_NAME} PRIVATE "${QNX_SYSROOT_LIB_PATH}")
    set_target_properties(${PROJECT_NAME} PROPERTIES
        BUILD_RPATH "${QNX_SYSROOT_LIB_PATH}"
    )
else()
    target_link_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/../../app_client")
endif()

# app_client依赖cjson库
target_link_libraries(${PROJECT_NAME} PRIVATE
    app_client
)

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})

Yocto BitBake配方

SUMMARY = ""
DESCRIPTION = ""

inherit git-utils
inherit pkgconfig cmake
inherit cmake-install
inherit ${@'qnx-includes' if d.getVar('BUILD_PLATFORM') == 'QNX' else ''}

S = "${WORKDIR}/git/proj/app"

APTIV_SRC_URI = "git://github.com/proj;branch=main;protocol=https"
SRCREV_FORMAT = "app"
SRCREV = "${AUTOREV}"

DEPENDS:append = " client-libs"
RDEPENDS:${PN} = " client-libs"

EXTRA_OECMAKE:append = " \
    -DCMAKE_INSTALL_INCLUDEDIR='${RECIPE_SYSROOT}${includedir}' \
    -DCMAKE_INSTALL_LIBDIR='${RECIPE_SYSROOT}${libdir}' \
    -DQNX_SYSROOT_LIB_PATH='${RECIPE_SYSROOT}${libdir}/proj' \
"

do_compile:prepend:qnx() {
    PATH=$PATH:${QNX_HOST}${bindir}
    install -d ${RECIPE_SYSROOT}${libdir}/proj/
    cp ${RECIPE_SYSROOT}${libdir}/libcjson* ${RECIPE_SYSROOT}${libdir}/proj/
    cp ${RECIPE_SYSROOT}${libdir}/libapp_client* ${RECIPE_SYSROOT}${libdir}/proj/
}


FILES:${PN} += " \
    ${bindir}/app \
"

错误信息

2026-02-27T09:27:21 | /opt/qnx800/host/linux/x86_64/usr/bin/aarch64-unknown-nto-qnx8.0.0-ld: warning: libcjson.so.1, needed by /home/sid_sva_mi/poky/build/tmp/work/cortexa57-poky-linux/app/dev_branch/recipe-sysroot/usr/lib/proj///libapp_client.so.1.0, not found (try using -rpath or -rpath-link)


失败时生成的构建命令

&& /opt/qnx800/host/linux/x86_64/usr/bin/q++ -Wc,-isysroot,/opt/qnx800/target/qnx -lang-c++ -Vgcc_ntoaarch64le_cxx  -D_QNX_SOURCE   -Vgcc_ntoaarch64le_cxx  -D_QNX_SOURCE  -O2  CMakeFiles/app.dir/src/main.cpp.o CMakeFiles/app.dir/src/abc.cpp.o -o app -L/home/sid_sva_mi/poky/build/tmp/work/cortexa57-poky-linux/app/dev_branch/recipe-sysroot/usr/lib/proj -lapp_client && :

解决方案

原因分析

Yocto的CMake交叉编译工具链会覆盖部分RPATH相关逻辑,且CMake对QNX链接器的处理与GNU ld不同,导致BUILD_RPATH未被转换为-rpath-link参数。

修复步骤

  1. 直接添加-rpath-link链接选项
    在CMakeLists.txt的QNX分支中,通过target_link_options强制传递参数:

    if(${QNX})
        target_link_directories(${PROJECT_NAME} PRIVATE "${QNX_SYSROOT_LIB_PATH}")
        set_target_properties(${PROJECT_NAME} PROPERTIES
            BUILD_RPATH "${QNX_SYSROOT_LIB_PATH}"
        )
        # 手动添加rpath-link参数
        target_link_options(${PROJECT_NAME} PRIVATE
            "-Wl,-rpath-link,${QNX_SYSROOT_LIB_PATH}"
        )
    else()
        target_link_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/../../app_client")
    endif()
    
  2. 确保QNX变量在Yocto中正确定义
    在BitBake配方的EXTRA_OECMAKE中添加-DQNX=ON:

    EXTRA_OECMAKE:append = " \
        -DCMAKE_INSTALL_INCLUDEDIR='${RECIPE_SYSROOT}${includedir}' \
        -DCMAKE_INSTALL_LIBDIR='${RECIPE_SYSROOT}${libdir}' \
        -DQNX_SYSROOT_LIB_PATH='${RECIPE_SYSROOT}${libdir}/proj' \
        -DQNX=ON \
    "
    
  3. 简化库文件路径(可选)
    无需手动复制库到proj目录,直接添加系统库路径到链接目录:

    if(${QNX})
        target_link_directories(${PROJECT_NAME} PRIVATE 
            "${QNX_SYSROOT_LIB_PATH}"
            "${RECIPE_SYSROOT}${libdir}"
        )
        # 其他设置...
    endif()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 12:13:13