-
Notifications
You must be signed in to change notification settings - Fork 4
/
_build.py
234 lines (211 loc) · 10.3 KB
/
_build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
import sys
import argparse
import os
import shutil
import glob
import subprocess
#import re
#import platform
# Run using Python 3.10 installed with the following specific packages:
# cmd
# python -m pip install --upgrade pip
# ------------------------- ENVIRONMENT CONFIGURATION -------------------------
# Environment dictionary
oEnvironmentDictionary = {}
# Reads a key/value text file describing the environment as a dictionary
def getEnvironmentDictionary(sEnvironmentFilePath):
# Open environment file
oEnvironmentFile = open(sEnvironmentFilePath, 'r')
# Create empty dictionary
oEnvironmentDictionary = {}
# Key list
lKeys = []
# Iterate environment file lines
for sLine in oEnvironmentFile:
# Split sLine into pair
lLinePair = sLine.split("=")
# Check pair
if len(lLinePair) < 2:
continue
# Strip key and value
sLineKey = lLinePair[0].strip()
sLineValue = lLinePair[1].strip()
# Add key to list
if not sLineKey in lKeys:
lKeys.append(sLineKey)
# Add to dictionary
if sLineKey in oEnvironmentDictionary:
# Store as array if defined multiple times
if isinstance(oEnvironmentDictionary[sLineKey], list):
oEnvironmentDictionary[sLineKey].append(sLineValue)
else:
oEnvironmentDictionary[sLineKey] = [oEnvironmentDictionary[sLineKey], sLineValue]
else:
oEnvironmentDictionary[sLineKey] = sLineValue
# Resolve references
for sKey1 in lKeys:
for sKey2 in lKeys:
if sKey1 == sKey2:
break
oEnvironmentDictionary[sKey1] = oEnvironmentDictionary[sKey1].replace('$' + sKey2, oEnvironmentDictionary[sKey2])
# Close environment file
oEnvironmentFile.close()
return oEnvironmentDictionary
# Retrieves a scalar value from the environment dictionary
def getEnvironmentScalar(sEntry):
global oEnvironmentDictionary
sResult = None
if sEntry in oEnvironmentDictionary:
sResult = oEnvironmentDictionary[sEntry]
if isinstance(sResult, list):
sResult = None
return sResult
# Retrieves an array value from the environment dictionary
def getEnvironmentArray(sEntry):
global oEnvironmentDictionary
lResult = []
if sEntry in oEnvironmentDictionary:
lResult = oEnvironmentDictionary[sEntry]
if not isinstance(lResult, list):
lResult = [lResult]
return lResult
# ------------------------- FILESYSTEM MANIPULATION -------------------------
# Deletes directory by name
def cmdDeleteDirectory(sName):
try:
if os.path.exists(sName):
shutil.rmtree(sName)
except:
print('ERROR: Directory {0} could not be deleted'.format(sName))
# Create directory by name
def cmdCreateDirectory(sName):
try:
os.makedirs(sName, exist_ok=True)
except:
print('ERROR: Directory {0} could not be created'.format(sName))
# Copies a file by name
def cmdCopyFile(sFrom, sTo):
try:
shutil.copyfile(sFrom, sTo)
except:
print('ERROR: File {0} could not be copied to {1}'.format(sFrom, sTo))
# Deletes files by pattern
def cmdDeleteFiles(sPattern):
lFiles = glob.glob(sPattern)
for sFilePath in lFiles:
try:
os.remove(sFilePath)
except:
print('ERROR: File {0} could not be deleted'.format(sFilePath))
# Executes a command
def cmdExecuteCommand(lCommand):
try:
mEnvironment = os.environ.copy()
for sKey in oEnvironmentDictionary:
mEnvironment[sKey] = oEnvironmentDictionary[sKey]
subprocess.run(lCommand, env=mEnvironment)
except:
raise Exception('ERROR: Error running command {0}'.format(' '.join(lCommand)))
# ------------------------- CLEAN -------------------------
# Cleaning method
def clean():
sProjectName = getEnvironmentScalar("PROJECT_NAME")
sBlockDesignName = getEnvironmentScalar("BLOCKDESIGN_NAME")
sProjectVivadoPath = getEnvironmentScalar("PROJECT_VIVADO_PATH")
sProjectSDKPath = getEnvironmentScalar("PROJECT_SDK_PATH")
print('Cleaning...')
cmdDeleteDirectory("{0}/.Xil".format(sProjectVivadoPath))
cmdDeleteDirectory("{0}/{1}.cache".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.hw".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.ip_user_files".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.runs".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sim".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.srcs".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/Packages".format(sProjectVivadoPath))
cmdDeleteFiles("{0}/{1}.xpr".format(sProjectVivadoPath, sProjectName))
cmdDeleteFiles("{0}/*.bif".format(sProjectVivadoPath))
cmdDeleteFiles("{0}/*.jou".format(sProjectVivadoPath))
cmdDeleteFiles("{0}/*.log".format(sProjectVivadoPath))
cmdDeleteDirectory("{0}/{1}.sw/.metadata".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/.sdk".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/.Xil".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/ARINC653_ARMV7A_Z7000/Debug".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/ARINC653_ARMV7A_Z7000/Release".format(sProjectVivadoPath, sProjectName))
cmdDeleteFiles("{0}/{1}.sw/ARINC653_ARMV7A_Z7000_bsp/ps7_cortexa9_0/lib/*.a".format(sProjectVivadoPath, sProjectName))
cmdDeleteFiles("{0}/{1}.sw/ARINC653_ARMV7A_Z7000_bsp/ps7_cortexa9_0/libsrc/standalone_v6_8/src/*.o".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/fsbl".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/fsbl_bsp".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/MEASURE/Debug".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/MEASURE/Release".format(sProjectVivadoPath, sProjectName))
cmdDeleteFiles("{0}/{1}.sw/MEASURE_bsp/ps7_cortexa9_0/lib/*.a".format(sProjectVivadoPath, sProjectName))
cmdDeleteFiles("{0}/{1}.sw/MEASURE_bsp/ps7_cortexa9_0/libsrc/standalone_v6_8/src/*.o".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/{2}_wrapper_hw_platform_0".format(sProjectVivadoPath, sProjectName, sBlockDesignName))
cmdDeleteDirectory("{0}/{1}.sw/RemoteSystemsTempFiles".format(sProjectVivadoPath, sProjectName))
cmdDeleteDirectory("{0}/{1}.sw/webtalk".format(sProjectVivadoPath, sProjectName))
cmdDeleteFiles("{0}/{1}.sw/*.log".format(sProjectVivadoPath, sProjectName))
cmdDeleteFiles("{0}/{1}.sw/{2}_wrapper.hdf".format(sProjectVivadoPath, sProjectName, sBlockDesignName))
# ------------------------- BUILD -------------------------
# Building method
def build():
sProjectName = getEnvironmentScalar("PROJECT_NAME")
sBlockDesignName = getEnvironmentScalar("BLOCKDESIGN_NAME")
sProjectVivadoPath = getEnvironmentScalar("PROJECT_VIVADO_PATH")
sProjectSDKPath = getEnvironmentScalar("PROJECT_SDK_PATH")
sXilinxVivadoPath = getEnvironmentScalar("XILINX_VIVADO_PATH")
sXilinxSDKPath = getEnvironmentScalar("XILINX_SDK_PATH")
sProjectFSBLPath = getEnvironmentScalar("PROJECT_FSBL_PATH")
sProjectBitstreamPath = getEnvironmentScalar("PROJECT_BITSTREAM_PATH")
sProjectBinaryPath = getEnvironmentScalar("PROJECT_BINARY_PATH")
print('Building...')
cmdExecuteCommand(['{0}/bin/vivado.bat'.format(sXilinxVivadoPath), '-mode', 'batch', '-source', '_build_01_soc_00_base.tcl'])
cmdExecuteCommand(['{0}/bin/vivado.bat'.format(sXilinxVivadoPath), '-mode', 'batch', '-source', '_build_01_soc_01_gpio.tcl'])
cmdExecuteCommand(['{0}/bin/vivado.bat'.format(sXilinxVivadoPath), '-mode', 'batch', '-source', '_build_01_soc_02_qspi.tcl'])
cmdExecuteCommand(['{0}/bin/vivado.bat'.format(sXilinxVivadoPath), '-mode', 'batch', '-source', '_build_01_soc_03_sd.tcl'])
cmdExecuteCommand(['{0}/bin/vivado.bat'.format(sXilinxVivadoPath), '-mode', 'batch', '-source', '_build_02_impl.tcl'])
cmdExecuteCommand(['{0}/bin/xsct.bat'.format(sXilinxSDKPath), '_build_03_sw.tcl'])
print("Generating boot image...")
fBootgen = open("{0}/bootgen.bif".format(sProjectVivadoPath), "w")
fBootgen.write("//arch = zynq; split = false; format = BIN\n")
fBootgen.write("the_ROM_image:\n")
fBootgen.write("{\n")
fBootgen.write("[bootloader]{0}\n".format(sProjectFSBLPath))
fBootgen.write("{0}\n".format(sProjectBitstreamPath))
fBootgen.write("{0}\n".format(sProjectBinaryPath))
fBootgen.write("}")
fBootgen.close()
cmdExecuteCommand(["{0}/bin/bootgen.bat".format(sXilinxSDKPath), "-image", "{0}/bootgen.bif".format(sProjectVivadoPath), "-arch", "zynq", "-o", "{0}/BOOT.bin".format(sProjectVivadoPath), "-w", "on"])
# ------------------------- MAIN -------------------------
# Main method
def main(argv):
global oEnvironmentDictionary
# Parse arguments
parser = argparse.ArgumentParser(description="This is a script for building the project")
parser.add_argument('--environment', '-e', default=".\\_build.env", help="Text file defining environmental information")
parser.add_argument('--clean', '-c', default=False, action='store_true', help="Clean the project")
parser.add_argument('--build', '-b', default=False, action='store_true', help="Build the project")
args = parser.parse_args()
# Check if environment file exists and it is not empty
sEnvironmentFilePath = args.environment
if os.path.exists(sEnvironmentFilePath):
if os.stat(sEnvironmentFilePath).st_size == 0:
print('ERROR: Environment file {0} is empty'.format(sEnvironmentFilePath))
return
else:
print('ERROR: Environment file {0} does not exist'.format(sEnvironmentFilePath))
return
# Read environment information
oEnvironmentDictionary = getEnvironmentDictionary(sEnvironmentFilePath)
print('INFO: Environment:')
for sEntry in oEnvironmentDictionary:
print('INFO: ' + sEntry + ' = ' + str(oEnvironmentDictionary[sEntry]))
# Handle "clean" command
if args.clean == True:
clean()
# Handle "build" command
if args.build == True:
build()
return
# Entry point
if __name__ == "__main__":
# Run main method
main(sys.argv)