xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。

前言

依我这几天学习cmake和xmake来说,xmake的构建项目的能力非常强大,并且速度也非常快,语法也是非常现代化。
同时,它也是一个自满足的构建系统,拥有强大的包管理系统,快速的构建引擎。

而且xmake的开发者活跃度较高,经常在线。

所以我决定用它来构建一个由cubeMX生成的stm32的项目。

安装xmake

项目地址:https://github.com/xmake-io/xmake/releases

windows

点击链接下载xmake的安装包,包名一般是xmake-[version].[win32|win64].exe,或者下载xmake-[version].[win32|win64].zip的包,解压后添加该路径到环境变量中。

或者可以使用winget install xmake安装。
xmake-stm32-2022-01-19-18-39-13

linux

我这里的是Ubuntu20.04 LTS系统,可以使用sudo apt install xmake直接安装。
xmake-stm32-2022-01-19-17-50-01

打开命令提示符,输入xmake --vision
xmake-stm32-2022-01-19-17-45-59

生成代码

安装STM32代码生成器-STM32CubeMX

在ST官网下载STM32CubeMX:https://www.st.com/zh/development-tools/stm32cubemx.html

xmake-stm32-2022-01-19-18-42-17

输入邮箱后会收到一封邮件,点开邮件链接就可以下载了。

使用CubeMX生成代码

选择芯片->选择功能配置->Project Manager

Project Manager里面的Project注意选择ToolChain为Makefile
xmake-stm32-2022-01-19-18-53-10

Code Generator里面选择Copy only the necessary library files 以减小项目大小。
xmake-stm32-2022-01-19-19-50-50

然后就可以生成代码了。
xmake-stm32-2022-01-19-19-59-05

编译工具

我们可以使用armcc和arm-none-eabi-gcc来编译,但是armcc一般是集成在Keil等软件中,需要收费,所以这里使用arm-none-eabi-gcc来编译。

arm-none-eabi-gcc

用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel,不适用编译 Linux 应用 Application),

一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用,所以不支持那些跟操作系统关系密切的函数。

在这里下载对应系统版本:https://launchpad.net/gcc-arm-embedded/+download

下载后解压到路径

1
wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q3-update/+download/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2

下载较慢,可以用天翼云:https://cloud.189.cn/t/VB7nuiY3QN32

解压后配置一下环境变量。

配置xmake

然后就是今天的重点,配置xmake文件,在目录里面新建xmake.lua文件。然后按照下面几个部分添加代码。

编译规则

为当前工程xmake.lua添加debug编译模式的配置规则

1
add_rules("mode.debug", "mode.release")

交叉编译链

1
2
3
4
toolchain("arm-none-eabi")
set_kind("standalone")
set_sdkdir("C:/software/gcc-arm-none-eabi")
toolchain_end()

这个set_sdkdir根据自己的路径,只要这个目录下面包含bin目录就可以自动识别了。

编译文件

注:本小节下的代码除了target外都要空格,表示在target目标工程下配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
target("stm32f103")
set_kind("binary")
set_toolchains("arm-none-eabi")
add_files(
"./Core/Src/*.c",
"./startup_stm32f103xb.s",
"./Drivers/STM32F1xx_HAL_Driver/Src/*.c"
)
add_includedirs(
"./Core/Inc",
"./Drivers/CMSIS/Include",
"./Drivers/CMSIS/Device/ST/STM32F1xx/Include",
"./Drivers/STM32F1xx_HAL_Driver/Inc",
"./Drivers/STM32F1xx_HAL_Driver/Inc/Legacy"
)

设置一个目标工程target,然后设置刚刚的配置的交叉编译工具。
接着这里要选择包含所有的.c文件,.s文件和.h文件,xmake支持使用通配符来识别文件例如"src/*.c",来加载src目录下所有的c文件。

1
2
3
4
add_defines(
"USE_HAL_DRIVER",
"STM32F103xB"
)

再添加定义,这个是stm32里面的声明,相当于#define

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
add_cflags(
"-Og",
"-mcpu=cortex-m3",
"-mthumb",
"-Wall -fdata-sections -ffunction-sections",
"-g -gdwarf-2",{force = true}
)

add_asflags(
"-Og",
"-mcpu=cortex-m3",
"-mthumb",
"-x assembler-with-cpp",
"-Wall -fdata-sections -ffunction-sections",
"-g -gdwarf-2",{force = true}
)

add_ldflags(
"-Og",
"-mcpu=cortex-m3",
"-L./",
"-TSTM32F103C8Tx_FLASH.ld",
"-Wl,--gc-sections",
"-lc -lm -lnosys -lrdimon -u _printf_float",{force = true}
)

然后再填写一下源文件、静态文件和链接文件的参数。
就是指定一些编译时候的参数之类的,最后加上{force = true}强制启用参数,不启用的话有的参数会被xmake给忽略。

1
2
set_targetdir("build")
set_filename("output.elf")

设置编译目录,也可以不设置,一般默认build,然后输出文件的名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
after_build(function(target)
print("生成HEX 和BIN 文件")
os.exec("arm-none-eabi-objcopy -O ihex ./build//output.elf ./build//output.hex")
os.exec("arm-none-eabi-objcopy -O binary ./build//output.elf ./build//output.bin")
print("生成已完成")
import("core.project.task")
print("********************储存空间占用情况*****************************")
os.exec("arm-none-eabi-size -Ax ./build/output.elf")
os.exec("arm-none-eabi-size -Bx ./build/output.elf")
os.exec("arm-none-eabi-size -Bd ./build/output.elf")
print("heap-堆、stck-栈、.data-已初始化的变量全局/静态变量,bss-未初始化的data、.text-代码和常量")
-- task.run("flash")
end)

生成生成HEX 和BIN 文件,之后可以选择手动烧录进去比较好。

编译项目

使用xmake命令编译项目,xmake -v更加详细的编译,使用vscode的同学还可以使用xmake project -k compile_commands命令来启用配置vscode的intellisense自动提醒等功能。

gitee

将整个工程贴到gitee上了:https://gitee.com/luodeb/stm32-xmake

总结

简洁,好用。