128 lines
3.8 KiB
Python
128 lines
3.8 KiB
Python
import os
|
|
import re
|
|
import sys
|
|
import tempfile
|
|
import subprocess
|
|
from urllib.request import urlopen
|
|
from urllib.error import HTTPError, URLError
|
|
|
|
ARTIFACTS_URL = "http://autobuild.buildroot.net/artefacts/"
|
|
BASE_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), "../../.."))
|
|
|
|
|
|
def log_file_path(builddir, stage, logtofile=True):
|
|
"""Return path to log file"""
|
|
return "{}-{}.log".format(builddir, stage) if logtofile else None
|
|
|
|
|
|
def open_log_file(builddir, stage, logtofile=True):
|
|
"""
|
|
Open a file for logging and return its handler.
|
|
If logtofile is True, returns sys.stdout. Otherwise opens a file
|
|
with a suitable name in the build directory.
|
|
"""
|
|
return open(log_file_path(builddir, stage, logtofile), 'a+') if logtofile else sys.stdout
|
|
|
|
|
|
def basepath(relpath=""):
|
|
"""Return the absolute path for a file or directory relative to the Buildroot top directory."""
|
|
return os.path.join(BASE_DIR, relpath)
|
|
|
|
|
|
def filepath(relpath):
|
|
return os.path.join(BASE_DIR, "support/testing", relpath)
|
|
|
|
|
|
def download(dldir, filename):
|
|
finalpath = os.path.join(dldir, filename)
|
|
if os.path.exists(finalpath):
|
|
return finalpath
|
|
|
|
if not os.path.exists(dldir):
|
|
os.makedirs(dldir)
|
|
|
|
tmpfile = tempfile.mktemp(dir=dldir)
|
|
print("Downloading to {}".format(tmpfile))
|
|
|
|
try:
|
|
url_fh = urlopen(os.path.join(ARTIFACTS_URL, filename))
|
|
with open(tmpfile, "w+b") as tmpfile_fh:
|
|
tmpfile_fh.write(url_fh.read())
|
|
except (HTTPError, URLError) as err:
|
|
os.unlink(tmpfile)
|
|
raise err
|
|
|
|
print("Renaming from {} to {}".format(tmpfile, finalpath))
|
|
os.rename(tmpfile, finalpath)
|
|
return finalpath
|
|
|
|
|
|
def run_cmd_on_host(builddir, cmd):
|
|
"""Call subprocess.check_output and return the text output."""
|
|
out = subprocess.check_output(cmd,
|
|
stderr=open(os.devnull, "w"),
|
|
cwd=builddir,
|
|
env={"LANG": "C"},
|
|
universal_newlines=True)
|
|
return out
|
|
|
|
|
|
def get_elf_arch_tag(builddir, prefix, fpath, tag):
|
|
"""
|
|
Runs the cross readelf on 'fpath', then extracts the value of tag 'tag'.
|
|
Example:
|
|
>>> get_elf_arch_tag('output', 'arm-none-linux-gnueabi-',
|
|
'bin/busybox', 'Tag_CPU_arch')
|
|
v5TEJ
|
|
>>>
|
|
"""
|
|
cmd = ["host/bin/{}-readelf".format(prefix),
|
|
"-A", os.path.join("target", fpath)]
|
|
out = run_cmd_on_host(builddir, cmd)
|
|
regexp = re.compile(r"^ {}: (.*)$".format(tag))
|
|
for line in out.splitlines():
|
|
m = regexp.match(line)
|
|
if not m:
|
|
continue
|
|
return m.group(1)
|
|
return None
|
|
|
|
|
|
def get_file_arch(builddir, prefix, fpath):
|
|
return get_elf_arch_tag(builddir, prefix, fpath, "Tag_CPU_arch")
|
|
|
|
|
|
def get_elf_prog_interpreter(builddir, prefix, fpath):
|
|
"""
|
|
Runs the cross readelf on 'fpath' to extract the program interpreter
|
|
name and returns it.
|
|
Example:
|
|
>>> get_elf_prog_interpreter('br-tests/TestExternalToolchainLinaroArm',
|
|
'arm-linux-gnueabihf',
|
|
'bin/busybox')
|
|
/lib/ld-linux-armhf.so.3
|
|
>>>
|
|
"""
|
|
cmd = ["host/bin/{}-readelf".format(prefix),
|
|
"-l", os.path.join("target", fpath)]
|
|
out = run_cmd_on_host(builddir, cmd)
|
|
regexp = re.compile(r"^ *\[Requesting program interpreter: (.*)\]$")
|
|
for line in out.splitlines():
|
|
m = regexp.match(line)
|
|
if not m:
|
|
continue
|
|
return m.group(1)
|
|
return None
|
|
|
|
|
|
def img_round_power2(img):
|
|
"""
|
|
Rounds up the size of an image file to the next power of 2
|
|
"""
|
|
sz = os.stat(img).st_size
|
|
pow2 = 1
|
|
while pow2 < sz:
|
|
pow2 = pow2 << 1
|
|
with open(img, 'ab') as f:
|
|
f.truncate(pow2)
|