使用 cmake 的 raspberry pi 的 C 交叉编译无法找到 header 文件

C cross compile for raspberry pi with cmake fails to find header file

我正在尝试移植一个 运行 在 x86 体系结构中很好的程序(Linux Mint 17.1) to a Raspberry Pi (Raspbian Jessie Lite). I'm using CMake, so I just followed the nice guide in Crafty Bytes

我的 toolchain-raspberrypi.cmake 看起来像这样:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

# Specify the cross compiler
SET(CMAKE_C_COMPILER $ENV{HOME}/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc)

#SET(CMAKE_C_FLAGS "-L$ENV{HOME}/rpi/rootfs/usr/lib/arm-linux-gnueabihf -I$ENV{HOME}$ENV{HOME}/rpi/rootfs/usr/include")

# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/rpi/rootfs)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")

# Search for programs only in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# Search for libraries and headers only in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

CMake 生成 Makefile 并且似乎找到了所有需要的库:

$ cmake -D CMAKE_BUILD_TYPE=Debug -D CMAKE_TOOLCHAIN_FILE=/home/unknown/rpi/toolchain-raspberrypi.cmake ..
-- The C compiler identification is GNU 4.8.3
-- Check for working C compiler: /home/unknown/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc
-- Check for working C compiler: /home/unknown/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Looking for include file stdlib.h
-- Looking for include file stdlib.h - found
-- Looking for sys/types.h
-- Looking for sys/types.h - found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of intmax_t
-- Check size of intmax_t - done
-- Check size of uintmax_t
-- Check size of uintmax_t - done
-- Check size of pid_t
-- Check size of pid_t - done
-- Found Lua51: /home/unknown/rpi/rootfs/usr/lib/arm-linux-gnueabihf/liblua5.1.so;/home/unknown/rpi/rootfs/usr/lib/arm-linux-gnueabihf/libm.so (found version "5.1.5")
-- Luaudio_INCLUDE_DIRS:     /home/unknown/rpi/rootfs/usr/include/lua5.1
-- LUA_LIBRARIES:         /home/unknown/rpi/rootfs/usr/lib/arm-linux-gnueabihf/liblua5.1.so;/home/unknown/rpi/rootfs/usr/lib/arm-linux-gnueabihf/libm.so
-- Found libusb-1.0:
--  - Includes: /home/unknown/rpi/rootfs/usr/include/libusb-1.0
--  - Libraries: /home/unknown/rpi/rootfs/usr/lib/libusb-1.0.a
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.26")
-- checking for one of the modules 'check'
-- Looking for include file pthread.h
-- Looking for include file pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found libusb-1.0:
--  - Includes: /home/unknown/rpi/rootfs/usr/include/libusb-1.0
--  - Libraries: /home/unknown/rpi/rootfs/usr/lib/libusb-1.0.a
-- Configuring done
-- Generating done
-- Build files have been written to: /home/unknown/projects/ha/workspace/ha/build-rpi

但是当我 运行 make 时,我在尝试定位库时遇到错误 header:

$ make
Scanning dependencies of target ha
[  2%] Building C object src/CMakeFiles/ha.dir/log.c.o
[  5%] Building C object src/CMakeFiles/ha.dir/cm.c.o
/home/unknown/projects/ha/workspace/ha/src/cm.c:13:31: fatal error: libusb-1.0/libusb.h: No such file or directory
 #include <libusb-1.0/libusb.h>
                               ^
compilation terminated.
make[2]: *** [src/CMakeFiles/ha.dir/cm.c.o] Error 1
make[1]: *** [src/CMakeFiles/ha.dir/all] Error 2
make: *** [all] Error 2

我完全被困在这里了。文件在那里:

$ ls ~/rpi/rootfs/usr/include/libusb-1.0/ -l
total 72
-rw-r--r-- 1 unknown unknown 70156 jun 22  2014 libusb.h

