blob: b1ea3fa6a42f3f12f1e2a2004b0ca26feba4df4d [file] [log] [blame]
Matthew Barthccb7f852016-11-23 17:43:02 -06001#!/usr/bin/env python
2
3"""
4This script determines the given package's openbmc dependencies from its
5configure.ac file where it downloads, configures, builds, and installs each of
6these dependencies. Then the given package is configured, built, and installed
7prior to executing its unit tests.
8"""
9
10from urlparse import urljoin
Matthew Barth33df8792016-12-19 14:30:17 -060011from subprocess import check_call, call
Matthew Barthccb7f852016-11-23 17:43:02 -060012import os
13import sys
Matthew Barth33df8792016-12-19 14:30:17 -060014import argparse
15
16
17def check_call_cmd(dir, *cmd):
18 """
19 Verbose prints the directory location the given command is called from and
20 the command, then executes the command using check_call.
21
22 Parameter descriptions:
23 dir Directory location command is to be called from
24 cmd List of parameters constructing the complete command
25 """
26 printline(dir, ">", " ".join(cmd))
27 check_call(cmd)
Matthew Barthccb7f852016-11-23 17:43:02 -060028
29
30def clone_pkg(pkg):
Matthew Barth33df8792016-12-19 14:30:17 -060031 """
32 Clone the given openbmc package's git repository from gerrit into
33 the WORKSPACE location
34
35 Parameter descriptions:
36 pkg Name of the package to clone
37 """
Matthew Barthccb7f852016-11-23 17:43:02 -060038 pkg_repo = urljoin('https://gerrit.openbmc-project.xyz/openbmc/', pkg)
39 os.chdir(WORKSPACE)
Matthew Barth33df8792016-12-19 14:30:17 -060040 check_call_cmd(WORKSPACE, 'git', 'clone', pkg_repo)
41
42
43def get_deps(configure_ac):
44 """
45 Parse the given 'configure.ac' file for package dependencies and return
46 a list of the dependencies found.
47
48 Parameter descriptions:
49 configure_ac Opened 'configure.ac' file object
50 """
51 line = ""
52 dep_pkgs = []
53 for cfg_line in configure_ac:
54 # Remove whitespace & newline
55 cfg_line = cfg_line.rstrip()
56 # Check for line breaks
57 if cfg_line.endswith('\\'):
58 line += str(cfg_line[:-1])
59 continue
60 line = line+cfg_line
61
62 # Find any defined dependency
63 for macro_key in DEPENDENCIES:
64 if not line.startswith(macro_key):
65 continue
66 for dep_key in DEPENDENCIES[macro_key]:
67 if line.find(dep_key) == -1:
68 continue
69 dep_pkgs += [DEPENDENCIES[macro_key][dep_key]]
70 line = ""
71
72 return dep_pkgs
Matthew Barthccb7f852016-11-23 17:43:02 -060073
74
75def build_depends(pkg, pkgdir, dep_installed):
76 """
77 For each package(pkg), starting with the package to be unit tested,
78 parse its 'configure.ac' file from within the package's directory(pkgdir)
79 for each package dependency defined recursively doing the same thing
80 on each package found as a dependency.
81
82 Parameter descriptions:
83 pkg Name of the package
84 pkgdir Directory where package source is located
85 dep_installed Current list of dependencies and installation status
86 """
87 os.chdir(pkgdir)
88 # Open package's configure.ac
Matthew Barth33df8792016-12-19 14:30:17 -060089 with open("configure.ac", "rt") as configure_ac:
90 # Retrieve dependency list from package's configure.ac
91 configure_ac_deps = get_deps(configure_ac)
92 for dep_pkg in configure_ac_deps:
93 # Dependency package not already known
94 if dep_installed.get(dep_pkg) is None:
95 # Dependency package not installed
96 dep_installed[dep_pkg] = False
97 clone_pkg(dep_pkg)
98 # Determine this dependency package's
99 # dependencies and install them before
100 # returning to install this package
101 dep_pkgdir = os.path.join(WORKSPACE, dep_pkg)
102 dep_installed = build_depends(dep_pkg, dep_pkgdir,
103 dep_installed)
104 else:
105 # Dependency package known and installed
106 if dep_installed[dep_pkg]:
Matthew Barthccb7f852016-11-23 17:43:02 -0600107 continue
Matthew Barth33df8792016-12-19 14:30:17 -0600108 else:
109 # Cyclic dependency failure
110 raise Exception("Cyclic dependencies found in "+pkg)
Matthew Barthccb7f852016-11-23 17:43:02 -0600111
112 # Build & install this package
113 if not dep_installed[pkg]:
114 conf_flags = ""
115 os.chdir(pkgdir)
116 # Add any necessary configure flags for package
117 if CONFIGURE_FLAGS.get(pkg) is not None:
118 conf_flags = " ".join(CONFIGURE_FLAGS.get(pkg))
Matthew Barth33df8792016-12-19 14:30:17 -0600119 check_call_cmd(pkgdir, './bootstrap.sh')
120 check_call_cmd(pkgdir, './configure', conf_flags)
121 check_call_cmd(pkgdir, 'make')
122 check_call_cmd(pkgdir, 'make', 'install')
Matthew Barthccb7f852016-11-23 17:43:02 -0600123 dep_installed[pkg] = True
124
125 return dep_installed
126
127
128if __name__ == '__main__':
129 # CONFIGURE_FLAGS = [GIT REPO]:[CONFIGURE FLAGS]
130 CONFIGURE_FLAGS = {
131 'phosphor-objmgr': ['--enable-unpatched-systemd']
132 }
133
134 # DEPENDENCIES = [MACRO]:[library/header]:[GIT REPO]
135 DEPENDENCIES = {
136 'AC_CHECK_LIB': {'mapper': 'phosphor-objmgr'},
137 'AC_CHECK_HEADER': {'host-ipmid/ipmid-api.h': 'phosphor-host-ipmid'}
138 }
139
Matthew Barth33df8792016-12-19 14:30:17 -0600140 # Set command line arguments
141 parser = argparse.ArgumentParser()
142 parser.add_argument("-w", "--workspace", dest="WORKSPACE", required=True,
143 help="Workspace directory location(i.e. /home)")
144 parser.add_argument("-p", "--package", dest="PACKAGE", required=True,
145 help="OpenBMC package to be unit tested")
146 parser.add_argument("-v", "--verbose", action="store_true",
147 help="Print additional package status messages")
148 args = parser.parse_args(sys.argv[1:])
149 WORKSPACE = args.WORKSPACE
150 UNIT_TEST_PKG = args.PACKAGE
151 if args.verbose:
152 def printline(*line):
153 for arg in line:
154 print arg,
155 print
156 else:
157 printline = lambda *l: None
Matthew Barthccb7f852016-11-23 17:43:02 -0600158
159 prev_umask = os.umask(000)
160 # Determine dependencies and install them
161 dep_installed = dict()
162 dep_installed[UNIT_TEST_PKG] = False
163 dep_installed = build_depends(UNIT_TEST_PKG,
164 os.path.join(WORKSPACE, UNIT_TEST_PKG),
165 dep_installed)
166 os.chdir(os.path.join(WORKSPACE, UNIT_TEST_PKG))
167 # Run package unit tests
Matthew Barth33df8792016-12-19 14:30:17 -0600168 check_call_cmd(os.path.join(WORKSPACE, UNIT_TEST_PKG), 'make', 'check')
Matthew Barthccb7f852016-11-23 17:43:02 -0600169 os.umask(prev_umask)