如何让CMake使用其他根文件系统中的旧版libc进行交叉编译?
交叉编译优先级问题:优先使用目标系统旧版libc
问题背景
在WSL-Ubuntu22.04环境下,通过CMake交叉编译可运行于旧版Debian Stretch(2017年版本)的应用程序(目标系统运行缓慢,故选择本地编译后复制部署)。已编写工具链文件并完成编译,但编译器始终使用本地系统的新版libc,而非目标系统的旧版libc。
已将目标系统完整根文件系统复制到本地/opt/box-root-fs目录,且在工具链文件中设置了CMAKE_FIND_ROOT_PATH和CMAKE_SYSROOT,但编译器仍优先搜索本地系统的头文件和库。通过VERBOSE=1 make查看编译命令,确认--sysroot参数已正确添加,但头文件搜索目录中,本地系统目录排在目标根文件系统目录之前。需要解决如何让编译器优先使用复制的目标根文件系统中的旧版库。
项目文件
CMakeLists.txt
cmake_minimum_required (VERSION 3.7) PROJECT(two_lidars) # Change as wished set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_BUILD_TYPE "Debug") # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() ########### # toojpeg # ########### add_library(toojpeg toojpeg/toojpeg.cpp) target_include_directories(toojpeg PUBLIC ${PROJECT_SOURCE_DIR}/include) ################ # single lidar # ################ set(SINGLE_LIDAR_NAME single_lidar_listener) set(single_lidar_files single_lidar.cpp sick_scan_xd_api_wrapper.c ) add_executable(${SINGLE_LIDAR_NAME} ${single_lidar_files}) # needs toojpeg target_link_libraries(${SINGLE_LIDAR_NAME} toojpeg) # set(SINGLE_LIDAR_INCLUDE_DIRS ${INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/include) # need sick find_package(sick_scan_xd REQUIRED) set(SINGLE_LIDAR_INCLUDE_DIRS ${SINGLE_LIDAR_INCLUDE_DIRS} ${SICK_SCAN_XD_INCLUDE_DIR}) include(CMakePrintHelpers) cmake_print_variables(SICK_SCAN_XD_LIBRARIES SICK_SCAN_XD_INCLUDE_DIR) target_include_directories(${SINGLE_LIDAR_NAME} PUBLIC ${SINGLE_LIDAR_INCLUDE_DIRS}) target_include_directories(${SINGLE_LIDAR_NAME} PUBLIC /usr/local/include) target_link_libraries(${SINGLE_LIDAR_NAME} ${SICK_SCAN_XD_LIBRARIES}) target_link_libraries(${SINGLE_LIDAR_NAME} ${CMAKE_DL_LIBS}) ######## # main # ######## set(main_files main.cpp ) add_executable(${PROJECT_NAME} ${main_files})
工具链文件 TC-arm-linux-gnueabihf.cmake
# the name of the target operating system set(CMAKE_SYSTEM_NAME Linux) # which compilers to use for C and C++ set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) # where is the target environment located set(CMAKE_FIND_ROOT_PATH /opt/box-root-fs) set(CMAKE_SYSROOT /opt/box-root-fs) # adjust the default behavior of the FIND_XXX() commands: # search programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search headers and libraries in the target environment set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
配置命令
mkdir -p ./build/ && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=../TC-arm-linux-gnueabihf.cmake ..
解决方法
强制指定编译器sysroot:部分交叉编译器自带默认sysroot路径,会覆盖CMake设置。在工具链文件中添加编译/链接参数强制指定:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --sysroot=/opt/box-root-fs") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --sysroot=/opt/box-root-fs") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=/opt/box-root-fs")调整头文件/库搜索优先级:在工具链文件中强制设置优先搜索目标系统路径:
set(CMAKE_INCLUDE_PATH "/opt/box-root-fs/usr/include;/opt/box-root-fs/include") set(CMAKE_LIBRARY_PATH "/opt/box-root-fs/usr/lib;/opt/box-root-fs/lib")限制find_package搜索范围:避免CMake在主机环境查找依赖包,在工具链文件中添加:
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)清理重建缓存:删除旧构建目录,重新执行配置编译,避免缓存干扰:
rm -rf build && mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=../TC-arm-linux-gnueabihf.cmake .. && make VERBOSE=1
内容的提问来源于stack exchange,提问作者Alessandro Bertulli
相关产品推荐
相关产品推荐

