Fix ar9x compile/boot (#7102)
[opentx.git] / radio / util / build-firmware.py
blob630751a64e2f961d30f6c8c3e8b8426dba420e79
1 #!/usr/bin/env python
3 from __future__ import print_function
4 import os
5 import sys
6 import subprocess
7 import shutil
8 import filelock
10 from fwoptions import *
12 # Error codes
13 FIRMWARE_SIZE_TOO_BIG = 1
14 COMPILATION_ERROR = 4
15 INVALID_FIRMWARE = 5
16 INVALID_BOARD = 6
17 INVALID_LANGUAGE = 7
20 def build_target(target, path, cmake_options):
21 srcdir = os.path.dirname(os.path.realpath(__file__)) + "/../.."
22 outpath = path + ".out"
23 errpath = path + ".err"
25 # Launch CMake
26 cmd = ["cmake"]
27 for option, value in cmake_options.items():
28 cmd.append("-D%s=%s" % (option, value))
29 if "OPENTX_VERSION_SUFFIX" in os.environ:
30 suffix = os.environ["OPENTX_VERSION_SUFFIX"]
31 cmd.append('-DVERSION_SUFFIX="%s"' % suffix)
32 if suffix.startswith("N"):
33 cmd.append('-DNIGHTLY_BUILD_WARNING=YES')
34 cmd.append(srcdir)
36 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
37 output, error = proc.communicate()
38 if proc.returncode == 0:
39 open(outpath, "a").write("\n".join(cmd) + output.decode("utf-8") + error.decode("utf-8"))
40 else:
41 open(errpath, "w").write(output.decode("utf-8") + error.decode("utf-8"))
42 return COMPILATION_ERROR
44 # Launch make
45 cmd = ["make", "-j2", target]
46 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
47 output, error = proc.communicate()
48 if proc.returncode == 0:
49 open(outpath, "a").write(output.decode("utf-8") + error.decode("utf-8"))
50 else:
51 open(errpath, "w").write(output.decode("utf-8") + error.decode("utf-8"))
52 return COMPILATION_ERROR
54 return 0
57 def main():
58 if len(sys.argv) != 3:
59 exit(INVALID_FIRMWARE)
61 target = sys.argv[1]
62 directory, filename = os.path.split(sys.argv[2])
63 root, ext = os.path.splitext(filename)
64 options = root.split("-")
66 if len(options) < 2 or options[0] != "opentx":
67 exit(INVALID_FIRMWARE)
69 optcount = 1
70 cmake_options = {}
71 board_name = options[optcount]
73 if board_name == "sky9x":
74 cmake_options["PCB"] = "SKY9X"
75 firmware_options = options_sky9x
76 maxsize = 65536 * 4
77 elif board_name == "9xrpro":
78 cmake_options["PCB"] = "9XRPRO"
79 cmake_options["SDCARD"] = "YES"
80 firmware_options = options_sky9x
81 maxsize = 65536 * 4
82 elif board_name == "ar9x":
83 cmake_options["PCB"] = "AR9X"
84 cmake_options["SDCARD"] = "YES"
85 firmware_options = options_ar9x
86 maxsize = 65536 * 4
87 elif board_name == "x9lite":
88 cmake_options["PCB"] = "X9LITE"
89 firmware_options = options_taranis_x9lite
90 maxsize = 65536 * 8
91 elif board_name == "x9lites":
92 cmake_options["PCB"] = "X9LITES"
93 firmware_options = options_taranis_x9lite
94 maxsize = 65536 * 8
95 elif options[optcount] == "x7":
96 cmake_options["PCB"] = "X7"
97 firmware_options = options_taranis_x9dp
98 maxsize = 65536 * 8
99 elif board_name == "xlite":
100 cmake_options["PCB"] = "XLITE"
101 firmware_options = options_taranis_xlite
102 maxsize = 65536 * 8
103 elif board_name == "xlites":
104 cmake_options["PCB"] = "XLITES"
105 firmware_options = options_taranis_xlites
106 maxsize = 65536 * 8
107 elif board_name == "x9d":
108 cmake_options["PCB"] = "X9D"
109 firmware_options = options_taranis_x9d
110 maxsize = 65536 * 8
111 elif board_name == "x9d+":
112 cmake_options["PCB"] = "X9D+"
113 firmware_options = options_taranis_x9dp
114 maxsize = 65536 * 8
115 elif board_name == "x9d+2019":
116 cmake_options["PCB"] = "X9D+"
117 cmake_options["PCBREV"] = "2019"
118 firmware_options = options_taranis_x9dp
119 maxsize = 65536 * 8
120 elif board_name == "x9e":
121 cmake_options["PCB"] = "X9E"
122 firmware_options = options_taranis_x9e
123 maxsize = 65536 * 8
124 elif board_name == "x10":
125 cmake_options["PCB"] = "X10"
126 firmware_options = options_horus_x10
127 maxsize = 2 * 1024 * 1024
128 elif board_name == "x10express":
129 cmake_options["PCB"] = "X10"
130 cmake_options["PCBREV"] = "EXPRESS"
131 firmware_options = options_horus_x10
132 maxsize = 2 * 1024 * 1024
133 elif board_name == "x12s":
134 cmake_options["PCB"] = "X12S"
135 firmware_options = options_horus_x12s
136 maxsize = 2 * 1024 * 1024
137 elif board_name == "t12":
138 cmake_options["PCB"] = "X7"
139 cmake_options["PCBREV"] = "T12"
140 firmware_options = options_taranis_x9dp
141 maxsize = 65536 * 8
142 elif board_name == "t16":
143 cmake_options["PCB"] = "X10"
144 cmake_options["PCBREV"] = "T16"
145 firmware_options = options_jumper_t16
146 maxsize = 2 * 1024 * 1024
147 else:
148 exit(INVALID_BOARD)
150 if target == "firmware":
151 binary = "firmware.bin"
152 ext = ".bin"
153 filename = "opentx"
154 elif target == "libsimulator":
155 binary = "libopentx-" + board_name + "-simulator.so"
156 ext = ".so"
157 filename = "libopentx"
158 else:
159 exit(INVALID_BOARD)
161 filename += "-" + board_name
162 optcount += 1
164 # The firmware options
165 for opt, values in firmware_options.items():
166 found = False
167 for i in range(optcount, len(options)):
168 if options[i] == opt:
169 found = True
170 break
172 if not isinstance(values, list):
173 values = [values]
175 for name, value1, value2 in values:
176 if found:
177 value = value1
178 filename += "-" + opt
179 else:
180 value = value2
182 if value is not None:
183 cmake_options[name] = value
185 # The firmware display language
186 language = ""
187 for key in languages:
188 if key == options[-1]:
189 language = key
190 if not language:
191 exit(INVALID_LANGUAGE)
192 cmake_options["TRANSLATIONS"] = language.upper()
194 filename += "-" + language + ext
195 path = os.path.join(directory, filename)
196 errpath = path + ".err"
198 if os.path.isfile(errpath):
199 print(filename)
200 exit(COMPILATION_ERROR)
202 if os.path.isfile(path):
203 print(filename)
204 exit(0)
206 lockpath = path + ".lock"
207 lock = filelock.FileLock(lockpath)
208 try:
209 with lock.acquire(timeout=60 * 60):
210 if not os.path.isfile(path):
211 result = build_target(target, path, cmake_options)
212 if result != 0:
213 print(filename)
214 return result
215 except filelock.Timeout:
216 print(filename)
217 exit(COMPILATION_ERROR)
219 if target == "firmware":
220 # Check binary size
221 size = os.stat(binary).st_size
222 if size > maxsize:
223 return FIRMWARE_SIZE_TOO_BIG
225 # Copy binary to the binaries directory
226 shutil.move(binary, path)
228 print(filename)
229 exit(0)
232 if __name__ == "__main__":
233 main()