0

我正在构建一个我想支持某个专有平台的应用程序。它使用了CMake 似乎不喜欢的 ARMCC 的修改版本 - 无论我做什么,它都会不断尝试armlink在不应该的地方提供奇怪的标志,而忽略覆盖其行为的尝试。

是否有可能从本质上提供一个关于 CMake 应该如何处理特定编译器的全新定义?即在整个过程中指定用于编译、链接等的二进制文件和标志、预期的文件扩展名等,这样CMake 就不会做任何讨厌的事情?CMake 似乎使自定义编译器定义变得非常晦涩难懂。

编辑:我已经让它提供了大部分正确的标志,但现在我意识到我无法更改 CMake 测试程序 - 如果某个非典型符号集(替代入口点,不是主要的)不存在。

编辑2:我已经跳过了测试程序,但是现在它在尝试获取编译器信息时失败了(为什么要麻烦?我已经给它提供了它需要知道的所有情况......)并出现此错误:

Error: C9912E: No --cpu selected

为了清楚起见,它在上面一行显示的命令显然具有提供给有效值的 --cpu 标志:

armcc.exe -xc++ --cpu=MPCore -fpch-preprocess -v -dD -E

虽然我完全不确定它试图用它的其余部分做什么 - 我似乎无法覆盖这部分。

4

1 回答 1

2

首先,你需要一个toolchain.cmake文件。在这里,您提供armcc编译器、链接器等的路径。

SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

# this one is important
SET( CMAKE_SYSTEM_PROCESSOR  arm )

SET(MCU_ARCH Cortex-M4) #MCU architecture

SET(TOOLCHAIN_BIN_DIR "C:/Keil_v5/ARM/ARMCC/bin/")
set(LINKER_SCATTER_SCRIPT ${PROJECT_SOURCE_DIR}/Scatter_file.sct)

SET(CMAKE_C_COMPILER            ${TOOLCHAIN_BIN_DIR}/armcc.exe      CACHE FILEPATH "C compiler")
SET(CMAKE_CXX_COMPILER          ${TOOLCHAIN_BIN_DIR}/armcc.exe      CACHE FILEPATH "C++ compiler")
SET(CMAKE_LINKER                ${TOOLCHAIN_BIN_DIR}/armlink.exe    CACHE FILEPATH "linker")
SET(CMAKE_AR                    ${TOOLCHAIN_BIN_DIR}/armar.exe      CACHE FILEPATH "Archiver")
SET(CMAKE_ASM_COMPILER          ${TOOLCHAIN_BIN_DIR}/armasm.exe     CACHE FILEPATH "Assembler")
SET(CMAKE_FROMELF               ${TOOLCHAIN_BIN_DIR}/fromelf.exe    CACHE FILEPATH "From ELF tool")

SET(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

SET(CMAKE_EXE_LINKER_FLAGS_INIT "--cpu ${MCU_ARCH} --myFlag1 --myFlag2 ${LINKER_SCATTER_SCRIPT}")

接下来,在CMakeLists.txt文件中,您可以传递编译器和链接器标志:

cmake_minimum_required(VERSION 3.10)
SET(CMAKE_VERBOSE_MAKEFILE ON)
project (MyProject C CXX ASM)


#Source Files -> Let CMake know your source files
SET(SRC_FILES       ${CMAKE_SOURCE_DIR}/Dir/main.c) 

add_executable(
        ${PROJECT_NAME}
        ${SRC_FILES})

#Defining compiler preprocessor directives
target_compile_definitions(${PROJECT_NAME} PRIVATE
        $<$<COMPILE_LANGUAGE:C>:  DEFINE_1;__DEBUG;>
        $<$<COMPILE_LANGUAGE:CXX>:DEFINE_2;__DEBUG;>)

#Defining compiler flags
target_compile_options(${PROJECT_NAME} PRIVATE
        $<$<COMPILE_LANGUAGE:C>:    --c99 -c -O0 --cpu ${MCU_ARCH};>
        $<$<COMPILE_LANGUAGE:CXX>:--cpp11 -c -O0 --cpu ${MCU_ARCH};>
        $<$<COMPILE_LANGUAGE:ASM>:--cpu ${MCU_ARCH} -g>)

SET(CMAKE_ASM_FLAGS         "--pd \"DEFINE_3"")
target_link_libraries(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/SomeLibFile.lib --flagForLibFile)
target_link_options(${PROJECT_NAME} PRIVATE --linkerFlags)

target_include_directories(${PROJECT_NAME} PUBLIC
        ${CMAKE_SOURCE_DIR})

对于必要的标志,看看 Keil 正在使用什么。

然后您可以通过将toolchain.cmake文件传递为来构建您的应用程序-DCMAKE_TOOLCHAIN_FILE=toolchain.cmake

编辑:根据来自KamilCuk的反馈进行更新

于 2020-04-28T06:40:04.780 回答