CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/scripts/build_binaries.py
Views: 1798
1
#!/usr/bin/env python3
2
3
"""
4
script to build the latest binaries for each vehicle type, ready to upload
5
Peter Barker, August 2017
6
based on build_binaries.sh by Andrew Tridgell, March 2013
7
8
AP_FLAKE8_CLEAN
9
"""
10
11
from __future__ import print_function
12
13
import datetime
14
import optparse
15
import os
16
import re
17
import shutil
18
import time
19
import string
20
import subprocess
21
import sys
22
import traceback
23
24
# local imports
25
import generate_manifest
26
import gen_stable
27
import build_binaries_history
28
29
import board_list
30
from board_list import AP_PERIPH_BOARDS
31
32
if sys.version_info[0] < 3:
33
running_python3 = False
34
else:
35
running_python3 = True
36
37
38
def topdir():
39
'''return path to ardupilot checkout directory. This is to cope with
40
running on developer's machines (where autotest is typically
41
invoked from the root directory), and on the autotest server where
42
it is invoked in the checkout's parent directory.
43
'''
44
for path in [
45
os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".."),
46
"",
47
]:
48
if os.path.exists(os.path.join(path, "libraries", "AP_HAL_ChibiOS")):
49
return path
50
raise Exception("Unable to find ardupilot checkout dir")
51
52
53
def is_chibios_build(board):
54
'''see if a board is using HAL_ChibiOS'''
55
# cope with both running from Tools/scripts or running from cwd
56
hwdef_dir = os.path.join(topdir(), "libraries", "AP_HAL_ChibiOS", "hwdef")
57
58
return os.path.exists(os.path.join(hwdef_dir, board, "hwdef.dat"))
59
60
61
def get_required_compiler(vehicle, tag, board):
62
'''return required compiler for a build tag.
63
return format is the version string that waf configure will detect.
64
You should setup a link from this name in $HOME/arm-gcc directory pointing at the
65
appropriate compiler
66
'''
67
if not is_chibios_build(board):
68
# only override compiler for ChibiOS builds
69
return None
70
# use 10.2.1 compiler for all other builds
71
return "g++-10.2.1"
72
73
74
class build_binaries(object):
75
def __init__(self, tags):
76
self.tags = tags
77
self.dirty = False
78
self.board_list = board_list.BoardList()
79
80
def progress(self, string):
81
'''pretty-print progress'''
82
print("BB: %s" % string)
83
84
def run_git(self, args):
85
'''run git with args git_args; returns git's output'''
86
cmd_list = ["git"]
87
cmd_list.extend(args)
88
return self.run_program("BB-GIT", cmd_list)
89
90
def board_branch_bit(self, board):
91
'''return a fragment which might modify the branch name.
92
this was previously used to have a master-AVR branch etc
93
if the board type was apm1 or apm2'''
94
return None
95
96
def board_options(self, board):
97
'''return board-specific options'''
98
if board in ["bebop", "disco"]:
99
return ["--static"]
100
return []
101
102
def run_waf(self, args, compiler=None):
103
if os.path.exists("waf"):
104
waf = "./waf"
105
else:
106
waf = os.path.join(".", "modules", "waf", "waf-light")
107
cmd_list = ["python3", waf]
108
cmd_list.extend(args)
109
env = None
110
if compiler is not None:
111
# default to $HOME/arm-gcc, but allow for any path with AP_GCC_HOME environment variable
112
gcc_home = os.environ.get("AP_GCC_HOME", os.path.join(os.environ["HOME"], "arm-gcc"))
113
gcc_path = os.path.join(gcc_home, compiler, "bin")
114
if os.path.exists(gcc_path):
115
# setup PATH to point at the right compiler, and setup to use ccache
116
env = os.environ.copy()
117
env["PATH"] = gcc_path + ":" + env["PATH"]
118
env["CC"] = "ccache arm-none-eabi-gcc"
119
env["CXX"] = "ccache arm-none-eabi-g++"
120
else:
121
raise Exception("BB-WAF: Missing compiler %s" % gcc_path)
122
self.run_program("BB-WAF", cmd_list, env=env)
123
124
def run_program(self, prefix, cmd_list, show_output=True, env=None, force_success=False):
125
if show_output:
126
self.progress("Running (%s)" % " ".join(cmd_list))
127
p = subprocess.Popen(cmd_list, stdin=None,
128
stdout=subprocess.PIPE, close_fds=True,
129
stderr=subprocess.STDOUT, env=env)
130
output = ""
131
while True:
132
x = p.stdout.readline()
133
if len(x) == 0:
134
returncode = os.waitpid(p.pid, 0)
135
if returncode:
136
break
137
# select not available on Windows... probably...
138
time.sleep(0.1)
139
continue
140
if running_python3:
141
x = bytearray(x)
142
x = filter(lambda x : chr(x) in string.printable, x)
143
x = "".join([chr(c) for c in x])
144
output += x
145
x = x.rstrip()
146
if show_output:
147
print("%s: %s" % (prefix, x))
148
(_, status) = returncode
149
if status != 0 and not force_success:
150
self.progress("Process failed (%s)" %
151
str(returncode))
152
raise subprocess.CalledProcessError(
153
returncode, cmd_list)
154
return output
155
156
def run_make(self, args):
157
cmd_list = ["make"]
158
cmd_list.extend(args)
159
self.run_program("BB-MAKE", cmd_list)
160
161
def run_git_update_submodules(self):
162
'''if submodules are present initialise and update them'''
163
if os.path.exists(os.path.join(self.basedir, ".gitmodules")):
164
self.run_git(["submodule",
165
"update",
166
"--init",
167
"--recursive",
168
"-f"])
169
170
def checkout(self, vehicle, ctag, cboard=None, cframe=None, submodule_update=True):
171
'''attempt to check out a git tree. Various permutations are
172
attempted based on ctag - for examplle, if the board is avr and ctag
173
is bob we will attempt to checkout bob-AVR'''
174
if self.dirty:
175
self.progress("Skipping checkout for dirty build")
176
return True
177
178
self.progress("Trying checkout %s %s %s %s" %
179
(vehicle, ctag, cboard, cframe))
180
self.run_git(['stash'])
181
if ctag == "latest":
182
vtag = "master"
183
else:
184
tagvehicle = vehicle
185
if tagvehicle == "Rover":
186
# FIXME: Rover tags in git still named APMrover2 :-(
187
tagvehicle = "APMrover2"
188
vtag = "%s-%s" % (tagvehicle, ctag)
189
190
branches = []
191
if cframe is not None:
192
# try frame specific tag
193
branches.append("%s-%s" % (vtag, cframe))
194
if cboard is not None:
195
bbb = self.board_branch_bit(cboard)
196
if bbb is not None:
197
# try board type specific branch extension
198
branches.append("".join([vtag, bbb]))
199
branches.append(vtag)
200
201
for branch in branches:
202
try:
203
self.progress("Trying branch %s" % branch)
204
self.run_git(["checkout", "-f", branch])
205
if submodule_update:
206
self.run_git_update_submodules()
207
self.run_git(["log", "-1"])
208
return True
209
except subprocess.CalledProcessError:
210
self.progress("Checkout branch %s failed" % branch)
211
212
self.progress("Failed to find tag for %s %s %s %s" %
213
(vehicle, ctag, cboard, cframe))
214
return False
215
216
def skip_board_waf(self, board):
217
'''check if we should skip this build because we do not support the
218
board in this release
219
'''
220
221
try:
222
out = self.run_program(
223
'waf',
224
["python3", './waf', 'configure', '--board=BOARDTEST'],
225
show_output=False,
226
force_success=True
227
)
228
lines = out.split('\n')
229
needles = ["BOARDTEST' (choose from", "BOARDTEST': choices are"]
230
for line in lines:
231
for needle in needles:
232
idx = line.find(needle)
233
if idx != -1:
234
break
235
if idx != -1:
236
line = line[idx+len(needle):-1]
237
line = line.replace("'", "")
238
line = line.replace(" ", "")
239
boards = line.split(",")
240
ret = board not in boards
241
if ret:
242
self.progress("Skipping board (%s) - not in board list" % board)
243
return ret
244
except IOError as e:
245
if e.errno != 2:
246
raise
247
248
self.progress("Skipping unsupported board %s" % (board,))
249
return True
250
251
def skip_frame(self, board, frame):
252
'''returns true if this board/frame combination should not be built'''
253
if frame == "heli":
254
if board in ["bebop", "aerofc-v1", "skyviper-v2450", "CubeSolo", "CubeGreen-solo", 'skyviper-journey']:
255
self.progress("Skipping heli build for %s" % board)
256
return True
257
return False
258
259
def first_line_of_filepath(self, filepath):
260
'''returns the first (text) line from filepath'''
261
with open(filepath) as fh:
262
line = fh.readline()
263
return line
264
265
def skip_build(self, buildtag, builddir):
266
'''check if we should skip this build because we have already built
267
this version
268
'''
269
270
if os.getenv("FORCE_BUILD", False):
271
return False
272
273
if not os.path.exists(os.path.join(self.basedir, '.gitmodules')):
274
self.progress("Skipping build without submodules")
275
return True
276
277
bname = os.path.basename(builddir)
278
ldir = os.path.join(os.path.dirname(os.path.dirname(
279
os.path.dirname(builddir))), buildtag, bname) # FIXME: WTF
280
281
oldversion_filepath = os.path.join(ldir, "git-version.txt")
282
if not os.path.exists(oldversion_filepath):
283
self.progress("%s doesn't exist - building" % oldversion_filepath)
284
return False
285
286
oldversion = self.first_line_of_filepath(oldversion_filepath)
287
newversion = self.run_git(["log", "-1"])
288
newversion = newversion.splitlines()[0]
289
oldversion = oldversion.rstrip()
290
newversion = newversion.rstrip()
291
self.progress("oldversion=%s newversion=%s" %
292
(oldversion, newversion,))
293
if oldversion == newversion:
294
self.progress("Skipping build - version match (%s)" %
295
(newversion,))
296
return True
297
298
self.progress("%s needs rebuild" % (ldir,))
299
return False
300
301
def write_string_to_filepath(self, string, filepath):
302
'''writes the entirety of string to filepath'''
303
with open(filepath, "w") as x:
304
x.write(string)
305
306
def version_h_path(self, src):
307
'''return path to version.h'''
308
if src == 'AP_Periph':
309
return os.path.join('Tools', src, "version.h")
310
return os.path.join(src, "version.h")
311
312
def addfwversion_gitversion(self, destdir, src):
313
# create git-version.txt:
314
gitlog = self.run_git(["log", "-1"])
315
gitversion_filepath = os.path.join(destdir, "git-version.txt")
316
gitversion_content = gitlog
317
versionfile = self.version_h_path(src)
318
if os.path.exists(versionfile):
319
content = self.read_string_from_filepath(versionfile)
320
match = re.search('define.THISFIRMWARE "([^"]+)"', content)
321
if match is None:
322
self.progress("Failed to retrieve THISFIRMWARE from version.h")
323
self.progress("Content: (%s)" % content)
324
self.progress("Writing version info to %s" %
325
(gitversion_filepath,))
326
gitversion_content += "\nAPMVERSION: %s\n" % (match.group(1))
327
else:
328
self.progress("%s does not exist" % versionfile)
329
330
self.write_string_to_filepath(gitversion_content, gitversion_filepath)
331
332
def addfwversion_firmwareversiontxt(self, destdir, src):
333
# create firmware-version.txt
334
versionfile = self.version_h_path(src)
335
if not os.path.exists(versionfile):
336
self.progress("%s does not exist" % (versionfile,))
337
return
338
ss = r".*define +FIRMWARE_VERSION[ ]+(?P<major>\d+)[ ]*,[ ]*" \
339
r"(?P<minor>\d+)[ ]*,[ ]*(?P<point>\d+)[ ]*,[ ]*" \
340
r"(?P<type>[A-Z_]+)[ ]*"
341
content = self.read_string_from_filepath(versionfile)
342
match = re.search(ss, content)
343
if match is None:
344
self.progress("Failed to retrieve FIRMWARE_VERSION from version.h")
345
self.progress("Content: (%s)" % content)
346
return
347
ver = "%d.%d.%d-%s\n" % (int(match.group("major")),
348
int(match.group("minor")),
349
int(match.group("point")),
350
match.group("type"))
351
firmware_version_filepath = "firmware-version.txt"
352
self.progress("Writing version (%s) to %s" %
353
(ver, firmware_version_filepath,))
354
self.write_string_to_filepath(
355
ver, os.path.join(destdir, firmware_version_filepath))
356
357
def addfwversion(self, destdir, src):
358
'''write version information into destdir'''
359
self.addfwversion_gitversion(destdir, src)
360
self.addfwversion_firmwareversiontxt(destdir, src)
361
362
def read_string_from_filepath(self, filepath):
363
'''returns content of filepath as a string'''
364
with open(filepath, 'rb') as fh:
365
content = fh.read()
366
367
if running_python3:
368
return content.decode('ascii')
369
370
return content
371
372
def string_in_filepath(self, string, filepath):
373
'''returns true if string exists in the contents of filepath'''
374
return string in self.read_string_from_filepath(filepath)
375
376
def mkpath(self, path):
377
'''make directory path and all elements leading to it'''
378
'''distutils.dir_util.mkpath was playing up'''
379
try:
380
os.makedirs(path)
381
except OSError as e:
382
if e.errno != 17: # EEXIST
383
raise e
384
385
def touch_filepath(self, filepath):
386
'''creates a file at filepath, or updates the timestamp on filepath'''
387
if os.path.exists(filepath):
388
os.utime(filepath, None)
389
else:
390
with open(filepath, "a"):
391
pass
392
393
def build_vehicle(self, tag, vehicle, boards, vehicle_binaries_subdir,
394
binaryname, frames=[None]):
395
'''build vehicle binaries'''
396
self.progress("Building %s %s binaries (cwd=%s)" %
397
(vehicle, tag, os.getcwd()))
398
399
board_count = len(boards)
400
count = 0
401
for board in sorted(boards, key=str.lower):
402
now = datetime.datetime.now()
403
count += 1
404
self.progress("[%u/%u] Building board: %s at %s" %
405
(count, board_count, board, str(now)))
406
for frame in frames:
407
if frame is not None:
408
self.progress("Considering frame %s for board %s" %
409
(frame, board))
410
if frame is None:
411
framesuffix = ""
412
else:
413
framesuffix = "-%s" % frame
414
if not self.checkout(vehicle, tag, board, frame, submodule_update=False):
415
msg = ("Failed checkout of %s %s %s %s" %
416
(vehicle, board, tag, frame,))
417
self.progress(msg)
418
self.error_strings.append(msg)
419
continue
420
421
self.progress("Building %s %s %s binaries %s" %
422
(vehicle, tag, board, frame))
423
ddir = os.path.join(self.binaries,
424
vehicle_binaries_subdir,
425
self.hdate_ym,
426
self.hdate_ymdhm,
427
"".join([board, framesuffix]))
428
if self.skip_build(tag, ddir):
429
continue
430
if self.skip_frame(board, frame):
431
continue
432
433
# we do the submodule update after the skip_board_waf check to avoid doing it on
434
# builds we will not be running
435
self.run_git_update_submodules()
436
437
if self.skip_board_waf(board):
438
continue
439
440
if os.path.exists(self.buildroot):
441
shutil.rmtree(self.buildroot)
442
443
self.remove_tmpdir()
444
445
githash = self.run_git(["rev-parse", "HEAD"]).rstrip()
446
447
t0 = time.time()
448
449
self.progress("Configuring for %s in %s" %
450
(board, self.buildroot))
451
try:
452
waf_opts = ["configure",
453
"--board", board,
454
"--out", self.buildroot,
455
"clean"]
456
gccstring = get_required_compiler(vehicle, tag, board)
457
if gccstring is not None and gccstring.find("g++-6.3") == -1:
458
# versions using the old compiler don't have the --assert-cc-version option
459
waf_opts += ["--assert-cc-version", gccstring]
460
461
waf_opts.extend(self.board_options(board))
462
self.run_waf(waf_opts, compiler=gccstring)
463
except subprocess.CalledProcessError:
464
self.progress("waf configure failed")
465
continue
466
467
time_taken_to_configure = time.time() - t0
468
469
try:
470
target = os.path.join("bin",
471
"".join([binaryname, framesuffix]))
472
self.run_waf(["build", "--targets", target], compiler=gccstring)
473
except subprocess.CalledProcessError:
474
msg = ("Failed build of %s %s%s %s" %
475
(vehicle, board, framesuffix, tag))
476
self.progress(msg)
477
self.error_strings.append(msg)
478
# record some history about this build
479
t1 = time.time()
480
time_taken_to_build = t1-t0
481
self.history.record_build(githash, tag, vehicle, board, frame, None, t0, time_taken_to_build)
482
continue
483
484
time_taken_to_build = (time.time()-t0) - time_taken_to_configure
485
486
time_taken = time.time()-t0
487
self.progress("Making %s %s %s %s took %u seconds (configure=%u build=%u)" %
488
(vehicle, tag, board, frame, time_taken, time_taken_to_configure, time_taken_to_build))
489
490
bare_path = os.path.join(self.buildroot,
491
board,
492
"bin",
493
"".join([binaryname, framesuffix]))
494
files_to_copy = []
495
extensions = [".apj", ".abin", "_with_bl.hex", ".hex"]
496
if vehicle == 'AP_Periph' or board == "Here4FC":
497
# need bin file for uavcan-gui-tool and MissionPlanner
498
extensions.append('.bin')
499
for extension in extensions:
500
filepath = "".join([bare_path, extension])
501
if os.path.exists(filepath):
502
files_to_copy.append((filepath, os.path.basename(filepath)))
503
if not os.path.exists(bare_path):
504
raise Exception("No elf file?!")
505
506
# attempt to run an extract_features.py to create features.txt:
507
features_text = None
508
ef_path = os.path.join(topdir(), "Tools", "scripts", "extract_features.py")
509
if os.path.exists(ef_path):
510
try:
511
features_text = self.run_program("EF", [ef_path, bare_path], show_output=False)
512
except Exception as e:
513
self.print_exception_caught(e)
514
self.progress("Failed to extract features")
515
pass
516
else:
517
self.progress("Not extracting features as (%s) does not exist" % (ef_path,))
518
519
# only rename the elf if we have have other files to
520
# copy. So linux gets "arducopter" and stm32 gets
521
# "arducopter.elf"
522
target_elf_filename = os.path.basename(bare_path)
523
if len(files_to_copy) > 0:
524
target_elf_filename += ".elf"
525
files_to_copy.append((bare_path, target_elf_filename))
526
527
for (path, target_filename) in files_to_copy:
528
try:
529
'''copy path into various places, adding metadata'''
530
bname = os.path.basename(ddir)
531
tdir = os.path.join(os.path.dirname(os.path.dirname(
532
os.path.dirname(ddir))), tag, bname)
533
if tag == "latest":
534
# we keep a permanent archive of all
535
# "latest" builds, their path including a
536
# build timestamp:
537
if not os.path.exists(ddir):
538
self.mkpath(ddir)
539
self.addfwversion(ddir, vehicle)
540
features_filepath = os.path.join(ddir, "features.txt",)
541
if features_text is not None:
542
self.progress("Writing (%s)" % features_filepath)
543
self.write_string_to_filepath(features_text, features_filepath)
544
self.progress("Copying %s to %s" % (path, ddir,))
545
shutil.copy(path, os.path.join(ddir, target_filename))
546
# the most recent build of every tag is kept around:
547
self.progress("Copying %s to %s" % (path, tdir))
548
if not os.path.exists(tdir):
549
self.mkpath(tdir)
550
# must addfwversion even if path already
551
# exists as we re-use the "beta" directories
552
self.addfwversion(tdir, vehicle)
553
features_filepath = os.path.join(tdir, "features.txt")
554
if features_text is not None:
555
self.progress("Writing (%s)" % features_filepath)
556
self.write_string_to_filepath(features_text, features_filepath)
557
shutil.copy(path, os.path.join(tdir, target_filename))
558
except Exception as e:
559
self.print_exception_caught(e)
560
self.progress("Failed to copy %s to %s: %s" % (path, tdir, str(e)))
561
# why is touching this important? -pb20170816
562
self.touch_filepath(os.path.join(self.binaries,
563
vehicle_binaries_subdir, tag))
564
565
# record some history about this build
566
self.history.record_build(githash, tag, vehicle, board, frame, bare_path, t0, time_taken_to_build)
567
568
self.checkout(vehicle, "latest")
569
570
def _get_exception_stacktrace(self, e):
571
if sys.version_info[0] >= 3:
572
ret = "%s\n" % e
573
ret += ''.join(traceback.format_exception(type(e),
574
e,
575
tb=e.__traceback__))
576
return ret
577
578
# Python2:
579
return traceback.format_exc(e)
580
581
def get_exception_stacktrace(self, e):
582
try:
583
return self._get_exception_stacktrace(e)
584
except Exception:
585
return "FAILED TO GET EXCEPTION STACKTRACE"
586
587
def print_exception_caught(self, e, send_statustext=True):
588
self.progress("Exception caught: %s" %
589
self.get_exception_stacktrace(e))
590
591
def AP_Periph_boards(self):
592
return AP_PERIPH_BOARDS
593
594
def build_arducopter(self, tag):
595
'''build Copter binaries'''
596
597
boards = []
598
boards.extend(["aerofc-v1", "bebop"])
599
boards.extend(self.board_list.find_autobuild_boards('Copter'))
600
self.build_vehicle(tag,
601
"ArduCopter",
602
boards,
603
"Copter",
604
"arducopter",
605
frames=[None, "heli"])
606
607
def build_arduplane(self, tag):
608
'''build Plane binaries'''
609
boards = self.board_list.find_autobuild_boards('Plane')[:]
610
boards.append("disco")
611
self.build_vehicle(tag,
612
"ArduPlane",
613
boards,
614
"Plane",
615
"arduplane")
616
617
def build_antennatracker(self, tag):
618
'''build Tracker binaries'''
619
self.build_vehicle(tag,
620
"AntennaTracker",
621
self.board_list.find_autobuild_boards('Tracker')[:],
622
"AntennaTracker",
623
"antennatracker")
624
625
def build_rover(self, tag):
626
'''build Rover binaries'''
627
self.build_vehicle(tag,
628
"Rover",
629
self.board_list.find_autobuild_boards('Rover')[:],
630
"Rover",
631
"ardurover")
632
633
def build_ardusub(self, tag):
634
'''build Sub binaries'''
635
self.build_vehicle(tag,
636
"ArduSub",
637
self.board_list.find_autobuild_boards('Sub')[:],
638
"Sub",
639
"ardusub")
640
641
def build_AP_Periph(self, tag):
642
'''build AP_Periph binaries'''
643
boards = self.AP_Periph_boards()
644
self.build_vehicle(tag,
645
"AP_Periph",
646
boards,
647
"AP_Periph",
648
"AP_Periph")
649
650
def build_blimp(self, tag):
651
'''build Blimp binaries'''
652
self.build_vehicle(tag,
653
"Blimp",
654
self.board_list.find_autobuild_boards('Blimp')[:],
655
"Blimp",
656
"blimp")
657
658
def generate_manifest(self):
659
'''generate manigest files for GCS to download'''
660
self.progress("Generating manifest")
661
base_url = 'https://firmware.ardupilot.org'
662
generator = generate_manifest.ManifestGenerator(self.binaries,
663
base_url)
664
generator.run()
665
666
generator.write_manifest_json(os.path.join(self.binaries, "manifest.json"))
667
generator.write_features_json(os.path.join(self.binaries, "features.json"))
668
self.progress("Manifest generation successful")
669
670
self.progress("Generating stable releases")
671
gen_stable.make_all_stable(self.binaries)
672
self.progress("Generate stable releases done")
673
674
def validate(self):
675
'''run pre-run validation checks'''
676
if "dirty" in self.tags:
677
if len(self.tags) > 1:
678
raise ValueError("dirty must be only tag if present (%s)" %
679
(str(self.tags)))
680
self.dirty = True
681
682
def remove_tmpdir(self):
683
if os.path.exists(self.tmpdir):
684
self.progress("Removing (%s)" % (self.tmpdir,))
685
shutil.rmtree(self.tmpdir)
686
687
def buildlogs_dirpath(self):
688
return os.getenv("BUILDLOGS",
689
os.path.join(os.getcwd(), "..", "buildlogs"))
690
691
def run(self):
692
self.validate()
693
694
self.mkpath(self.buildlogs_dirpath())
695
696
binaries_history_filepath = os.path.join(
697
self.buildlogs_dirpath(), "build_binaries_history.sqlite")
698
self.history = build_binaries_history.BuildBinariesHistory(binaries_history_filepath)
699
700
prefix_bin_dirpath = os.path.join(os.environ.get('HOME'),
701
"prefix", "bin")
702
origin_env_path = os.environ.get("PATH")
703
os.environ["PATH"] = ':'.join([prefix_bin_dirpath, origin_env_path,
704
"/bin", "/usr/bin"])
705
if 'BUILD_BINARIES_PATH' in os.environ:
706
self.tmpdir = os.environ['BUILD_BINARIES_PATH']
707
else:
708
self.tmpdir = os.path.join(os.getcwd(), 'build.tmp.binaries')
709
os.environ["TMPDIR"] = self.tmpdir
710
711
print(self.tmpdir)
712
self.remove_tmpdir()
713
714
self.progress("Building in %s" % self.tmpdir)
715
716
now = datetime.datetime.now()
717
self.progress(now)
718
719
if not self.dirty:
720
self.run_git(["checkout", "-f", "master"])
721
githash = self.run_git(["rev-parse", "HEAD"])
722
githash = githash.rstrip()
723
self.progress("git hash: %s" % str(githash))
724
725
self.hdate_ym = now.strftime("%Y-%m")
726
self.hdate_ymdhm = now.strftime("%Y-%m-%d-%H:%m")
727
728
self.mkpath(os.path.join("binaries", self.hdate_ym,
729
self.hdate_ymdhm))
730
self.binaries = os.path.join(self.buildlogs_dirpath(), "binaries")
731
self.basedir = os.getcwd()
732
self.error_strings = []
733
734
if not self.dirty:
735
self.run_git_update_submodules()
736
self.buildroot = os.path.join(os.environ.get("TMPDIR"),
737
"binaries.build")
738
739
for tag in self.tags:
740
t0 = time.time()
741
self.build_arducopter(tag)
742
self.build_arduplane(tag)
743
self.build_rover(tag)
744
self.build_antennatracker(tag)
745
self.build_ardusub(tag)
746
self.build_AP_Periph(tag)
747
self.build_blimp(tag)
748
self.history.record_run(githash, tag, t0, time.time()-t0)
749
750
if os.path.exists(self.tmpdir):
751
shutil.rmtree(self.tmpdir)
752
753
self.generate_manifest()
754
755
for error_string in self.error_strings:
756
self.progress("%s" % error_string)
757
sys.exit(len(self.error_strings))
758
759
760
if __name__ == '__main__':
761
parser = optparse.OptionParser("build_binaries.py")
762
763
parser.add_option("", "--tags", action="append", type="string",
764
default=[], help="tags to build")
765
cmd_opts, cmd_args = parser.parse_args()
766
767
tags = cmd_opts.tags
768
if len(tags) == 0:
769
# FIXME: wedge this defaulting into parser somehow
770
tags = ["stable", "beta-4.3", "beta", "latest"]
771
772
bb = build_binaries(tags)
773
bb.run()
774
775