【问题标题】:CMake GTest fatal error (missing stdlib.h) when cross compiling交叉编译时 CMake GTest 致命错误(缺少 stdlib.h)
【发布时间】:2019-05-31 15:33:51
【问题描述】:

设置

我有以下文件。

empty.cc:

#include <cstdlib>

CMakeLists.txt:

set(CMAKE_MINIMUM_VERSION 3.8)

cmake_minimum_required(VERSION ${CMAKE_MINIMUM_VERSION})

find_package(GTest REQUIRED)

set(gtest_test gtest-test)
add_executable(${gtest_test} empty.cc)
#target_link_libraries(${gtest_test} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) # Line A
target_link_libraries(${gtest_test} GTest::GTest GTest::Main) # Line B

工具链.cmake:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 4.14.0)
set(CMAKE_SYSTEM_PROCESSOR arm)


set(CMAKE_C_COMPILER /opt/zynq/xtl/bin/arm-linux-musleabihf-gcc)
set(CMAKE_CXX_COMPILER /opt/zynq/xtl/bin/arm-linux-musleabihf-g++)

set(CMAKE_SYSROOT /opt/zynq/xtl/arm-linux-musleabihf)

set(CMAKE_FIND_ROOT_PATH /opt/zynq/xtl/arm-linux-musleabihf)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER)


set(CMAKE_INSTALL_PREFIX /opt/zynq/xtl/arm-linux-musleabihf)

问题

我使用:

cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake .. && make VERBOSE=1 -j

当我使用Line A(即target_link_libraries(${gtest_test} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}))链接GTest 时,一切正常。但是当我使用Line B,即target_link_libraries(${gtest_test} GTest::GTest GTest::Main)时,出现以下错误:

/opt/zynq/xtl/bin/arm-linux-musleabihf-g++ --sysroot=/opt/zynq/xtl/arm-linux-musleabihf   -isystem /opt/zynq/xtl/arm-linux-musleabihf/include   -o CMakeFiles/gtest-test.dir/empty.cc.o -c /home/xxx/git/cmake/cmake-with-gtest/empty.cc
In file included from /home/xxx/git/cmake/cmake-with-gtest/empty.cc:1:
/opt/zynq/xtl/arm-linux-musleabihf/include/c++/8.3.0/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
 #include_next <stdlib.h>
               ^~~~~~~~~~
compilation terminated.
CMakeFiles/gtest-test.dir/build.make:62: recipe for target 
'CMakeFiles/gtest-test.dir/empty.cc.o' failed
make[2]: *** [CMakeFiles/gtest-test.dir/empty.cc.o] Error 1

g++版本

...$ /opt/zynq/xtl/bin/arm-linux-musleabihf-g++ --version
arm-linux-musleabihf-g++ (GCC) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

正常构建,即不交叉编译,使用任何一个都可以正常工作

target_link_libraries(${gtest_test} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) # Line A

target_link_libraries(${gtest_test} GTest::GTest GTest::Main) # Line B

问题

为什么使用一种链接方式会导致缺少标题,而另一种则可以正常工作?

【问题讨论】:

  • 小笔记(与问题无关): 1. CMAKE_SYSROOT 变量中设置的目录自动 被视为CMAKE_FIND_ROOT_PATH 列表中的一个;无需显式地将 sysroot 添加到 CMAKE_FIND_ROOT_PATH 列表中。 2.设置CMAKE_INSTALL_PREFIX一般不属于工具链。另请参阅设置默认安装前缀的模式:stackoverflow.com/questions/39481958/…

标签: c++ cmake cross-compiling googletest


【解决方案1】:

众所周知,将-isystem 用于标准编译器包含目录会破坏广泛用于标准C++ 头文件的#include_next 指令。参见例如这个问题:-isystem on a system include directory causes errors.

CMake 有一种过滤掉标准编译器包含目录的机制,它使用变量CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES 作为需要过滤掉的包含目录的列表。不幸的是,编译器不会自动检测到此列表(请参阅已关闭的错误报告:https://gitlab.kitware.com/cmake/cmake/issues/16291)。相反,目录 /usr/include(相对于 sysroot)只是添加到该列表中。

因为在您的工具链编译器中包含的目录不是/usr/include 而是/include 之一,您需要将此目录显式添加到异常列表中:

# in toolchain.cmake
list(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_SYSROOT}/include)
# Setting the exclude directory for C compiler is optional:
# C standard headers rarely use `#include_next` directive
list(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_SYSROOT}/include)

区别

target_link_libraries(${gtest_test} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) # Line A

target_link_libraries(${gtest_test} GTest::GTest GTest::Main) # Line B

Line B 使用 目标名称 进行链接,并且包含与该目标关联的目录会自动添加到您的可执行文件中。这就是你得到-isystem的原因。

第二种方式(Line B)被视为“现代”方式,建议在新编写的代码中使用。但是这两种方法都应该有效。

【讨论】:

  • 嗯...它不起作用。我没有提到,但我在/opt/zynq/xtl/arm-linux-musleabihf 中有usr 指向这个目录,即usr -&gt; .。所以/opt/zynq/xtl/arm-linux-musleabihf/include 如果实际上与/opt/zynq/xtl/arm-linux-musleabihf/usr/include 相同。
猜你喜欢
  • 2016-07-11
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
相关资源
最近更新 更多