import os import sys import time import shutil CC="riscv64-unknown-elf-gcc" OBJCPY="riscv64-unknown-elf-objcopy" OBJDUMP="riscv64-unknown-elf-objdump" CFLAG=[ "-march=rv32i_zicsr", "-mabi=ilp32", "-ffunction-sections", "-fdata-sections", "-ffast-math", "-fno-common", "-fno-builtin-printf", "-Wall", "-Werror", "-g", "-O0", "-fno-omit-frame-pointer", "-msave-restore" ] DEF=[] INC=[ "-I./riscv/rtthread/libcpu/risc-v/common", "-I./riscv/rtthread/include", "-I./riscv/startup", "-I./riscv/rtthread/components/drivers/include" ] SRC=[ "riscv/startup/main.c", "riscv/startup/test.c", # "riscv/startup/interrupt.c", "riscv/startup/start.S", # "riscv/startup/trap.S", "riscv/startup/rtthread_irq.c", "riscv/rtthread/libcpu/risc-v/common/atomic_riscv.c", "riscv/rtthread/libcpu/risc-v/common/context_gcc.S", "riscv/rtthread/libcpu/risc-v/common/cpuport.c", "riscv/rtthread/libcpu/risc-v/common/interrupt_gcc.S", "riscv/rtthread/libcpu/risc-v/common/trap_common.c", "riscv/rtthread/src/clock.c", "riscv/rtthread/src/components.c", "riscv/rtthread/src/cpu.c", "riscv/rtthread/src/idle.c", "riscv/rtthread/src/ipc.c", "riscv/rtthread/src/irq.c", "riscv/rtthread/src/kservice.c", "riscv/rtthread/src/mem.c", "riscv/rtthread/src/memheap.c", "riscv/rtthread/src/mempool.c", "riscv/rtthread/src/object.c", "riscv/rtthread/src/scheduler_comm.c", # "riscv/rtthread/src/scheduler_mp.c", "riscv/rtthread/src/scheduler_up.c", "riscv/rtthread/src/signal.c", "riscv/rtthread/src/slab.c", "riscv/rtthread/src/thread.c", "riscv/rtthread/src/timer.c", "riscv/rtthread/src/klibc/kstdio.c", "riscv/rtthread/src/klibc/kstring.c", "riscv/rtthread/components/drivers/core/device.c" ] LD_FILE="riscv.ld" TARGET="riscv" OUTPUT="output" 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): # print(f"src:{src}") 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 # for item in src_time: # if(item>dst_time): # return True return False # 读取.d文件,返回依赖文件列表 def read_depend_files(name:str): with open(name) as f: lines=f.readlines() t='' for line in lines: line=line.strip() if(line[-1]=='\\'): t+=line[:-1] else: t+=line t=t.split(':')[-1].strip() t=t.split(' ') # print(f"依赖列表{t}") return t # 生成依赖关系 def build_depend(src:list): flags=f"{' '.join(INC)} {' '.join(DEF)} {' '.join(CFLAG)}" for i in src: name=tran_path(i).split('.')[0] dst='.'.join([name,'d']) dst=os.path.join(OUTPUT,dst) if(check_rebuild(dst,[i])): cmd=f"{CC} -MM {i} -o {dst} {flags}" print(f"更新 {dst}") ret=os.system(cmd) if(ret): exit() else: # print(f"{i} 没有更新源文件") pass # 生成中间文件 def build_object(src:list): flags=f"{' '.join(INC)} {' '.join(DEF)} {' '.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(OUTPUT,dst) cd='.'.join([name,'d']) cmd = '' if(file_type in ['c','.C']): cd=os.path.join(OUTPUT,cd) if(check_rebuild(dst,read_depend_files(cd))): cmd=f"{CC} -c {i} -o {dst} {flags}" else: # print(f"{i} 没有更新依赖关系") pass elif(file_type in ['s','S','asm','ASM']): if(check_rebuild(dst,[i])): cmd=f"{CC} -c {i} -o {dst} {flags}" else: # print(f"{i} 没有更新依赖关系") pass if(len(cmd)>0): print(f"编译 {dst}") ret=os.system(cmd) if(ret): exit() # 生成可执行文件 def build_target(src:list): flags=f"{' '.join(INC)} {' '.join(DEF)} {' '.join(CFLAG)}" obj_list=[] for i in src: name=tran_path(i).split('.')[0] obj_list.append(OUTPUT+'/'+'.'.join([name,'o'])) dst=os.path.join(OUTPUT,TARGET)+".elf" if(check_rebuild(dst,obj_list)): cmd=f"{CC} {' '.join(obj_list)} -o {dst} {flags} -T{LD_FILE} -Wall -Wextra -nostartfiles -Wl,-Map,\"{OUTPUT}/{TARGET}.map\"" print(f"链接 {dst}") ret=os.system(cmd) if(ret): exit() else: # print(f"{dst} 没有更新的链接文件") pass def main(): global SRC if not os.path.exists(OUTPUT): os.mkdir(OUTPUT) build_depend(SRC) build_object(SRC) build_target(SRC) os.system(f"{OBJCPY} -O binary {OUTPUT}/{TARGET}.elf {OUTPUT}/{TARGET}.bin") os.system(f"{OBJCPY} -O ihex {OUTPUT}/{TARGET}.elf {OUTPUT}/{TARGET}.hex") os.system(f"{OBJDUMP} -d {OUTPUT}/{TARGET}.elf > {OUTPUT}/{TARGET}.lst") if __name__ == "__main__": main()