Page's Personal Website

Cmake的toolchain自定义变量失效问题

2024-08-09

在编译我们库的时候,cmake执行到toolchain.cmake的时候,一些自定义变量是空的,但是看参数我是已经传递进去了

简介

toolchain

toolchain的用途官网解释的很清楚[1],主要是为了交叉编译

  • Cross-compiling

Cross-compiling a piece of software means that the software is built on one system, but is intended to run on a different system.

分析

测试用例

官网代码拿过来整一个简单的测试用例[2]

MESSAGE("------------------------------------------1" ${ANDROID_NDK})
if( NOT ANDROID_NDK )
  MESSAGE("111")
else()
  MESSAGE("222")
endif()
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)

# which C and C++ compiler to use
set(CMAKE_C_COMPILER /home/alex/eldk-mips/usr/bin/mips_4KC-gcc)
set(CMAKE_CXX_COMPILER
    /home/alex/eldk-mips/usr/bin/mips_4KC-g++)

# location of the target environment
set(CMAKE_FIND_ROOT_PATH /home/alex/eldk-mips/mips_4KC
                          /home/alex/eldk-mips-extra-install )

# adjust the default behavior of the FIND_XXX() commands:
# search for headers and libraries in the target environment,
# search for programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
MESSAGE("------------------------------------------2")

执行cmake命令,把自定义变量ANDROID_NDK传递过去

cmake -DANDROID_NDK=externals/android-ndk-r10e -DCMAKE_TOOLCHAIN_FILE=..\linux.toolchain.cmake ..

输出结果:

F:\study\compile\cmake\cmake_toolchain\build>cmake -DANDROID_NDK=externals/android-ndk-r10e -DCMAKE_TOOLCHAIN_FILE=..\linux.toolchain.cmake ..
-- Building for: Visual Studio 17 2022
CMake Warning (dev) at CMakeLists.txt:1 (project):
  cmake_minimum_required() should be called prior to this top-level project()
  call.  Please see the cmake-commands(7) manual for usage documentation of
  both commands.
This warning is for project developers.  Use -Wno-dev to suppress it.

------------------------------------------1==externals/android-ndk-r10e
222
------------------------------------------2
------------------------------------------1==externals/android-ndk-r10e
222
------------------------------------------2
-- The C compiler identification is MSVC 19.36.32535.0
-- The CXX compiler identification is MSVC 19.36.32535.0
-- Detecting C compiler ABI info
------------------------------------------1==
111
------------------------------------------2
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
------------------------------------------1==
111
------------------------------------------2
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (3.0s)
-- Generating done (0.0s)
-- Build files have been written to: F:/study/compile/cmake/cmake_toolchain/build

小结

  • toolchain.cmake会执行多次[3],细看的话会发现是检查不同的东西(C compiler或者C++ compiler)
  • ANDROID_NDK自定义变量在强两次是有值的,后面两次却没有了

原因

  • 按照[3][4]中的回答来看,首先还是因为toolchain.cmake因为try_compile会执行多次,这个上面测试结果也可以看得出来
  • 然后就是自定义变量,并不会递归的传递下去

解决

  • 方法一:设置到环境变量即可
  • 方法二:使用CMAKE_TRY_COMPILE_PLATFORM_VARIABLES[5],参考[2]中的测试用例
set(CMAKE_SYSTEM_NAME Linux)

set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES ANDROID_NDK)

再看打印结果

F:\study\compile\cmake\cmake_toolchain\build>cmake -DANDROID_NDK=externals/android-ndk-r10e -DCMAKE_TOOLCHAIN_FILE=..\linux.toolchain.cmake ..
-- Building for: Visual Studio 17 2022
CMake Warning (dev) at CMakeLists.txt:1 (project):
  cmake_minimum_required() should be called prior to this top-level project()
  call.  Please see the cmake-commands(7) manual for usage documentation of
  both commands.
This warning is for project developers.  Use -Wno-dev to suppress it.

------------------------------------------1==externals/android-ndk-r10e
222
------------------------------------------2
------------------------------------------1==externals/android-ndk-r10e
222
------------------------------------------2
-- The C compiler identification is MSVC 19.36.32535.0
-- The CXX compiler identification is MSVC 19.36.32535.0
-- Detecting C compiler ABI info
------------------------------------------1==externals/android-ndk-r10e
222
------------------------------------------2
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
------------------------------------------1==externals/android-ndk-r10e
222
------------------------------------------2
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (3.0s)
-- Generating done (0.0s)
-- Build files have been written to: F:/study/compile/cmake/cmake_toolchain/build

可以看到每一次调用toolchain.cmake都会正确的输出自定义变量ANDROID_NDK的值了

参考

[1][官网文档](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html)

[2][测试用例](https://github.com/pkxpp/HowToWriteCmakelistsFile/tree/main/7%20tool%20chain)

[3][toolchain.cmake执行多次]https://stackoverflow.com/questions/66700152/why-is-the-toolchain-file-executed-a-few-times-in-cmake

[4][toolchain变量失效]https://stackoverflow.com/questions/28613394/check-cmake-cache-variable-in-toolchain-file/66706187#66706187

[5][CMAKE_TRY_COMPILE_PLATFORM_VARIABLES](https://cmake.org/cmake/help/latest/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.html)


Comments

Content