import os from re import split import subprocess def getCfFileId(std: str): return "08" if std == "08" else "93" ## Weird behaviour from GHDL, but all vhdl versions besides 08 have [...]93.cf def ghdlEnvExists(std, relativePath="work"): ## Check if work exists try: os.lstat(relativePath) except: return False ## Check that work is writable if not os.access(relativePath, os.W_OK): print(f"{relativePath} is write-protected, please acquire correct permissions") return False cfFileExists = False filesInWork = os.listdir(relativePath) cfFileId = getCfFileId(std) for file in filesInWork: if ".cf" in file and cfFileId in file: cfFileExists = True if not cfFileExists: return False ## Nothing bad, continue return True def createBuildEnv(std: str): if ghdlEnvExists(std=std): print("Build environment already exists, exiting...") return -1 ## Create build env print("Initializing GHDL project in current directory...") os.makedirs("work",exist_ok=True) addAllVHDLFiles(std=std, init=True) return 0 def addAllVHDLFiles(std: str, init=False): ## Ensure everything is ready for adding files ## (init exception to avoid one if-case in ghdlEnvExists) if not ghdlEnvExists(std=std) and not init: return -1 vhdlFiles = [] currentlyAdded = [] cfFileId = getCfFileId(std) ## Find already present files if not init: cfFileName = list(filter(lambda x: ".cf" in x and cfFileId in x, os.listdir("work")))[0] cfFilePath = os.path.join(os.getcwd(),f"work/{cfFileName}") currentlyAdded = getCurrentlyAddedFiles(cfFilePath) ## Add files not added for file in os.listdir(): if ".vhd" in file and file not in currentlyAdded: vhdlFiles.append(file) if len(vhdlFiles) > 0: print(f"Detected new files. Adding {vhdlFiles}") command = ["ghdl", "-i", "--workdir=work", "--work=work", f"--std={std}"] + vhdlFiles subprocess.run(command) return 0 def getCurrentlyAddedFiles(cfFilePath:str): f = open(cfFilePath,"r") lines = f.readlines() f.close() fileLines = filter(lambda x: "file" in x, lines) files = map(lambda x: split("\" \"",x)[1], fileLines) return list(files)