STM32项目使用CMake

3
我将尝试使用CMake创建并编译一个基于ARM的STM32项目。
下面是CMakeLists.txt的内容:
cmake_minimum_required(VERSION 3.7)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

# Enable logging messages
#set(CMAKE_VERBOSE_MAKEFILE ON)

# Project name
set(PROJECT_NAME FixtureTACO)
PROJECT(${PROJECT_NAME} C CXX ASM)
SET(CMAKE_CXX_STANDARD 11)

###################### CHIP CONFIGURATION ##########################
SET(ROOT_PROJ   ${CMAKE_CURRENT_SOURCE_DIR})
SET(CPU         "cortex-m4")
SET(ARCH_NAME   "arm")
SET(ARCH_VER    "v7e-m")
SET(FAMILY      "stm32f3")
SET(CHIP        "STM32F303xC")
SET(ARCH        "${ARCH_NAME}${ARCH_VER}")
####################################################################

# MCU Config
set(FPU         "-mfpu=fpv4-sp-d16")
set(FLOAT_ABI   "-mfloat-abi=hard")

# Toolchain path
set(TOOLCHAIN_PATH  "")
set(ARM_LIB         "/usr/lib/arm-none-eabi/lib/${ARCH}")
# Specify C, C++ and ASM compilers
SET(CMAKE_C_COMPILER    ${TOOLCHAIN_PATH}arm-none-eabi-gcc)
SET(CMAKE_CXX_COMPILER  ${TOOLCHAIN_PATH}arm-none-eabi-g++)
set(AS                  ${TOOLCHAIN_PATH}arm-none-eabi-as)
set(AR                  ${TOOLCHAIN_PATH}arm-none-eabi-ar)
set(OBJCOPY             ${TOOLCHAIN_PATH}arm-none-eabi-objcopy)
set(OBJDUMP             ${TOOLCHAIN_PATH}arm-none-eabi-objdump)
set(SIZE                ${TOOLCHAIN_PATH}arm-none-eabi-size)
set(GDB                 ${TOOLCHAIN_PATH}arm-none-eabi-gdb)
set(SIZE                ${TOOLCHAIN_PATH}arm-none-eabi-size)

# Definitions passed at compile time (#defines)
add_definitions(-DFAMILY=${FAMILY})
add_definitions(-DCHIP=${CHIP})
add_definitions(-D${CHIP})
add_definitions(-DUSE_FULL_LL_DRIVER)
add_definitions(-USE_HAL_DRIVER)
add_definitions(-DHSE_VALUE=8000000)
add_definitions(-DHSE_STARTUP_TIMEOUT=100)
add_definitions(-DLSE_STARTUP_TIMEOUT=5000)
add_definitions(-DLSE_VALUE=32768)
add_definitions(-DHSI_VALUE=8000000)
add_definitions(-DLSI_VALUE=40000)
add_definitions(-DDD_VALUE=3300)
add_definitions(-DPREFETCH_ENABLE=1)

# Compilation flags
add_compile_options(-mcpu=${CPU})
add_compile_options(-march=${ARCH})
add_compile_options(-mthumb)
add_compile_options(${FPU})
add_compile_options(${FLOAT_ABI})
add_compile_options(-Og)
add_compile_options(-Wall)
add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)
# Only for debugging
add_compile_options(-g -gdwarf-2)


