这个脚本可以自动扫描目录下的.c和.s文件并编译,同时生成hex和bin文件
,可以代替Makefile工作。cortex-m 单片机
# -*- coding: gbk -*-import os
import sys
import time'''修改编译脚本之后需要全编译一次'''# CC = 'gcc'
CC = 'C:\\ARM_GCC\\bin\\arm-none-eabi-gcc'AS = CC + ' -x assembler-with-cpp'HEX = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O ihex'
BIN = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O binary -S'CSRC = []CINC = ['-Isoft']CDEF = ["-DTEST"]ASRC = []BUILD_DIR = 'build'TARGET = 'hello'CFLAG = ["-Wall -pedantic -specs=nano.specs -mcpu=cortex-m3 -mthumb -lc -lm -lnosys -Og -Tstm32_boot.ld",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 Truedst_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 Truereturn 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 CSRCglobal ASRCCSRC+=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")if __name__ == "__main__":main()