使用cmake进行覆盆子pi的C交叉编译无法找到头文件

时间:2016-12-21 21:48:16

标签: c cmake raspberry-pi cross-compiling libusb-1.0

我正在尝试将在x86架构中运行良好的程序(Linux Mint 17.1)移植到Raspberry Pi(Raspbian Jessie Lite)。我正在使用CMake,所以我只是按照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时,我试图找到一个库标题时出错:

$ 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的新手,到目前为止,我无法在此网站上找到任何有用的条目,也无法在其他任何地方找到有关此问题的信息。

有任何线索吗?

1 个答案:

答案 0 :(得分:0)

问题

cmake --trace输出可以看出,搜索 libusb-1.0 库的Findlibusb-1.0.cmake脚本通过<检测到库头的包含目录< / p>

find_path(LIBUSB_1_INCLUDE_DIR NAMES libusb.h ...)

这意味着脚本期望 libusb.h标题包含在

#include <libusb.h>

(同样的结论可以从cmake call:line

的输出中推断出来
- Includes: /home/unknown/rpi/rootfs/usr/include/libusb-1.0

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

但错误消息显示,cm.c文件实际上包含标题为

#include <libusb-1.0/libusb.h>

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

理想的解决方案

您需要使用兼容的 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()调用中使用,因此将使用正确的目录。

  

我想知道为什么在交叉编译时find_package的工作方式不同。

find_package更可能在PC上和交叉编译时相同,但在PC上,您可以通过其他方式包含路径/usr/include(例如,默认包含它)。