1# 2# Copyright (C) 2013 Intel Corporation 3# 4# SPDX-License-Identifier: MIT 5# 6 7# Provides a class for automating build tests for projects 8 9import os 10import re 11import bb.utils 12import subprocess 13import tempfile 14from abc import ABCMeta, abstractmethod 15 16class BuildProject(metaclass=ABCMeta): 17 18 def __init__(self, d, uri, foldername=None, tmpdir=None): 19 self.d = d 20 self.uri = uri 21 self.archive = os.path.basename(uri) 22 self.tempdirobj = None 23 if not tmpdir: 24 tmpdir = self.d.getVar('WORKDIR') 25 if not tmpdir: 26 self.tempdirobj = tempfile.TemporaryDirectory(prefix='buildproject-') 27 tmpdir = self.tempdirobj.name 28 self.localarchive = os.path.join(tmpdir, self.archive) 29 if foldername: 30 self.fname = foldername 31 else: 32 self.fname = re.sub(r'\.tar\.bz2$|\.tar\.gz$|\.tar\.xz$', '', self.archive) 33 34 # Download self.archive to self.localarchive 35 def _download_archive(self): 36 dl_dir = self.d.getVar("DL_DIR") 37 if dl_dir and os.path.exists(os.path.join(dl_dir, self.archive)): 38 bb.utils.copyfile(os.path.join(dl_dir, self.archive), self.localarchive) 39 return 40 41 exportvars = ['HTTP_PROXY', 'http_proxy', 42 'HTTPS_PROXY', 'https_proxy', 43 'FTP_PROXY', 'ftp_proxy', 44 'FTPS_PROXY', 'ftps_proxy', 45 'NO_PROXY', 'no_proxy', 46 'ALL_PROXY', 'all_proxy', 47 'SOCKS5_USER', 'SOCKS5_PASSWD'] 48 49 cmd = '' 50 for var in exportvars: 51 val = self.d.getVar(var) 52 if val: 53 cmd = 'export ' + var + '=\"%s\"; %s' % (val, cmd) 54 55 cmd = cmd + "wget -O %s %s" % (self.localarchive, self.uri) 56 subprocess.check_output(cmd, shell=True) 57 58 # This method should provide a way to run a command in the desired environment. 59 @abstractmethod 60 def _run(self, cmd): 61 pass 62 63 # The timeout parameter of target.run is set to 0 to make the ssh command 64 # run with no timeout. 65 def run_configure(self, configure_args='', extra_cmds=''): 66 return self._run('cd %s; %s ./configure %s' % (self.targetdir, extra_cmds, configure_args)) 67 68 def run_make(self, make_args=''): 69 return self._run('cd %s; make %s' % (self.targetdir, make_args)) 70 71 def run_install(self, install_args=''): 72 return self._run('cd %s; make install %s' % (self.targetdir, install_args)) 73 74 def clean(self): 75 if self.tempdirobj: 76 self.tempdirobj.cleanup() 77 self._run('rm -rf %s' % self.targetdir) 78 subprocess.check_call('rm -f %s' % self.localarchive, shell=True) 79 80class TargetBuildProject(BuildProject): 81 82 def __init__(self, target, d, uri, foldername=None): 83 self.target = target 84 self.targetdir = "~/" 85 BuildProject.__init__(self, d, uri, foldername) 86 87 def download_archive(self): 88 89 self._download_archive() 90 91 (status, output) = self.target.copy_to(self.localarchive, self.targetdir) 92 if status != 0: 93 raise Exception("Failed to copy archive to target, output: %s" % output) 94 95 (status, output) = self.target.run('tar xf %s%s -C %s' % (self.targetdir, self.archive, self.targetdir)) 96 if status != 0: 97 raise Exception("Failed to extract archive, output: %s" % output) 98 99 #Change targetdir to project folder 100 self.targetdir = self.targetdir + self.fname 101 102 # The timeout parameter of target.run is set to 0 to make the ssh command 103 # run with no timeout. 104 def _run(self, cmd): 105 return self.target.run(cmd, 0)[0] 106 107 108class SDKBuildProject(BuildProject): 109 110 def __init__(self, testpath, sdkenv, d, uri, foldername=None): 111 self.sdkenv = sdkenv 112 self.testdir = testpath 113 self.targetdir = testpath 114 bb.utils.mkdirhier(testpath) 115 self.datetime = d.getVar('DATETIME') 116 self.testlogdir = d.getVar("TEST_LOG_DIR") 117 bb.utils.mkdirhier(self.testlogdir) 118 self.logfile = os.path.join(self.testlogdir, "sdk_target_log.%s" % self.datetime) 119 BuildProject.__init__(self, d, uri, foldername, tmpdir=testpath) 120 121 def download_archive(self): 122 123 self._download_archive() 124 125 cmd = 'tar xf %s%s -C %s' % (self.targetdir, self.archive, self.targetdir) 126 subprocess.check_output(cmd, shell=True) 127 128 #Change targetdir to project folder 129 self.targetdir = os.path.join(self.targetdir, self.fname) 130 131 def run_configure(self, configure_args='', extra_cmds=' gnu-configize; '): 132 return super(SDKBuildProject, self).run_configure(configure_args=(configure_args or '$CONFIGURE_FLAGS'), extra_cmds=extra_cmds) 133 134 def run_install(self, install_args=''): 135 return super(SDKBuildProject, self).run_install(install_args=(install_args or "DESTDIR=%s/../install" % self.targetdir)) 136 137 def log(self, msg): 138 if self.logfile: 139 with open(self.logfile, "a") as f: 140 f.write("%s\n" % msg) 141 142 def _run(self, cmd): 143 self.log("Running . %s; " % self.sdkenv + cmd) 144 return subprocess.check_call(". %s; " % self.sdkenv + cmd, shell=True) 145