文章目录
-
- [debug - MDK - arm-none-eabi - 从MDK工程做一个makefile工程出来](#debug - MDK - arm-none-eabi - 从MDK工程做一个makefile工程出来)
- 概述
- 笔记
- 先将编译结果整理成一个bat
- [makefile v0.1](#makefile v0.1)
- [makefile v0.2](#makefile v0.2)
- [makefile v0.4](#makefile v0.4)
- [makefile v0.5](#makefile v0.5)
- [makefile v0.6](#makefile v0.6)
- [makefile v0.7](#makefile v0.7)
- [makefile v0.8](#makefile v0.8)
- [makefile v0.9](#makefile v0.9)
- 最终编译效果
- 备注
- 备注
- 备注
- END
debug - MDK - arm-none-eabi - 从MDK工程做一个makefile工程出来
概述
想从一个基于arm-gcc工具链编译的MDK工程,做一个makefile工程出来。
达到和MDK工程编译一摸一样的效果。
前面做了实验(debug - MDK - arm-none-eabi - 将MDK工程编译过程的所有命令行参数找出来), 已经将MDK工程编译时的全部命令行编译参数找出来了。
现在整理一个makefile出来。
笔记
my_arm_gnu_env_only.bat
先写一个带有arm-gcc环境和gnu-make环境的脚本.
bash
@echo off
rem @file my_arm_gnu_env_only.bat
rem @breif 通用的arm-gcc工具链,编译哪个工程都可以
set path=%~dp0arm-gnu-toolchain\bin;%~dp0gnuwin32\bin;%~dp0curl;%path%
rem set path=C:\nxp\MCUXpressoIDE_25.6.136\ide\;%path%
cmd /k "echo my arm gnu env"
先将编译结果整理成一个bat
为了清晰,先将前面实验找出来的全部命令行参数先要用.bat表达出来,先能干活, 然后再整理成makefile, 这样清晰简单。
build.bat
bash
@echo off
rem @file build.bat
cls
rem 打印bat文件的全路径名称
echo %~f0
echo.
echo ------------------------------------------------------------
echo BEGIN
echo.
echo ------------------------------------------------------------
echo clean
rem 路径符号必须是用'\'
rem 建立必须存在的文件夹
if not exist .\out mkdir .\out
rem 删除中间文件
if exist ".\*.o" (
echo del .\*.o
del .\*.o
)
if exist ".\out\*.o" (
echo del .\out\*.o
del .\out\*.o
)
if exist ".\out\*.map" (
echo del .\out\*.map
del .\out\*.map
)
if exist ".\out\*.elf" (
echo del .\out\*.elf
del .\out\*.elf
)
if exist ".\out\*.d" (
echo del .\out\*.d
del .\out\*.d
)
if exist ".\out\*.hex" (
echo del .\out\*.hex
del .\out\*.hex
)
if exist ".\out\*.lst" (
echo del .\out\*.lst
del .\out\*.lst
)
echo.
dir /s /b /oneg
echo.
echo ------------------------------------------------------------
echo compile
rem 如果不指定输出名称, 就是同名的.o
rem arm-none-eabi-gcc -c main.c
rem compile .s
arm-none-eabi-as ^
-mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" ^
--defsym __UVISION_VERSION=543 ^
--defsym __GCC=1 ^
--defsym __GCC_VERSION=1431 ^
--defsym LPC175x_6x=1 ^
-alhms=./out/startup_lpc17xx.lst ^
--MD ./out/startup_lpc17xx.d ^
-o ./out/startup_lpc17xx.o "src/startup_LPC17xx.s"
arm-none-eabi-gcc ^
-c ^
-mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" ^
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" ^
-D__UVISION_VERSION="543" ^
-D__GCC -D__GCC_VERSION="1431" ^
-DLPC175x_6x ^
-Wa,-alhms=./out/main.lst ^
-o ./out/main.o "src/main.cpp"
echo.
echo ------------------------------------------------------------
echo Link
arm-none-eabi-gcc ^
-T ./src/LPC1768.ld ^
-mcpu=cortex-m3 -mthumb -mthumb-interwork -Wl,-Map="./out/arm-gcc.map" -nostartfiles ^
-o "./out/arm-gcc.elf" "./out/startup_lpc17xx.o" "./out/main.o"
echo.
echo ------------------------------------------------------------
echo convert
rem exe 可以用双引号包裹起来
"arm-none-eabi-objcopy.exe" -O ihex ./out/arm-gcc.elf ./out/arm-gcc.hex
echo.
dir /s /b /oneg
echo.
echo ------------------------------------------------------------
echo END
运行效果
在cmd中先运行包含arm-gcc环境的脚本my_arm_gnu_env_only.bat,然后再运行build.bat
bash
D:\my_dev\my_test\arm-gcc-makefile\v0.1\build.bat
------------------------------------------------------------
BEGIN
------------------------------------------------------------
clean
del .\out\*.o
del .\out\*.map
del .\out\*.elf
del .\out\*.d
del .\out\*.hex
del .\out\*.lst
D:\my_dev\my_test\arm-gcc-makefile\v0.1\build.bat
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src\LPC1768.ld
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src\main.cpp
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src\startup_LPC17xx.s
------------------------------------------------------------
compile
------------------------------------------------------------
Link
------------------------------------------------------------
convert
D:\my_dev\my_test\arm-gcc-makefile\v0.1\build.bat
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\arm-gcc.elf
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\arm-gcc.hex
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\arm-gcc.map
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\main.d
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\main.lst
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\main.o
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\startup_lpc17xx.d
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\startup_lpc17xx.lst
D:\my_dev\my_test\arm-gcc-makefile\v0.1\out\startup_lpc17xx.o
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src\LPC1768.ld
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src\main.cpp
D:\my_dev\my_test\arm-gcc-makefile\v0.1\src\startup_LPC17xx.s
------------------------------------------------------------
END
D:\my_dev\my_test\arm-gcc-makefile\v0.1>
makefile v0.1
从bat直接翻译一个最简单的makefile
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
all:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
arm-none-eabi-as \
-mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1 \
-alhms=./out/startup_lpc17xx.lst \
--MD ./out/startup_lpc17xx.d \
-o ./out/startup_lpc17xx.o "src/startup_LPC17xx.s"
arm-none-eabi-gcc \
-c \
-mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x \
-Wa,-alhms=./out/main.lst \
-o ./out/main.o "src/main.cpp"
arm-none-eabi-gcc \
-T ./src/LPC1768.ld \
-mcpu=cortex-m3 -mthumb -mthumb-interwork -Wl,-Map="./out/arm-gcc.map" -nostartfiles \
-o "./out/arm-gcc.elf" "./out/startup_lpc17xx.o" "./out/main.o"
arm-none-eabi-objcopy -O ihex ./out/arm-gcc.elf ./out/arm-gcc.hex
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
makefile v0.2
加入编译目标的依赖,依赖的实现变了,就编译。如果实现没变,就不编译
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.2 加入编译目标的依赖,提高编译效率
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
all: ./out/startup_lpc17xx.o ./out/main.o ./out/arm-gcc.elf
clean:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
./out/startup_lpc17xx.o: src/startup_LPC17xx.s
arm-none-eabi-as \
-mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1 \
-alhms=./out/startup_lpc17xx.lst \
--MD ./out/startup_lpc17xx.d \
-o ./out/startup_lpc17xx.o "src/startup_LPC17xx.s"
./out/main.o: src/main.cpp
arm-none-eabi-gcc \
-c \
-mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x \
-Wa,-alhms=./out/main.lst \
-o ./out/main.o "src/main.cpp"
./out/arm-gcc.elf: ./out/startup_lpc17xx.o ./src/LPC1768.ld ./out/main.o
arm-none-eabi-gcc \
-T ./src/LPC1768.ld \
-mcpu=cortex-m3 -mthumb -mthumb-interwork -Wl,-Map="./out/arm-gcc.map" -nostartfiles \
-o "./out/arm-gcc.elf" "./out/startup_lpc17xx.o" "./out/main.o"
arm-none-eabi-objcopy -O ihex ./out/arm-gcc.elf ./out/arm-gcc.hex
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
makefile v0.4
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.4 确认和验证是否实际目标可以写成伪目标, 答案是不能(会失去文件自动检测编译的功能,导致全部编译)
# v0.3 声明伪目标, 加入编译目标 rebuild
# v0.2 加入编译目标的依赖,提高编译效率
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
# 如果多个编译目标的规则都相同,可以将多个目标放在一起,用空格分开
# e.g.
# obj1 obj2: main.cpp
# gcc -xx ...
# 在编译目标的gcc命令中使用的自动变量
# @$ 当前目标
# @< 依赖的第一个文件
# -o @$ @< # 要编译的文件比较多时, 可以代替硬编码
# c_file: src/*.c
# 如果编译目标指定的依赖不存在,makefile会报错
# 如果没有的实际目标,就不要留在makefile中
# 编译具体目标时, 不能写成伪目标,而是要直接写成真正要编译的.o目标,否则就不能检测依赖的文件变化了,而是每次都全部编译
.PHONY: all clean rebuild
all: \
./out/arm-gcc.elf
@echo build all
rebuild:
make clean
make
clean:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
./out/startup_lpc17xx.o: src/startup_lpc17xx.s
arm-none-eabi-as \
-mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1 \
-alhms=./out/startup_lpc17xx.lst \
--MD ./out/startup_lpc17xx.d \
-o ./out/startup_lpc17xx.o "src/startup_LPC17xx.s"
./out/main.o: src/main.cpp
arm-none-eabi-gcc \
-c \
-mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x \
-Wa,-alhms=./out/main.lst \
-o ./out/main.o "src/main.cpp"
./out/arm-gcc.elf: ./out/startup_lpc17xx.o ./src/LPC1768.ld ./out/main.o
arm-none-eabi-gcc \
-T ./src/LPC1768.ld \
-mcpu=cortex-m3 -mthumb -mthumb-interwork -Wl,-Map="./out/arm-gcc.map" -nostartfiles \
-o "./out/arm-gcc.elf" "./out/startup_lpc17xx.o" "./out/main.o"
arm-none-eabi-objcopy -O ihex ./out/arm-gcc.elf ./out/arm-gcc.hex
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
makefile v0.5
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.5 将编译选项定义为变量
# v0.4 确认和验证是否实际目标可以写成伪目标, 答案是不能(会失去文件自动检测编译的功能,导致全部编译)
# v0.3 声明伪目标, 加入编译目标 rebuild
# v0.2 加入编译目标的依赖,提高编译效率
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
# 如果多个编译目标的规则都相同,可以将多个目标放在一起,用空格分开
# e.g.
# obj1 obj2: main.cpp
# gcc -xx ...
# 在编译目标的gcc命令中使用的自动变量
# @$ 当前目标
# @< 依赖的第一个文件
# -o @$ @< # 要编译的文件比较多时, 可以代替硬编码
# c_file: src/*.c
# 如果编译目标指定的依赖不存在,makefile会报错
# 如果没有的实际目标,就不要留在makefile中
# 编译具体目标时, 不能写成伪目标,而是要直接写成真正要编译的.o目标,否则就不能检测依赖的文件变化了,而是每次都全部编译
ASM_FLAGS = -mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1
CPP_FLAGS = -mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x
LINK_FLAGS = -mcpu=cortex-m3 -mthumb -mthumb-interwork -nostartfiles
.PHONY: all clean rebuild
all: \
./out/arm-gcc.elf
@echo build all
rebuild:
make clean
make
clean:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
./out/startup_lpc17xx.o: src/startup_lpc17xx.s
arm-none-eabi-as \
$(ASM_FLAGS) \
-alhms=./out/startup_lpc17xx.lst \
--MD ./out/startup_lpc17xx.d \
-o ./out/startup_lpc17xx.o "src/startup_LPC17xx.s"
./out/main.o: src/main.cpp
arm-none-eabi-gcc \
-c \
$(CPP_FLAGS) \
-Wa,-alhms=./out/main.lst \
-o ./out/main.o "src/main.cpp"
./out/arm-gcc.elf: ./out/startup_lpc17xx.o ./src/LPC1768.ld ./out/main.o
arm-none-eabi-gcc \
$(LINK_FLAGS) \
-Wl,-Map="./out/arm-gcc.map" \
-T ./src/LPC1768.ld \
-o "./out/arm-gcc.elf" "./out/startup_lpc17xx.o" "./out/main.o"
arm-none-eabi-objcopy -O ihex ./out/arm-gcc.elf ./out/arm-gcc.hex
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
makefile v0.6
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.6 用makefil自动变量优化编译命令, 使gcc命令行更灵活
# v0.5 将编译选项定义为变量
# v0.4 确认和验证是否实际目标可以写成伪目标, 答案是不能(会失去文件自动检测编译的功能,导致全部编译)
# v0.3 声明伪目标, 加入编译目标 rebuild
# v0.2 加入编译目标的依赖,提高编译效率
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
# 如果多个编译目标的规则都相同,可以将多个目标放在一起,用空格分开
# e.g.
# obj1 obj2: main.cpp
# gcc -xx ...
# 在编译目标的gcc命令中使用的自动变量
# @$ 当前目标
# @< 依赖的第一个文件
# -o @$ @< # 要编译的文件比较多时, 可以代替硬编码
# c_file: src/*.c
# 如果编译目标指定的依赖不存在,makefile会报错
# 如果没有的实际目标,就不要留在makefile中
# 编译具体目标时, 不能写成伪目标,而是要直接写成真正要编译的.o目标,否则就不能检测依赖的文件变化了,而是每次都全部编译
ASM_FLAGS = -mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1
CPP_FLAGS = -mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x
LINK_FLAGS = -mcpu=cortex-m3 -mthumb -mthumb-interwork -nostartfiles
.PHONY: all clean rebuild
all: \
./out/arm-gcc.elf
@echo build all
rebuild:
make clean
make
clean:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
./out/startup_lpc17xx.o: src/startup_lpc17xx.s
arm-none-eabi-as \
$(ASM_FLAGS) \
-alhms=$(patsubst %.o,%.lst,$@) \
--MD $(patsubst %.o,%.d,$@) \
-o $@ $<
./out/main.o: src/main.cpp
arm-none-eabi-gcc \
-c \
$(CPP_FLAGS) \
-Wa,-alhms="$(patsubst %.o,%.lst,$@)" \
-o $@ $<
./out/arm-gcc.elf: ./src/LPC1768.ld ./out/startup_lpc17xx.o ./out/main.o
arm-none-eabi-gcc \
$(LINK_FLAGS) \
-Wl,-Map="$(patsubst %.elf,%.map,$@)" \
-T $< \
-o $@ $(filter-out $<, $^)
arm-none-eabi-objcopy -O ihex $@ $(patsubst .elf,.hex,$@)
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
makefile v0.7
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.7 在make命令中加注释,解释用到的make内置函数的功能和用法
# v0.6 用makefil自动变量优化编译命令, 使gcc命令行更灵活
# v0.5 将编译选项定义为变量
# v0.4 确认和验证是否实际目标可以写成伪目标, 答案是不能(会失去文件自动检测编译的功能,导致全部编译)
# v0.3 声明伪目标, 加入编译目标 rebuild
# v0.2 加入编译目标的依赖,提高编译效率
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
# 如果多个编译目标的规则都相同,可以将多个目标放在一起,用空格分开
# e.g.
# obj1 obj2: main.cpp
# gcc -xx ...
# 在编译目标的gcc命令中使用的自动变量
# @$ 当前目标
# @< 依赖的第一个文件
# -o @$ @< # 要编译的文件比较多时, 可以代替硬编码
# c_file: src/*.c
# 如果编译目标指定的依赖不存在,makefile会报错
# 如果没有的实际目标,就不要留在makefile中
# 编译具体目标时, 不能写成伪目标,而是要直接写成真正要编译的.o目标,否则就不能检测依赖的文件变化了,而是每次都全部编译
ASM_FLAGS = -mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1
CPP_FLAGS = -mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x
LINK_FLAGS = -mcpu=cortex-m3 -mthumb -mthumb-interwork -nostartfiles
.PHONY: all clean rebuild
all: \
./out/arm-gcc.elf
# 在make目标中, 可以加注释, 但是注释必须顶着行头写
@echo build all
rebuild:
make clean
make
clean:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
./out/startup_lpc17xx.o: src/startup_lpc17xx.s
# patsubst 是make内置函数, 格式 patsubst %1,%2,%3
# 作用 : 将%3的内容中的%1字符串换为%2字符串
arm-none-eabi-as \
$(ASM_FLAGS) \
-alhms=$(patsubst %.o,%.lst,$@) \
--MD $(patsubst %.o,%.d,$@) \
-o $@ $<
# $@ 是编译目标的名字
# $< 是依赖的第一个内容
./out/main.o: src/main.cpp
arm-none-eabi-gcc \
-c \
$(CPP_FLAGS) \
-Wa,-alhms="$(patsubst %.o,%.lst,$@)" \
-o $@ $<
./out/arm-gcc.elf: ./src/LPC1768.ld ./out/startup_lpc17xx.o ./out/main.o
arm-none-eabi-gcc \
$(LINK_FLAGS) \
-Wl,-Map="$(patsubst %.elf,%.map,$@)" \
-T $< \
-o $@ $(filter-out $<, $^)
# filter-out %1,%2
# filter-out 是将%2中的%1去掉
arm-none-eabi-objcopy -O ihex $@ $(patsubst .elf,.hex,$@)
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
makefile v0.8
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.8 用通配符来简化文件的编译(不用写具体的目标文件和依赖文件的名字了),这样对于大工程,makefile就不用写的很复杂
# v0.7 在make命令中加注释,解释用到的make内置函数的功能和用法
# v0.6 用makefil自动变量优化编译命令, 使gcc命令行更灵活
# v0.5 将编译选项定义为变量
# v0.4 确认和验证是否实际目标可以写成伪目标, 答案是不能(会失去文件自动检测编译的功能,导致全部编译)
# v0.3 声明伪目标, 加入编译目标 rebuild
# v0.2 加入编译目标的依赖,提高编译效率
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
# 如果多个编译目标的规则都相同,可以将多个目标放在一起,用空格分开
# e.g.
# obj1 obj2: main.cpp
# gcc -xx ...
# 在编译目标的gcc命令中使用的自动变量
# @$ 当前目标
# @< 依赖的第一个文件
# -o @$ @< # 要编译的文件比较多时, 可以代替硬编码
# c_file: src/*.c
# 如果编译目标指定的依赖不存在,makefile会报错
# 如果没有的实际目标,就不要留在makefile中
# 编译具体目标时, 不能写成伪目标,而是要直接写成真正要编译的.o目标,否则就不能检测依赖的文件变化了,而是每次都全部编译
ASM_FLAGS = -mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1
CPP_FLAGS = -mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x
LINK_FLAGS = -mcpu=cortex-m3 -mthumb -mthumb-interwork -nostartfiles
.PHONY: all clean rebuild
all: \
./out/arm-gcc.elf
# 在make目标中, 可以加注释, 但是注释必须顶着行头写
@echo build all
rebuild:
make clean
make
clean:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
./out/startup_lpc17xx.o: src/startup_lpc17xx.s
# patsubst 是make内置函数, 格式 patsubst %1,%2,%3
# 作用 : 将%3的内容中的%1字符串换为%2字符串
arm-none-eabi-as \
$(ASM_FLAGS) \
-alhms=$(patsubst %.o,%.lst,$@) \
--MD $(patsubst %.o,%.d,$@) \
-o $@ $<
# $@ 是编译目标的名字
# $< 是依赖的第一个内容
# 如果要使用通配符, 估计得将.o生成到不同输出目录才行,否则命令目标有冲突
# e.g. *.cpp 生成到 out/cpp, *.c 生成到out/c
./out/%.o: src/%.cpp
arm-none-eabi-gcc \
-c \
$(CPP_FLAGS) \
-Wa,-alhms="$(patsubst %.o,%.lst,$@)" \
-o $@ $<
./out/arm-gcc.elf: ./src/LPC1768.ld ./out/startup_lpc17xx.o ./out/main.o
arm-none-eabi-gcc \
$(LINK_FLAGS) \
-Wl,-Map="$(patsubst %.elf,%.map,$@)" \
-T $< \
-o $@ $(filter-out $<, $^)
# filter-out %1,%2
# filter-out 是将%2中的%1去掉
arm-none-eabi-objcopy -O ihex $@ $(patsubst .elf,.hex,$@)
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
makefile v0.9
arm-none-eabi-objcopy 语句的字符替换手误,修正了。
bash
# @file makefile
# @brief 从build.bat进化出来的makefile
# v0.9 在每个gcc命令之间加分隔行(容易看清楚每个命令的区间)
# v0.8 用通配符来简化文件的编译(不用写具体的目标文件和依赖文件的名字了),这样对于大工程,makefile就不用写的很复杂
# v0.7 在make命令中加注释,解释用到的make内置函数的功能和用法
# v0.6 用makefil自动变量优化编译命令, 使gcc命令行更灵活
# v0.5 将编译选项定义为变量
# v0.4 确认和验证是否实际目标可以写成伪目标, 答案是不能(会失去文件自动检测编译的功能,导致全部编译)
# v0.3 声明伪目标, 加入编译目标 rebuild
# v0.2 加入编译目标的依赖,提高编译效率
# v0.1 最简单的makefile, 从.bat直接改过来
# makefile_obj : depend(可选)
# action
# makefile_obj从行首开始
# action必须从TAB键开始
# 命令之前加@, 就关掉了echo回显
# 如果多个编译目标的规则都相同,可以将多个目标放在一起,用空格分开
# e.g.
# obj1 obj2: main.cpp
# gcc -xx ...
# 在编译目标的gcc命令中使用的自动变量
# @$ 当前目标
# @< 依赖的第一个文件
# -o @$ @< # 要编译的文件比较多时, 可以代替硬编码
# c_file: src/*.c
# 如果编译目标指定的依赖不存在,makefile会报错
# 如果没有的实际目标,就不要留在makefile中
# 编译具体目标时, 不能写成伪目标,而是要直接写成真正要编译的.o目标,否则就不能检测依赖的文件变化了,而是每次都全部编译
ASM_FLAGS = -mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
--defsym __UVISION_VERSION=543 \
--defsym __GCC=1 \
--defsym __GCC_VERSION=1431 \
--defsym LPC175x_6x=1
CPP_FLAGS = -mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" \
-I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" \
-D__UVISION_VERSION="543" \
-D__GCC -D__GCC_VERSION="1431" \
-DLPC175x_6x
LINK_FLAGS = -mcpu=cortex-m3 -mthumb -mthumb-interwork -nostartfiles
.PHONY: all clean rebuild
all: \
./out/arm-gcc.elf
# 在make目标中, 可以加注释, 但是注释必须顶着行头写
@echo build all
rebuild:
make clean
make
clean:
@cls
@if not exist ".\out" mkdir ".\out"
@if exist ".\out\*" del /q ".\out\*"
@echo ----------------------------------------
@echo before build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
./out/startup_lpc17xx.o: src/startup_lpc17xx.s
# patsubst 是make内置函数, 格式 patsubst %1,%2,%3
# 作用 : 将%3的内容中的%1字符串换为%2字符串
arm-none-eabi-as \
$(ASM_FLAGS) \
-alhms=$(patsubst %.o,%.lst,$@) \
--MD $(patsubst %.o,%.d,$@) \
-o $@ $<
@echo ----------
# $@ 是编译目标的名字
# $< 是依赖的第一个内容
# 如果要使用通配符, 估计得将.o生成到不同输出目录才行,否则命令目标有冲突
# e.g. *.cpp 生成到 out/cpp, *.c 生成到out/c
./out/%.o: src/%.cpp
arm-none-eabi-gcc \
-c \
$(CPP_FLAGS) \
-Wa,-alhms="$(patsubst %.o,%.lst,$@)" \
-o $@ $<
@echo ----------
./out/arm-gcc.elf: ./src/LPC1768.ld ./out/startup_lpc17xx.o ./out/main.o
arm-none-eabi-gcc \
$(LINK_FLAGS) \
-Wl,-Map="$(patsubst %.elf,%.map,$@)" \
-T $< \
-o $@ $(filter-out $<, $^)
@echo ----------
# filter-out %1,%2
# filter-out 是将%2中的%1去掉
arm-none-eabi-objcopy -O ihex $@ $(patsubst %.elf,%.hex,$@)
@echo ----------
@echo ----------------------------------------
@echo after build
@echo ----------------------------------------
@dir /s /b /oneg
@echo ----------------------------------------
最终编译效果
bash
----------------------------------------
before build
----------------------------------------
D:\my_dev\my_test\arm-gcc-makefile\v0.8\doc
D:\my_dev\my_test\arm-gcc-makefile\v0.8\makefile
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src
D:\my_dev\my_test\arm-gcc-makefile\v0.8\doc\build.bat
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src\LPC1768.ld
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src\main.cpp
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src\startup_LPC17xx.s
----------------------------------------
make[1]: Leaving directory `D:/my_dev/my_test/arm-gcc-makefile/v0.8'
make
make[1]: Entering directory `D:/my_dev/my_test/arm-gcc-makefile/v0.8'
arm-none-eabi-as \
-mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" --defsym __UVISION_VERSION=543 --defsym __GCC=1 --defsym __GCC_VERSION=1431 --defsym LPC175x_6x=1 \
-alhms=out/startup_lpc17xx.lst \
--MD out/startup_lpc17xx.d \
-o out/startup_lpc17xx.o src/startup_lpc17xx.s
----------
arm-none-eabi-gcc \
-c \
-mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" -D__UVISION_VERSION="543" -D__GCC -D__GCC_VERSION="1431" -DLPC175x_6x \
-Wa,-alhms="out/main.lst" \
-o out/main.o src/main.cpp
----------
arm-none-eabi-gcc \
-mcpu=cortex-m3 -mthumb -mthumb-interwork -nostartfiles \
-Wl,-Map="out/arm-gcc.map" \
-T src/LPC1768.ld \
-o out/arm-gcc.elf out/startup_lpc17xx.o out/main.o
----------
arm-none-eabi-objcopy -O ihex out/arm-gcc.elf out/arm-gcc.elf
----------
----------------------------------------
after build
----------------------------------------
D:\my_dev\my_test\arm-gcc-makefile\v0.8\doc
D:\my_dev\my_test\arm-gcc-makefile\v0.8\makefile
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src
D:\my_dev\my_test\arm-gcc-makefile\v0.8\doc\build.bat
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\arm-gcc.elf
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\arm-gcc.map
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\main.d
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\main.lst
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\main.o
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\startup_lpc17xx.d
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\startup_lpc17xx.lst
D:\my_dev\my_test\arm-gcc-makefile\v0.8\out\startup_lpc17xx.o
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src\LPC1768.ld
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src\main.cpp
D:\my_dev\my_test\arm-gcc-makefile\v0.8\src\startup_LPC17xx.s
----------------------------------------
build all
make[1]: Leaving directory `D:/my_dev/my_test/arm-gcc-makefile/v0.8'
D:\my_dev\my_test\arm-gcc-makefile\v0.8>
备注
如果是一个复杂点的工程,可能需要多个.mk才方便编译。
可以用make -c 去到一个子目录中(那里有子模块的.mk), 编译完sub.mk, 再回到主make中。
逐个子模块的.mk都编译完。再执行link.
可以参考开源工程(e.g. Smoothieware)
备注
gnu官方的make手册(https://www.gnu.org/software/make/manual/), 有makefile编写的细节问题,可以去看下。
备注
makefile命令行写的灵活一些,方便扩展到其他工程用,不过也别太过了,毕竟不是经常玩makefile.
makefile优化差不多就行,免得自己以后(e.g. 1年以后?)看时,看不懂就坏了。