CMake交叉编译树莓派时/usr/include未用于查找fftw3.h问题
刚接触CMake交叉编译踩这种坑太正常了,我来帮你捋捋可能的原因和解决办法:
核心问题:交叉编译模式下CMake会屏蔽主机系统路径
你现在是做树莓派的交叉编译,CMake会切换到目标架构(ARM)的sysroot环境下工作,不会默认使用主机(x86)的/usr/include目录——毕竟主机的头文件是给x86程序用的,直接拿来编译ARM程序会导致兼容性问题,所以CMake在交叉编译模式下会自动忽略主机系统的默认路径,这就是你明明显式加了路径却没用的关键原因。
具体解决步骤
检查交叉编译工具链配置
先确认你的工具链文件(比如raspi-toolchain.cmake)里是否设置了CMAKE_SYSROOT,这个路径应该指向树莓派系统镜像的根目录,或者交叉编译工具链自带的sysroot文件夹。真正需要的fftw3.h应该放在这个sysroot下的usr/include里,而不是主机的/usr/include。
如果你的fftw3是在主机上安装的x86版本,那它完全不适合树莓派,你需要先交叉编译fftw3库,把编译好的ARM版本头文件和库放到交叉编译工具链的sysroot中,或者单独指定一个存放交叉编译库的路径。调整find_path的搜索逻辑
如果你已经准备好交叉编译后的fftw3,让find_path去目标sysroot里找头文件,而不是主机路径:find_path(FFTW_FOLDER NAMES fftw3.h PATHS ${CMAKE_SYSROOT}/usr/include NO_DEFAULT_PATH)或者可以全局设置
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE为ONLY,强制CMake的查找指令只在sysroot和你指定的路径中搜索:set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)修正target_include_directories的路径
你之前显式添加的如果是主机的/usr/include,交叉编译时CMake会直接忽略它。应该替换成交叉编译环境下的有效路径,比如:# 如果fftw3在sysroot里 target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_SYSROOT}/usr/include) # 或者如果是自己交叉编译后单独存放的路径 target_include_directories(${LIB_NAME} PUBLIC /path/to/cross-compiled-fftw/include)验证实际搜索路径
可以在CMakeLists中添加调试输出,看看CMake实际的include路径:message(STATUS "Current include paths: ${CMAKE_INCLUDE_PATH}")或者在运行CMake时加上
-DCMAKE_VERBOSE_MAKEFILE=ON参数,查看编译阶段实际使用的头文件搜索路径,这样能更直观地定位问题。
总结
交叉编译和本地编译的核心区别就是CMake会切换到目标架构的专属环境,主机的系统路径在这个模式下是无效的。先搞定交叉编译工具链的sysroot配置,再确保fftw3是针对ARM架构编译的,最后调整CMake指令指向正确的目标路径,问题就能解决了。
内容的提问来源于stack exchange,提问作者Damien

