diff options
author | Tim Orling <timothy.t.orling@linux.intel.com> | 2020-03-25 21:26:55 -0700 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-03-29 12:05:31 +0100 |
commit | 03d54a42a3be77d18f5e8d67dc077f65f2cd4457 (patch) | |
tree | bb479132370392709bf337f417310f5922114d54 /scripts | |
parent | 80c1002c2e4dd7cdaa6ef40a5d37addcc27ca3da (diff) | |
download | poky-03d54a42a3be77d18f5e8d67dc077f65f2cd4457.tar.gz |
scripts/install-buildtools: add helper script to install buildtools
For distros such as CentOS-7 where the default buildtools are too
old we need to make it easy for users to install a pre-built SDK
with all of "build-essentials" included.
Other uses may include building older Yocto Project releases with
a distro where buildtools are too new.
For convenience, the standard buildtools installation is also
supported.
NOTE: extended buildtools is the default, e.g.
--with-extended-buildtools is on by default
Example usage (extended buildtools from milestone):
(1) using --url and --filename
$ install-buildtools \
--url http://downloads.yoctoproject.org/releases/yocto/milestones/yocto-3.1_M2/buildtools \
--filename x86_64-buildtools-extended-nativesdk-standalone-3.0+snapshot-20200122.sh
(2) using --base-url, --release, --installer-version and --build-date
$ install-buildtools \
--base-url http://downloads.yoctoproject.org/releases/yocto \
--release yocto-3.1_M2 \
--install-version 3.0+snapshot
--build-date 202000122
Example usage (standard buildtools from release):
(3) using --url and --filename
$ install-buildtools --without-extended-buildtools \
--url http://downloads.yoctoproject.org/releases/yocto/yocto-3.0.2/buildtools \
--filename x86_64-buildtools-nativesdk-standalone-3.0.2.sh
(4) using --base-url, --release and --installer-version
$ install-buildtools --without-extended-buildtools \
--base-url http://downloads.yoctoproject.org/releases/yocto \
--release yocto-3.0.2 \
--install-version 3.0.2
[YOCTO #13832]
(From OE-Core rev: 2d0aea6a73c427ce6aa17dc71e0783977a52bb2b)
Signed-off-by: Tim Orling <timothy.t.orling@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/install-buildtools | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/scripts/install-buildtools b/scripts/install-buildtools new file mode 100755 index 0000000000..0947e9c4d6 --- /dev/null +++ b/scripts/install-buildtools | |||
@@ -0,0 +1,270 @@ | |||
1 | #!/usr/bin/env python3 | ||
2 | |||
3 | # Buildtools and buildtools extended installer helper script | ||
4 | # | ||
5 | # Copyright (C) 2017-2020 Intel Corporation | ||
6 | # | ||
7 | # SPDX-License-Identifier: MIT | ||
8 | # | ||
9 | # NOTE: --with-extended-buildtools is on by default | ||
10 | # | ||
11 | # Example usage (extended buildtools from milestone): | ||
12 | # (1) using --url and --filename | ||
13 | # $ install-buildtools \ | ||
14 | # --url http://downloads.yoctoproject.org/releases/yocto/milestones/yocto-3.1_M2/buildtools \ | ||
15 | # --filename x86_64-buildtools-extended-nativesdk-standalone-3.0+snapshot-20200122.sh | ||
16 | # (2) using --base-url, --release, --installer-version and --build-date | ||
17 | # $ install-buildtools \ | ||
18 | # --base-url http://downloads.yoctoproject.org/releases/yocto \ | ||
19 | # --release yocto-3.1_M2 \ | ||
20 | # --install-version 3.0+snapshot | ||
21 | # --build-date 202000122 | ||
22 | # | ||
23 | # Example usage (standard buildtools from release): | ||
24 | # (3) using --url and --filename | ||
25 | # $ install-buildtools --without-extended-buildtools \ | ||
26 | # --url http://downloads.yoctoproject.org/releases/yocto/yocto-3.0.2/buildtools \ | ||
27 | # --filename x86_64-buildtools-nativesdk-standalone-3.0.2.sh | ||
28 | # (4) using --base-url, --release and --installer-version | ||
29 | # $ install-buildtools --without-extended-buildtools \ | ||
30 | # --base-url http://downloads.yoctoproject.org/releases/yocto \ | ||
31 | # --release yocto-3.0.2 \ | ||
32 | # --install-version 3.0.2 | ||
33 | # | ||
34 | |||
35 | import argparse | ||
36 | import logging | ||
37 | import os | ||
38 | import re | ||
39 | import shutil | ||
40 | import stat | ||
41 | import subprocess | ||
42 | import sys | ||
43 | import tempfile | ||
44 | from urllib.parse import quote | ||
45 | |||
46 | scripts_path = os.path.dirname(os.path.realpath(__file__)) | ||
47 | lib_path = scripts_path + '/lib' | ||
48 | sys.path = sys.path + [lib_path] | ||
49 | import scriptutils | ||
50 | import scriptpath | ||
51 | |||
52 | # Figure out where is the bitbake/lib/bb since we need bb.utils.md5_file | ||
53 | bitbakepath = scriptpath.add_bitbake_lib_path() | ||
54 | if not bitbakepath: | ||
55 | sys.stderr.write("Unable to find bitbake by searching parent directory " | ||
56 | "of this script or PATH\n") | ||
57 | sys.exit(1) | ||
58 | |||
59 | PROGNAME = 'install-buildtools' | ||
60 | logger = scriptutils.logger_create(PROGNAME, stream=sys.stdout) | ||
61 | |||
62 | DEFAULT_BASE_URL: str = 'http://downloads.yoctoproject.org/releases/yocto' | ||
63 | DEFAULT_RELEASE: str = 'yocto-3.1_M2' | ||
64 | DEFAULT_INSTALLER_VERSION: str = '3.0+snapshot' | ||
65 | DEFAULT_BUILDDATE: str = "20200122" | ||
66 | |||
67 | |||
68 | def main(): | ||
69 | global DEFAULT_BASE_URL | ||
70 | global DEFAULT_RELEASE | ||
71 | global DEFAULT_INSTALLER_VERSION | ||
72 | global DEFAULT_BUILDDATE | ||
73 | filename: str = "" | ||
74 | release: str = "" | ||
75 | buildtools_url: str = "" | ||
76 | |||
77 | parser = argparse.ArgumentParser( | ||
78 | description="Buildtools installation helper", | ||
79 | add_help=False) | ||
80 | parser.add_argument('-u', '--url', | ||
81 | help='URL from where to fetch buildtools SDK installer, not ' | ||
82 | 'including filename (optional)\n' | ||
83 | 'Requires --filename.', | ||
84 | action='store') | ||
85 | parser.add_argument('-f', '--filename', | ||
86 | help='filename for the buildtools SDK installer to be installed ' | ||
87 | '(optional)\nRequires --url', | ||
88 | action='store') | ||
89 | parser.add_argument('-d', '--directory', | ||
90 | help='directory where buildtools SDK will be installed (optional)', | ||
91 | action='store') | ||
92 | parser.add_argument('-r', '--release', | ||
93 | default=DEFAULT_RELEASE, | ||
94 | help='Yocto Project release string for SDK which will be ' | ||
95 | 'installed (optional)', | ||
96 | action='store') | ||
97 | parser.add_argument('-V', '--installer-version', | ||
98 | default=DEFAULT_INSTALLER_VERSION, | ||
99 | help='version string for the SDK to be installed (optional)', | ||
100 | action='store') | ||
101 | parser.add_argument('-b', '--base-url', | ||
102 | default=DEFAULT_BASE_URL, | ||
103 | help='base URL from which to fetch SDK (optional)', action='store') | ||
104 | parser.add_argument('-t', '--build-date', | ||
105 | default=DEFAULT_BUILDDATE, | ||
106 | help='Build date of pre-release SDK (optional)', action='store') | ||
107 | group = parser.add_mutually_exclusive_group() | ||
108 | group.add_argument('--with-extended-buildtools', action='store_true', | ||
109 | dest='with_extended_buildtools', | ||
110 | default=True, | ||
111 | help='enable extended buildtools tarball (on by default)') | ||
112 | group.add_argument('--without-extended-buildtools', action='store_false', | ||
113 | dest='with_extended_buildtools', | ||
114 | help='disable extended buildtools (traditional buildtools tarball)') | ||
115 | parser.add_argument('-c', '--check', help='enable md5 checksum checking', | ||
116 | default=True, | ||
117 | action='store_true') | ||
118 | parser.add_argument('-D', '--debug', help='enable debug output', | ||
119 | action='store_true') | ||
120 | parser.add_argument('-q', '--quiet', help='print only errors', | ||
121 | action='store_true') | ||
122 | |||
123 | parser.add_argument('-h', '--help', action='help', | ||
124 | default=argparse.SUPPRESS, | ||
125 | help='show this help message and exit') | ||
126 | |||
127 | args = parser.parse_args() | ||
128 | |||
129 | if args.debug: | ||
130 | logger.setLevel(logging.DEBUG) | ||
131 | elif args.quiet: | ||
132 | logger.setLevel(logging.ERROR) | ||
133 | |||
134 | if args.url and args.filename: | ||
135 | logger.debug("--url and --filename detected. Ignoring --base-url " | ||
136 | "--release --installer-version arguments.") | ||
137 | filename = args.filename | ||
138 | buildtools_url = "%s/%s" % (args.url, filename) | ||
139 | else: | ||
140 | if args.base_url: | ||
141 | base_url = args.base_url | ||
142 | else: | ||
143 | base_url = DEFAULT_BASE_URL | ||
144 | if args.release: | ||
145 | # check if this is a pre-release "milestone" SDK | ||
146 | m = re.search(r"^(?P<distro>[a-zA-Z\-]+)(?P<version>[0-9.]+)(?P<milestone>_M[1-9])$", | ||
147 | args.release) | ||
148 | logger.debug("milestone regex: %s" % m) | ||
149 | if m and m.group('milestone'): | ||
150 | logger.debug("release[distro]: %s" % m.group('distro')) | ||
151 | logger.debug("release[version]: %s" % m.group('version')) | ||
152 | logger.debug("release[milestone]: %s" % m.group('milestone')) | ||
153 | if not args.build_date: | ||
154 | logger.error("Milestone installers require --build-date") | ||
155 | else: | ||
156 | if args.with_extended_buildtools: | ||
157 | filename = "x86_64-buildtools-extended-nativesdk-standalone-%s-%s.sh" % ( | ||
158 | args.installer_version, args.build_date) | ||
159 | else: | ||
160 | filename = "x86_64-buildtools-nativesdk-standalone-%s-%s.sh" % ( | ||
161 | args.installer_version, args.build_date) | ||
162 | safe_filename = quote(filename) | ||
163 | buildtools_url = "%s/milestones/%s/buildtools/%s" % (base_url, args.release, safe_filename) | ||
164 | # regular release SDK | ||
165 | else: | ||
166 | if args.with_extended_buildtools: | ||
167 | filename = "x86_64-buildtools-extended-nativesdk-standalone-%s.sh" % args.installer_version | ||
168 | else: | ||
169 | filename = "x86_64-buildtools-nativesdk-standalone-%s.sh" % args.installer_version | ||
170 | safe_filename = quote(filename) | ||
171 | buildtools_url = "%s/%s/buildtools/%s" % (base_url, args.release, safe_filename) | ||
172 | |||
173 | tmpsdk_dir = tempfile.mkdtemp() | ||
174 | try: | ||
175 | # Fetch installer | ||
176 | logger.info("Fetching buildtools installer") | ||
177 | tmpbuildtools = os.path.join(tmpsdk_dir, filename) | ||
178 | ret = subprocess.call("wget -q -O %s %s" % | ||
179 | (tmpbuildtools, buildtools_url), shell=True) | ||
180 | if ret != 0: | ||
181 | logger.error("Could not download file from %s" % buildtools_url) | ||
182 | return ret | ||
183 | |||
184 | # Verify checksum | ||
185 | if args.check: | ||
186 | import bb | ||
187 | logger.info("Fetching buildtools installer checksum") | ||
188 | check_url = "{}.md5sum".format(buildtools_url) | ||
189 | checksum_filename = "%s.md5sum" % filename | ||
190 | tmpbuildtools_checksum = os.path.join(tmpsdk_dir, checksum_filename) | ||
191 | ret = subprocess.call("wget -q -O %s %s" % | ||
192 | (tmpbuildtools_checksum, check_url), shell=True) | ||
193 | if ret != 0: | ||
194 | logger.error("Could not download file from %s" % check_url) | ||
195 | return ret | ||
196 | regex = re.compile(r"^(?P<md5sum>[0-9a-f]+)\s\s(?P<path>.*/)(?P<filename>.*)$") | ||
197 | with open(tmpbuildtools_checksum, 'rb') as f: | ||
198 | original = f.read() | ||
199 | m = re.search(regex, original.decode("utf-8")) | ||
200 | logger.debug("md5sum: %s" % m.group('md5sum')) | ||
201 | logger.debug("path: %s" % m.group('path')) | ||
202 | logger.debug("filename: %s" % m.group('filename')) | ||
203 | if filename != m.group('filename'): | ||
204 | logger.error("Filename does not match name in checksum") | ||
205 | return 1 | ||
206 | md5sum = m.group('md5sum') | ||
207 | md5value = bb.utils.md5_file(tmpbuildtools) | ||
208 | if md5sum == md5value: | ||
209 | logger.info("Checksum success") | ||
210 | else: | ||
211 | logger.error("Checksum %s expected. Actual checksum is %s." % | ||
212 | (md5sum, md5value)) | ||
213 | |||
214 | # Make installer executable | ||
215 | logger.info("Making installer executable") | ||
216 | st = os.stat(tmpbuildtools) | ||
217 | os.chmod(tmpbuildtools, st.st_mode | stat.S_IEXEC) | ||
218 | logger.debug(os.stat(tmpbuildtools)) | ||
219 | install_dir = "/opt/poky/%s" % args.installer_version | ||
220 | if args.directory: | ||
221 | install_dir = args.directory | ||
222 | ret = subprocess.call("%s -d %s -y" % | ||
223 | (tmpbuildtools, install_dir), shell=True) | ||
224 | else: | ||
225 | ret = subprocess.call("%s -y" % tmpbuildtools, shell=True) | ||
226 | if ret != 0: | ||
227 | logger.error("Could not run buildtools installer") | ||
228 | |||
229 | # Test installation | ||
230 | logger.info("Testing installation") | ||
231 | tool = "" | ||
232 | m = re.search("extended", tmpbuildtools) | ||
233 | logger.debug("extended regex: %s" % m) | ||
234 | if args.with_extended_buildtools and not m: | ||
235 | logger.info("Ignoring --with-extended-buildtools as filename " | ||
236 | "does not contain 'extended'") | ||
237 | if args.with_extended_buildtools and m: | ||
238 | tool = 'gcc' | ||
239 | else: | ||
240 | tool = 'tar' | ||
241 | proc = subprocess.run("source %s/environment-setup-x86_64-pokysdk-linux && which %s" % | ||
242 | (install_dir, tool), | ||
243 | shell=True, stdout=subprocess.PIPE) | ||
244 | which_tool = proc.stdout.decode("utf-8") | ||
245 | logger.debug("which %s: %s" % (tool, which_tool)) | ||
246 | ret = proc.returncode | ||
247 | if not which_tool.startswith(install_dir): | ||
248 | logger.error("Something went wrong: %s not found in %s" % | ||
249 | (tool, install_dir)) | ||
250 | if ret != 0: | ||
251 | logger.error("Something went wrong: installation failed") | ||
252 | else: | ||
253 | logger.info("Installation successful. Remember to source the " | ||
254 | "environment setup script now and in any new session.") | ||
255 | return ret | ||
256 | |||
257 | finally: | ||
258 | # cleanup tmp directory | ||
259 | shutil.rmtree(tmpsdk_dir) | ||
260 | |||
261 | |||
262 | if __name__ == '__main__': | ||
263 | try: | ||
264 | ret = main() | ||
265 | except Exception: | ||
266 | ret = 1 | ||
267 | import traceback | ||
268 | |||
269 | traceback.print_exc() | ||
270 | sys.exit(ret) | ||