$ ls ~/rpi/rootfs/usr/lib/libusb-1.0.a -l
-rw-r--r-- 1 unknown unknown 109920 jun 22  2014 /home/unknown/rpi/rootfs/usr/lib/libusb-1.0.a

并且当 运行使用 --trace 标志使用 CMake 时,它​​似乎找到了 libusb 相关文件:

/home/unknown/projectes/ha/workspace/ha/src/CMakeLists.txt(8):  find_package(libusb-1.0 REQUIRED )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(46):  if(LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(49):  else(LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(50):  find_path(LIBUSB_1_INCLUDE_DIR NAMES libusb.h PATHS /usr/include /usr/local/include /opt/local/include /sw/include PATH_SUFFIXES libusb-1.0 )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(62):  find_library(LIBUSB_1_LIBRARY NAMES usb-1.0 usb PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(72):  set(LIBUSB_1_INCLUDE_DIRS ${LIBUSB_1_INCLUDE_DIR} )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(75):  set(LIBUSB_1_LIBRARIES ${LIBUSB_1_LIBRARY} )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(79):  if(LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(80):  set(LIBUSB_1_FOUND TRUE )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(83):  if(LIBUSB_1_FOUND )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(84):  if(NOT libusb_1_FIND_QUIETLY )
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(85):  message(STATUS Found libusb-1.0: )
-- Found libusb-1.0:
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(86):  message(STATUS  - Includes: ${LIBUSB_1_INCLUDE_DIRS} )
--  - Includes: /home/unknown/rpi/rootfs/usr/include/libusb-1.0
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(87):  message(STATUS  - Libraries: ${LIBUSB_1_LIBRARIES} )
--  - Libraries: /home/unknown/rpi/rootfs/usr/lib/libusb-1.0.a
/usr/share/cmake-2.8/Modules/Findlibusb-1.0.cmake(96):  mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES )
/home/unknown/projectes/ha/workspace/ha/src/CMakeLists.txt(10):  INCLUDE_DIRECTORIES(${LIBUSB_1_INCLUDE_DIRS} )

我是 CMake 的新手,到目前为止,我无法在此站点或其他任何地方找到任何关于同一问题的有用条目。

有线索吗?

问题

cmake --trace 输出可以看出,搜索 libusb-1.0 库的 Findlibusb-1.0.cmake 脚本检测到库 headers 通过

find_path(LIBUSB_1_INCLUDE_DIR NAMES libusb.h ...)

这意味着,脚本 期望 libusb.h header 被包含为

#include <libusb.h>

(从 cmake 调用的输出可以推导出相同的结论:第

- Includes: /home/unknown/rpi/rootfs/usr/include/libusb-1.0

包含路径已经包含 libusb-1.0 后缀。)

但错误消息显示,cm.c 文件 实际上包括 header 作为

#include <libusb-1.0/libusb.h>

这意味着,Findlibusb-1.0.cmake 您使用的脚本(CMake 本身附带)与您项目中库的实际使用不兼容

理想方案

您需要使用 compatible Findlibusb-1.0.cmake 脚本发布您的项目,该脚本使用

find_path(LIBUSB_1_INCLUDE_DIR NAMES libusb-1.0/libusb.h ...)

用于检测包含路径。例如,来自 PCL 库的 one。 (在项目的开头 CMakeLists.txt 您需要调整 CMAKE_MODULE_PATH 变量以找到脚本。)

快速解决方法

您可以在 CMake 缓存中将路径 /home/unknown/rpi/rootfs/usr/include/libusb-1.0 替换为 /home/unknown/rpi/rootfs/usr/include。 (修改缓存后需要重新运行cmake)。

因为缓存的值很可能用于 include_directories() 从您的项目调用,所以将使用正确的目录。


I'm wondering why find_package works differently when cross compiling.

更可能的是 find_package 在 PC 上和 cross-compiling 上工作相同,但在 PC 上你得到路径 /usr/include 被其他方式包含(例如,它被默认包含) .