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