You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:31:20