【发布时间】:2021-06-16 09:19:43
【问题描述】:
在尝试使用 SDCC 编译器创建交叉编译 CMake 工具链模板时,我遇到了一个非常奇怪的问题。
如this link 中所述,如果toolchain.cmake 文件定义了CMAKE_SYSTEM_NAME,CMake 将在Module/Platform 目录下查找具有${CMAKE_SYSTEM_NAME}.cmake 的文件。这个文件应该定义特定于平台的选项。就我而言,我使用它来查找 sdcc 编译器并设置一些编译器标志。
这对我来说很好用。使用cmake -DCMAKE_MODULE_PATH="${PATH_TO_MY_MODULES}" -DCMAKE_TOOLCHAIN_FILE="${PATH_TO_MY_TOOLCHAIN}" -DSDCC_SYSROOT="SOME_VALUE",CMake 会找到所有正确的工具链和平台文件。
似乎工具链和平台文件在配置过程中执行(不确定这是否正确)几次。在最初的几次中,我在 CMake 命令中传递的变量SDCC_SYSROOT 的值符合预期的SOME_VALUE。但是,相同的变量SDCC_SYSROOT 似乎在最后一次执行这些工具链/平台文件时失去了价值。所以他们是空的。这会导致我的脚本生成致命错误。
toolchain.cmake有以下内容:
set(CMAKE_SYSTEM_NAME SDCC_PIC_16F877A)
# Finding resource settings
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# Set default MCU family and model
if (NOT MICROCHIP_FAMILY)
set(MICROCHIP_FAMILY "pic16")
endif()
if (MICROCHIP_MODEL STREQUAL "pic16")
set(MICROCHIP_MODEL "16f877a")
endif()
# Need a better way to detect the supported models here
if (NOT MICROCHIP_FAMILY STREQUAL "pic16" AND NOT MICROCHIP_MODEL STREQUAL "16f877a")
message(FATAL_ERROR "Settings not supported. Please drop a request.")
endif()
if (NOT SDCC_ROOT)
message(FATA_ERROR "Need to provide the root (from toolchain.)")
endif()
# Cache those variables
set(SDCC_ROOT "${SDCC_ROOT}"
CACHE INTERNAL "Root directory of SDCC installation")
set(MICROCHIP_FAMILY "${MICROCHIP_FAMILY}"
CACHE INTERNAL "Family of the chip to compile for")
set(MICROCHIP_MODEL "${MICROCHIP_MODEL}"
CACHE INTERNAL "Model of the chip to compile for")
Module/Platform/SDCC_PIC_16F877A.cmake 文件包含以下内容:
# Check if the shit exists
message("!!! The value of root is ${SDCC_ROOT}")
if (NOT SDCC_ROOT)
message(FATAL_ERROR
"SDCC_ROOT is not defined. Please set this variable e.g.\n"
"cmake -DSDCC_ROOT=\"C:/Program Files/sdcc\"")
endif()
# Finding the compilers
find_program(CMAKE_C_COMPILER
sdcc
PATHS ${SDCC_ROOT}
PATH_SUFFIXES "bin"
DOC "path to the SDCC C compiler.")
而我的CMakeLists.txt 如下:
cmake_minimum_required(VERSION 3.10)
project(PicExample)
message("THE COMPILER IS ${CMAKE_C_COMPILER}")
add_executable(pic_example main.c)
我从project/build 目录调用的内容和我得到的错误:
cmake -DCMAKE_MODULE_PATH:FILEPATH="/mnt/c/Users/mathe/Desktop/coding/sdcc-pic-template/Modules" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="/mnt/c/Users/mathe/Desktop/coding/sdcc-pic-template/Modules/toolchain.cmake" -DSDCC_ROOT="testing/" ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
!!! The value of root is testing/
!!! The value of root is testing/
-- Check for working C compiler: /usr/bin/cc
FATA_ERRORNeed to provide the root (from toolchain.)
!!! The value of root is
CMake Error at /mnt/c/Users/mathe/Desktop/coding/sdcc-pic-template/Modules/Platform/SDCC_PIC_16F877A.cmake:4 (message):
SDCC_ROOT is not defined. Please set this variable e.g.
cmake -DSDCC_ROOT="C:/Program Files/sdcc"
Call Stack (most recent call first):
/usr/share/cmake-3.16/Modules/CMakeSystemSpecificInformation.cmake:26 (include)
/mnt/c/Users/mathe/Desktop/coding/sdcc-pic-template/build/CMakeFiles/CMakeTmp/CMakeLists.txt:3 (project)
CMake Error at /usr/share/cmake-3.16/Modules/CMakeTestCCompiler.cmake:44 (try_compile):
Failed to configure test project build system.
Call Stack (most recent call first):
CMakeLists.txt:2 (project)
-- Configuring incomplete, errors occurred!
See also "/mnt/c/Users/mathe/Desktop/coding/sdcc-pic-template/build/CMakeFiles/CMakeOutput.log".
为什么工具链文件会被 CMake 多次“执行”,并且在最近的运行中无法访问缓存?我一直发现用于交叉编译的 CMake 文档非常困难,尤其是在您使用非标准编译器时。
我知道其他人之前也遇到过同样的问题,但我并不是简单地要求一个简单的 hacky 解决方案(设置环境变量)。我实际上想知道为什么会发生这种情况(以前的答案没有解决)。
【问题讨论】:
-
但是.. cmake 有自己的 sdcc 支持。 github.com/Kitware/CMake/blob/master/Modules/Platform/… 。
!!! The value of root is testing/输出什么? -
@KamilCuk 该配置文件很好,除非您想为 PIC(微芯片)处理器进行编译。不幸的是,该平台不支持该架构所需的标志。主要问题是“gputils”中的 obj 输出扩展名不同,后者是使用 Sdcc 为 PIC 编译时使用的汇编程序。此外,输出来自平台 cmake 中的消息。
-
"在配置过程中,似乎工具链和平台文件被执行了几次(不确定这是否是正确的术语)。" - 是的,构建项目时会执行多次工具链文件。由于这个原因,它不能仅仅依赖于命令行中传递的 CACHE 变量。您可以将该变量存储在环境一中,以便工具链在下次调用时可以访问它。有关详细信息,请参阅重复的问题。
-
@Tsyvarev 我以前看过这些答案,但我仍然认为这不应该作为重复而关闭,因为虽然我确实有与其他两个问题相同的问题,但那里的答案确实如此不回答我的问题:“我有什么遗漏吗?为什么工具链文件会被 CMake 多次“执行”?”。另外,设置一个环境变量看起来很老套,可能不是现代 CMake 应该做的方式。通过重复这个问题,我们基本上阻止了具有专业知识的人实际回答和解释问题......
-
“虽然我确实和其他两个问题有同样的问题,但那里的答案并不能回答我的问题”。 - 请注意,Stack Overflow 期望该问题专门用于单个问题。根据标题 - “CMake 没有将参数传递给工具链平台文件” - 你的问题是将参数传递给工具链。而这个问题正是在其他问题中描述的。如果您想问为什么工具链被多次调用,那么将整个问题帖子专门用于这个问题。 (不要在一个问题帖子中提出多个问题)。