summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorTim Orling <timothy.t.orling@linux.intel.com>2020-03-25 21:26:55 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-03-29 12:05:31 +0100
commit03d54a42a3be77d18f5e8d67dc077f65f2cd4457 (patch)
treebb479132370392709bf337f417310f5922114d54 /scripts
parent80c1002c2e4dd7cdaa6ef40a5d37addcc27ca3da (diff)
downloadpoky-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-xscripts/install-buildtools270
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
35import argparse
36import logging
37import os
38import re
39import shutil
40import stat
41import subprocess
42import sys
43import tempfile
44from urllib.parse import quote
45
46scripts_path = os.path.dirname(os.path.realpath(__file__))
47lib_path = scripts_path + '/lib'
48sys.path = sys.path + [lib_path]
49import scriptutils
50import scriptpath
51
52# Figure out where is the bitbake/lib/bb since we need bb.utils.md5_file
53bitbakepath = scriptpath.add_bitbake_lib_path()
54if 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
59PROGNAME = 'install-buildtools'
60logger = scriptutils.logger_create(PROGNAME, stream=sys.stdout)
61
62DEFAULT_BASE_URL: str = 'http://downloads.yoctoproject.org/releases/yocto'
63DEFAULT_RELEASE: str = 'yocto-3.1_M2'
64DEFAULT_INSTALLER_VERSION: str = '3.0+snapshot'
65DEFAULT_BUILDDATE: str = "20200122"
66
67
68def 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
262if __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)