为什么使用cmake? 使用cmake的原因是现在有许多的c/c++项目都使用cmake这个工具来构建项目。我相信是一种趋势,以后会有越来越多的项目使用cmake。这是其中一个原因,另一个原因是我想学QT,但是我又不想用QT Creator,所以学习一下cmake方便以后构建QT项目。
新建项目 使用stm32cubemx来生成新项目代码。具体步骤不在这赘述,网上有许多资料。我新建了一个名称为led的项目,显然这个项目就是简单点个灯。注意Toolchain选择make。
创建CMakeLists.txt文件 cd led
touch CMakeLists.txt
先到led这个项目的目录下,创建CMakeLists.txt 文件。
编写CMakeLists.txt 编写编译工具链文件 cmake并不知道我们在交叉编译,所以编写编译工具链文件来告诉cmake我们在进行交叉编译,并说明我们使用的是什么编译工具链。
cd led
touch gcc-arm-none-eabi.cmake
然后编辑gcc-arm-none-eabi.cmake ,我使用的是neovim,也可以使用其他编辑器。
nvim gcc-arm-none-eabi.cmake
在gcc-arm-none-eabi.cmake 中添加以下内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 set (CMAKE_SYSTEM_NAME Linux)set (CMAKE_SYSTEM_PROCESSOR arm)set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)set (TOOLCHAIN_PREFIX arm-none-eabi-)set (CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX} gcc)set (CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER} )set (CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX} g++)set (CMAKE_LINKER ${TOOLCHAIN_PREFIX} g++)set (CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX} objcopy)set (CMAKE_SIZE ${TOOLCHAIN_PREFIX} size)set (CMAKE_EXECUTABLE_SUFFIX_ASM ".elf" )set (CMAKE_EXECUTABLE_SUFFIX_C ".elf" )set (CMAKE_EXECUTABLE_SUFFIX_CXX ".elf" )
在此不详细说明各语句的作用,具体见官网:https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html
编写CMakeLists.txt nvim CMakeLists.txt
在CMakeLists.txt 中添加以下内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 cmake_minimum_required (VERSION 3.29 )set (CMAKE_PROJECT_NAME led)set (CMAKE_BUILD_TYPE Debug)set (CMAKE_EXPORT_COMPILE_COMMANDS ON )include ("gcc-arm-none-eabi.cmake" )set (TARGET_FLAGS "-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard " )set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_FLAGS}" )set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fdata-sections -ffunction-sections" )set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g3" )set (CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -MMD -MP" )set (CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics" )set (CMAKE_C_LINK_FLAGS "${TARGET_FLAGS}" )set (CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -T \"${CMAKE_SOURCE_DIR}/STM32F407VETx_FLASH.ld\"" )set (CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} --specs=nano.specs" )set (CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections" )set (CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lc -lm -Wl,--end-group" )set (CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--print-memory-usage" )set (CMAKE_CXX_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group" )project (${CMAKE_PROJECT_NAME} C CXX ASM)add_executable (${CMAKE_PROJECT_NAME} )target_compile_definitions (${CMAKE_PROJECT_NAME} PRIVATE USE_HAL_DRIVER STM32F407xx $<$<CONFIG:Debug>:DEBUG> ) target_sources (${CMAKE_PROJECT_NAME} PRIVATE ./Core/Src/main.c ./Core/Src/gpio.c ./Core/Src/stm32f4xx_it.c ./Core/Src/stm32f4xx_hal_msp.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c ./Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c ./Core/Src/system_stm32f4xx.c ./Core/Src/sysmem.c ./Core/Src/syscalls.c ./startup_stm32f407xx.s ) target_include_directories (${CMAKE_PROJECT_NAME} PRIVATE ./Core/Inc ./Drivers/STM32F4xx_HAL_Driver/Inc ./Drivers/STM32F4xx_HAL_Driver/Inc/Legacy ./Drivers/CMSIS/Device/ST/STM32F4xx/Include ./Drivers/CMSIS/Include ) add_custom_command (TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -O binary -S ${CMAKE_PROJECT_NAME} .elf ${CMAKE_PROJECT_NAME} .bin COMMAND ${CMAKE_OBJCOPY} -O ihex ${CMAKE_PROJECT_NAME} .elf ${CMAKE_PROJECT_NAME} .hex COMMAND echo "Size--------------------------------------------" COMMAND ${CMAKE_SIZE} ${CMAKE_PROJECT_NAME} .elf ${CMAKE_PROJECT_NAME} .hex )
编译项目 mkdir build
cd build
cmake -G Ninja ..
ninja
首先创建build目录,编译产生的文件会放在这个目录里。然后进入build目录。我使用ninja作为生成器,使用make当然也是可以的。最后ninja
生成可执行文件。终端输出如下。
cmake -G Ninja .. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ❯ cmake -G Ninja .. -- The C compiler identification is GNU 10.3.1 -- The CXX compiler identification is GNU 10.3.1 -- The ASM compiler identification is GNU -- Found assembler: /home/seraphembera/environment/stm32/gcc-arm-none-eabi/bin/arm-none-eabi-gcc -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /home/seraphembera/environment/stm32/gcc-arm-none-eabi/bin/arm-none-eabi-gcc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /home/seraphembera/environment/stm32/gcc-arm-none-eabi/bin/arm-none-eabi-g++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done (0.3s) -- Generating done (0.0s) -- Build files have been written to: /home/seraphembera/work/stm32/projects/led/build
ninja 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ❯ ninja [24/24] Linking C executable led.elf Memory region Used Size Region Size %age Used RAM: 1584 B 128 KB 1.21% CCMRAM: 0 GB 64 KB 0.00% FLASH: 6004 B 512 KB 1.15% Size-------------------------------------------- text data bss dec hex filename 5984 20 1572 7576 1d98 led.elf 0 6004 0 6004 1774 led.hex _ _ ___ ___ _ __ __ _ _ __ | |__ ___ _ __ ___ | |__ ___ _ __ __ _ / __|/ _ \ '__/ _` | ' _ \| '_ \ / _ \ ' _ ` _ \| '_ \ / _ \ ' __/ _` | \__ \ __/ | | (_| | |_) | | | | __/ | | | | | |_) | __/ | | (_| | |___/\___|_| \__,_| .__/|_| |_|\___|_| |_| |_|_.__/ \___|_| \__,_| |_|
烧录可执行文件 使用openocd烧录文件。
1 2 3 4 5 6 7 8 openocd \ -f interface/cmsis-dap.cfg \ -f target/stm32f4x.cfg \ -c init \ -c halt \ -c "program led.elf verify reset exit" \ -c reset \ -c shutdown