使用 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
被其他方式包含(例如,它被默认包含) .
我正在尝试移植一个 运行 在 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
被其他方式包含(例如,它被默认包含) .