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

如何指定同时适配本地编译与Yocto的CMake头文件包含路径?

问题描述

我开发了一款读取Optris热像仪图像数据的C++应用,基于Optris Direct SDK(.deb包形式)实现设备通信,在Linux开发机上用CMake构建可正常运行——SDK将库文件安装至/usr/lib,头文件安装至/usr/include/libirimager。

但尝试将该应用构建到Nvidia Jetson板的Yocto镜像时,因CMakeLists.txt中使用了头文件的绝对路径,导致编译时无法找到头文件。

最小复现示例

main.cpp

#include "IRImager.h"

int main()
{
    return 0;
}

CMakeLists.txt(本地正常,Yocto构建失败)

cmake_minimum_required(VERSION 3.14)

project(libir-example)

add_executable(libir-example
    main.cpp
)

target_include_directories(libir-example PRIVATE
    /usr/include/libirimager
)

target_link_libraries(libir-example PUBLIC
    irdirectsdk
)

Yocto配方libir-example.bb

DESCRIPTION = "Example of trying to build for libir"
LICENSE = "BSD"

SRCREV = "0.1"
PV = "0.1"
SRC_URI = "file://main.cpp file://CMakeLists.txt"

S = "${WORKDIR}"

DEPENDS += "optris-directsdk"

deltask do_populate_lic

inherit cmake

编译报错

| /home/foo/build/tmp/work/armv8a-oe4t-linux/libir-example/0.1-r0/main.cpp:1:10: fatal error: IRImager.h: No such file or directory
|     1 | #include "IRImager.h"
|       |          ^~~~~~~~~~~~

已确认IRImager.h存在于recipe-sysroot的/usr/include/libirimager目录下,尝试过${CMAKE_SYSROOT}无效,用${CMAKE_BINARY_DIR}相关路径虽能工作,但写法不优雅且无法支持本地编译。

附optris-directsdk_8.8.5.bb配方:

SUMMARY = "Optris DirestSDK"
DESCRIPTION = "SDK for talking to Optris thermal cameras"
HOMEPAGE = "https://www.optris.co.uk/optris-pi-sdks"
LICENSE = "CLOSED"

inherit bin_package

SRC_URI += " \
    https://ftp.evocortex.org/libirimager-latest?arch=arm64&type=deb;subdir=optris-directsdk-8.8.5;downloadfilename=libirimager-8.8.5.deb \
"

SRC_URI[sha256sum] = "97661cd4c258c1dde55938b7d18d7be5fa9a1480e0f0b0bb96268ad62089905f"

# Force the .so files into the regular package (not the -dev one)
FILES:${PN} += "/usr/lib/lib*.so"
FILES:${PN}-dev = ""

RDEPENDS:${PN} = "libudev libusb1"

# Need this because the libraries in the SDK are already stripped, which
# bitbake does not expect

INSANE_SKIP:${PN} = "already-stripped"

# Remove the parts of the SDK that we don't need (e.g. udev rules), otherwise
# bitbake complains about things existing that are not installed.

do_install:append() {
    rm -rf ${D}/lib
    rm -rf ${D}/usr/lib/libirextras.so
}
解决方案

要同时支持本地编译和Yocto构建,需要让CMake自动适配不同环境的头文件路径,推荐两种方案:

方案一:使用CMake的find_path自动查找头文件

修改CMakeLists.txt,用find_path定位IRImager.h的路径,无论是本地环境还是Yocto的sysroot环境,CMake都会自动搜索:

cmake_minimum_required(VERSION 3.14)

project(libir-example)

add_executable(libir-example
    main.cpp
)

# 查找IRImager.h所在的目录,本地默认路径作为备选
find_path(LIBIRIMAGER_INCLUDE_DIR
    NAMES IRImager.h
    PATHS /usr/include/libirimager
)

# 添加头文件目录
target_include_directories(libir-example PRIVATE
    ${LIBIRIMAGER_INCLUDE_DIR}
)

target_link_libraries(libir-example PUBLIC
    irdirectsdk
)

find_path会优先在Yocto构建时的sysroot路径中搜索,找不到再用指定的备选路径,完美兼容两种环境。

方案二:利用Yocto的pkg-config支持(需调整SDK配方)

如果SDK提供了.pc文件,CMake可以用pkg_check_modules直接获取头文件和库路径。但当前optris-directsdk配方没有处理开发文件,需要先修改配方:

调整optris-directsdk_8.8.5.bb

恢复-dev包的内容,确保头文件被正确打包:

# 移除原来的FILES:${PN}-dev = "",替换为:
FILES:${PN}-dev += "/usr/include/libirimager/*"
# 如果SDK有pkg-config文件,还要加上:
# FILES:${PN}-dev += "/usr/lib/pkgconfig/*.pc"

然后修改CMakeLists.txt使用pkg_check_modules:

cmake_minimum_required(VERSION 3.14)

project(libir-example)

find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBIRIMAGER REQUIRED IMPORTED_TARGET irdirectsdk)

add_executable(libir-example
    main.cpp
)

target_link_libraries(libir-example PRIVATE PkgConfig::LIBIRIMAGER)

这种方式更符合CMake的标准实践,Yocto构建时会自动通过pkg-config获取正确的路径,本地编译也能正常工作(只要SDK的.pc文件在系统pkg-config搜索路径中)。

补充说明

方案一无需修改optris-directsdk配方,适合快速适配;方案二需要确保SDK的开发文件(头文件、.pc文件)被正确安装到-dev包中,Yocto构建时会自动依赖optris-directsdk-dev,从而将头文件路径加入构建环境。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:10:00