2024-04-18 21:28:43 +08:00
|
|
|
|
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
修改编译脚本之后需要全编译一次
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# CC = 'gcc'
|
|
|
|
|
CC = 'arm-none-eabi-gcc'
|
|
|
|
|
|
|
|
|
|
AS = CC + ' -x assembler-with-cpp'
|
|
|
|
|
|
|
|
|
|
HEX = 'arm-none-eabi-objcopy' + ' -O ihex'
|
|
|
|
|
BIN = 'arm-none-eabi-objcopy' + ' -O binary -S'
|
2024-04-19 18:56:55 +08:00
|
|
|
|
OD = 'arm-none-eabi-objdump' + ' -dS'
|
2024-04-18 21:28:43 +08:00
|
|
|
|
|
|
|
|
|
CSRC = []
|
|
|
|
|
|
|
|
|
|
CINC = [
|
|
|
|
|
'-Isource/cmsis',
|
|
|
|
|
'-Isource/core',
|
|
|
|
|
'-Isource/stm32lib/inc'
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
CDEF = [
|
|
|
|
|
"-DSTM32F429_439xx"
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
ASRC = []
|
|
|
|
|
|
|
|
|
|
BUILD_DIR = 'build'
|
|
|
|
|
|
|
|
|
|
TARGET = 'hello'
|
|
|
|
|
|
|
|
|
|
CFLAG = [
|
2024-04-19 18:56:55 +08:00
|
|
|
|
"-Wall -pedantic -mcpu=cortex-m4 -mthumb -lc -lm -lnosys -Og",
|
|
|
|
|
"-pie",
|
|
|
|
|
# "-fPIC",
|
|
|
|
|
# "-fPIE",
|
|
|
|
|
"-msingle-pic-base",
|
|
|
|
|
"-specs=nano.specs",
|
|
|
|
|
# "-nostdlib -emain",
|
|
|
|
|
"",
|
|
|
|
|
"-Tstm32_app.ld",
|
2024-04-18 21:28:43 +08:00
|
|
|
|
f"-Wl,-Map={BUILD_DIR}/{TARGET}.map,--cref -Wl,--gc-sections"
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 找到指定后缀的文件
|
|
|
|
|
def find_type(path:str,fix:list[str]):
|
|
|
|
|
dlist=os.listdir(path)
|
|
|
|
|
file_list=[]
|
|
|
|
|
for i in dlist:
|
|
|
|
|
ps=os.path.join(path, i)
|
|
|
|
|
if os.path.isdir(ps):
|
|
|
|
|
file_list+=find_type(ps,fix)
|
|
|
|
|
else:
|
|
|
|
|
suf=ps.split('.')[-1]
|
|
|
|
|
if(suf in fix):
|
|
|
|
|
file_list.append(ps)
|
|
|
|
|
return file_list
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
将.c编译为.o文件,
|
|
|
|
|
编译脚本需要实现 如果.c文件有修改 则重新编译对应文件的.o文件
|
|
|
|
|
gcc -c test.c -o test.o
|
|
|
|
|
|
|
|
|
|
输出依赖关系到.d文件
|
|
|
|
|
gcc -MM main.c -o build/main.d
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def tran_path(path:str):
|
|
|
|
|
p=path.replace('\\','/')
|
|
|
|
|
p=p.replace('/','_')
|
|
|
|
|
if(p[0]=='.'):
|
|
|
|
|
return p[1:]
|
|
|
|
|
else:
|
|
|
|
|
return p
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 判断是否需要重新生成
|
|
|
|
|
def check_rebuild(dst:str,src:list[str]):
|
|
|
|
|
if(not os.path.exists(dst)):
|
|
|
|
|
return True
|
|
|
|
|
dst_time=os.path.getmtime(dst)
|
|
|
|
|
src_time=[]
|
|
|
|
|
for i in src:
|
|
|
|
|
src_time.append(os.path.getmtime(i))
|
|
|
|
|
src_time.sort()
|
|
|
|
|
if(src_time[-1]>dst_time):
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 读取.d文件,返回依赖文件列表
|
|
|
|
|
def read_depend_files(name:str):
|
|
|
|
|
with open(name) as f:
|
|
|
|
|
t=f.readline()
|
|
|
|
|
t=t.split(':')[-1].strip()
|
|
|
|
|
t=t.split(' ')
|
|
|
|
|
# print(f"依赖列表{t}")
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 生成依赖关系
|
|
|
|
|
def build_depend(src:list[str]):
|
|
|
|
|
flags=f"{' '.join(CINC)} {' '.join(CDEF)} {' '.join(CFLAG)}"
|
|
|
|
|
for i in src:
|
|
|
|
|
name=tran_path(i).split('.')[0]
|
|
|
|
|
dst='.'.join([name,'d'])
|
|
|
|
|
dst=os.path.join(BUILD_DIR,dst)
|
|
|
|
|
if(check_rebuild(dst,[i])):
|
|
|
|
|
cmd=f"{CC} -MM {i} -o {dst} {flags}"
|
|
|
|
|
print(cmd)
|
|
|
|
|
ret=os.system(cmd)
|
|
|
|
|
if(ret):
|
|
|
|
|
exit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 生成中间文件
|
|
|
|
|
def build_object(src:list[str]):
|
|
|
|
|
flags=f"{' '.join(CINC)} {' '.join(CDEF)} {' '.join(CFLAG)}"
|
|
|
|
|
for i in src:
|
|
|
|
|
name_l=tran_path(i).split('.')
|
|
|
|
|
name=name_l[0]
|
|
|
|
|
file_type=name_l[-1]
|
|
|
|
|
dst='.'.join([name,'o'])
|
|
|
|
|
dst=os.path.join(BUILD_DIR,dst)
|
|
|
|
|
cd='.'.join([name,'d'])
|
|
|
|
|
cmd = ''
|
|
|
|
|
if(file_type in ['c','.C']):
|
|
|
|
|
cd=os.path.join(BUILD_DIR,cd)
|
|
|
|
|
if(check_rebuild(dst,read_depend_files(cd))):
|
|
|
|
|
cmd=f"{CC} -c {i} -o {dst} {flags}"
|
|
|
|
|
elif(file_type in ['s','S','asm','ASM']):
|
|
|
|
|
if(check_rebuild(dst,[i])):
|
|
|
|
|
cmd=f"{AS} -c {i} -o {dst} {flags}"
|
|
|
|
|
if(len(cmd)>0):
|
|
|
|
|
print(cmd)
|
|
|
|
|
ret=os.system(cmd)
|
|
|
|
|
if(ret):
|
|
|
|
|
exit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 生成可执行文件
|
|
|
|
|
def build_target(src:list[str]):
|
|
|
|
|
flags=f"{' '.join(CINC)} {' '.join(CDEF)} {' '.join(CFLAG)}"
|
|
|
|
|
obj_list=[]
|
|
|
|
|
for i in src:
|
|
|
|
|
name=tran_path(i).split('.')[0]
|
|
|
|
|
obj_list.append(BUILD_DIR+'/'+'.'.join([name,'o']))
|
|
|
|
|
dst=os.path.join(BUILD_DIR,TARGET)
|
|
|
|
|
if(check_rebuild(dst,obj_list)):
|
|
|
|
|
cmd=f"{CC} {' '.join(obj_list)} -o {dst} {flags}"
|
|
|
|
|
print(cmd)
|
|
|
|
|
ret=os.system(cmd)
|
|
|
|
|
if(ret):
|
|
|
|
|
exit()
|
|
|
|
|
else:
|
|
|
|
|
print("已是最新,无需要重新生成的目标")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
global CSRC
|
|
|
|
|
global ASRC
|
2024-04-19 18:56:55 +08:00
|
|
|
|
if(os.path.exists(f"{TARGET}.s")):
|
|
|
|
|
os.remove(f"{TARGET}.s")
|
|
|
|
|
|
2024-04-18 21:28:43 +08:00
|
|
|
|
CSRC+=find_type('./',['c','C'])
|
|
|
|
|
ASRC+=find_type('./',['s','S','asm','ASM'])
|
|
|
|
|
|
|
|
|
|
if(not os.path.exists(BUILD_DIR)):
|
|
|
|
|
os.makedirs(BUILD_DIR)
|
|
|
|
|
|
|
|
|
|
print("生成依赖关系")
|
|
|
|
|
build_depend(CSRC)
|
|
|
|
|
print("生成对象文件")
|
|
|
|
|
build_object(CSRC)
|
|
|
|
|
build_object(ASRC)
|
|
|
|
|
print("生成目标文件")
|
|
|
|
|
build_target(CSRC+ASRC)
|
|
|
|
|
os.system(f"{HEX} {BUILD_DIR}/{TARGET} {BUILD_DIR}/{TARGET}.hex")
|
|
|
|
|
os.system(f"{BIN} {BUILD_DIR}/{TARGET} {BUILD_DIR}/{TARGET}.bin")
|
2024-04-19 18:56:55 +08:00
|
|
|
|
os.system(f"{OD} {BUILD_DIR}/{TARGET} > {TARGET}.s")
|
2024-04-18 21:28:43 +08:00
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|