# Linker script path
file(GLOB_RECURSE LINKER_SCRIPT ${ROOT_PROJ}/platforms/${FAMILY}/Linker/*.ld)

# Variables initialized first time
SET(CMAKE_CXX_FLAGS_INIT "-std=c++11")
SET(CMAKE_C_FLAGS_INIT "-std=gnu99")

################################## Source code ###############################################################
# Retrieve all sources # "platforms/${FAMILY}/Startup/*.s"
file(GLOB SOURCES  "platforms/${FAMILY}/Startup/*.s" "src/*.cpp" "src/*.c" "platforms/${FAMILY}/Hal/src/*.c" "platforms/${FAMILY}/Device/*.c")
#Retrieve all locations of headers
file(GLOB_RECURSE HEADERS "includes/*.h"  "src/*.h" "platforms/${FAMILY}*.h")
set (INCLUDE_DIRS "")
foreach (_headerFile ${HEADERS})
    get_filename_component(_dir ${_headerFile} PATH)
    list (APPEND INCLUDE_DIRS ${_dir})
endforeach()
list(REMOVE_DUPLICATES INCLUDE_DIRS)
include_directories(${INCLUDE_DIRS})
link_directories(${ARM_LIB})
################################## Source code END ###########################################################

set(EXE_NAME "${PROJECT_NAME}_${CHIP}")
add_executable(${EXE_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${CPU} -mthumb ${FPU} ${FLOAT_ABI} --specs=nano.specs -T${LINKER_SCRIPT} -Wl,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map,--cref -Wl,--gc-sections")

# Libs and external dependencies
target_link_libraries(${EXE_NAME}.elf -lc -lm -lnosys)

# Outputs
set(ELF_FILE ${PROJECT_BINARY_DIR}/${EXE_NAME}.elf)
set(HEX_FILE ${PROJECT_BINARY_DIR}/${EXE_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${EXE_NAME}.bin)

add_custom_command(TARGET "${EXE_NAME}.elf" POST_BUILD
        # Build .hex and .bin files
        COMMAND ${OBJCOPY} -Obinary ${ELF_FILE} ${BIN_FILE}
        COMMAND ${OBJCOPY} -Oihex  ${ELF_FILE} ${HEX_FILE}
        COMMENT "Building ${PROJECT_NAME}.bin and ${PROJECT_NAME}.hex"

        # Copy files to a custom build directory
        COMMAND ${CMAKE_COMMAND} -E copy ${ELF_FILE} "${ROOT_PROJ}/builds/${CHIP}/${EXE_NAME}.elf"
        COMMAND ${CMAKE_COMMAND} -E copy ${HEX_FILE} "${ROOT_PROJ}/builds/${CHIP}/${EXE_NAME}.hex"
        COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} "${ROOT_PROJ}/builds/${CHIP}/${EXE_NAME}.bin"

        # Display sizes
        COMMAND ${SIZE} --format=berkeley ${EXE_NAME}.elf ${EXE_NAME}.hex
        COMMENT "Invoking: Cross ARM GNU Print Size"
        )

add_custom_target(UPLOAD
        ${GDB} -iex "target remote tcp:127.0.0.1:3333"
        -iex "monitor program ${EXE_NAME}.elf"
        -iex "monitor reset init"
        -iex "disconnect" -iex "quit ")

当我尝试编译时,出现以下错误:
[ 82%] Building C object CMakeFiles/FixtureTACO_STM32F303xC.elf.dir/platforms/stm32f3/Hal/src/stm32f3xx_ll_utils.c.obj
[ 86%] Building ASM object CMakeFiles/FixtureTACO_STM32F303xC.elf.dir/platforms/stm32f3/Startup/startup_stm32f303xc.s.obj
cc: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ instead
cc: error: unrecognized command line option ‘-mthumb’; did you mean ‘-mtbm’?
cc: error: unrecognized command line option ‘-mfpu=fpv4-sp-d16’
cc: error: unrecognized command line option ‘-mfloat-abi=hard’

只有当汇编文件(在这种情况下是startup.s)存在于源文件中并且FPU和FLOAR_ABI标志存在时,才会出现错误。正如您所看到的,startup_stm32f303xc.s编译时出现了错误。
我怀疑我将这些标志添加到了错误的位置,但我不知道在哪里添加它们才能使其正常工作。
后来编辑:我已经在我的ubuntu系统上安装了arm 7编译器。由于它已经存在于环境变量中,因此我可以在不指定任何路径的情况下使用它。我可以为其他机器目标(从Makefiles)编译ARM代码而没有问题。我的问题在于cmake。

我的猜测是你需要使用生成器表达式和$<COMPILE_LANGUAGE:lang>,只向C编译器添加C选项,向ASM编译器添加ASM选项。实际上,你正在为两种语言的编译器添加选项,这会在编译ASM文件时出现问题。 - fdk1342
@Fred 我认为这正是我的问题。你能给我更多的细节吗? - caffeine
3个回答

4

在你的代码行 set(TOOLCHAIN_PATH "") 中,你必须加入一个编译器路径。首先前往获取免费的GCC ARM ToolChain。下载适用于你操作系统的版本,然后将其复制到你最喜欢的位置。如果你使用Linux,可以使用我提供的路径配置: 1.) 将gcc arm编译器复制到/opt/目录下:

sudo tar xjfv ~/Downloads/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2 -C /opt/

如果你想要更“性感”的路径,可以使用符号链接:

sudo ln -s /opt/gcc-arm-none-eabi-7-2018-q2-update/  /opt/gcc-arm-none-eabi

接下来,转到您的CMakeLists.txt并将set命令重写为:

set(TOOLCHAIN_PATH  "/opt/gcc-arm-none-eabi/bin")

但是,构建STM32项目的更好解决方案是使用已经为STM32系列专门制作的stm32-cmake模板项目。使用已经成功工作的东西会更容易。您还需要两个前提条件:安装STM32CubeMX和GCC ARM ToolChain。如果您想知道如何使用此模板,请直接私信我,我会给您快速指导。


你不需要“安装”工具链,只需将文件复制到一个目录中即可。如果你已经有了工具链文件,在你的代码中添加路径并加入 set(TOOLCHAIN_PATH "path/to/your/toolchain/bin") - user45189
我刚刚在查看stm32-cmake,让我感到困扰的是CMSIS对于任何项目都是必需的。我想使用纯HAL。 - Daniel N.

3

好的,我终于成功解决了!

我需要替换

set(AS ${TOOLCHAIN_PATH}arm-none-eabi-as)

使用

set(CMAKE_ASM_COMPILER  ${TOOLCHAIN_PATH}arm-none-eabi-gcc)

这并不是一个错误,而是GCC编译器的问题。您还可以附加以下标志:-x assembler-with-cpp

CMake不知道我的自定义ASM编译器,因此除非我使用CMAKE_ASM_COMPILER进行强制编译,否则它将使用默认系统ASM编译器。现在该项目已构建完成,在微控制器上正常工作。

其他答案都还行,但只有一半正确。只有ASM文件使用了错误的编译器被编译。


1
我认为您尝试使用x86编译器编译ARM代码,这是不可行的。您需要下载ARM工具链并使用正确的编译器。
-mcpu在x86分支中已经过时,但在ARM分支中没有过时。
其他选项在x86编译器中不存在。

是的!这就是问题所在。只有ASM编译器被省略了,其他都没问题。 - caffeine
@caffeine 很好。但实际上这个信息是显而易见的。 - 0___________

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接