summaryrefslogtreecommitdiffstats
path: root/meta/classes-recipe
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes-recipe')
-rw-r--r--meta/classes-recipe/go-mod-update-modules.bbclass152
-rw-r--r--meta/classes-recipe/go-mod.bbclass2
-rw-r--r--meta/classes-recipe/kernelsrc.bbclass4
-rw-r--r--meta/classes-recipe/populate_sdk_base.bbclass1
-rw-r--r--meta/classes-recipe/populate_sdk_ext.bbclass8
-rw-r--r--meta/classes-recipe/testsdk.bbclass1
6 files changed, 160 insertions, 8 deletions
diff --git a/meta/classes-recipe/go-mod-update-modules.bbclass b/meta/classes-recipe/go-mod-update-modules.bbclass
new file mode 100644
index 0000000000..5fccd0bb0d
--- /dev/null
+++ b/meta/classes-recipe/go-mod-update-modules.bbclass
@@ -0,0 +1,152 @@
1addtask do_update_modules after do_configure
2do_update_modules[nostamp] = "1"
3do_update_modules[network] = "1"
4
5# This class maintains two files, BPN-go-mods.inc and BPN-licenses.inc.
6#
7# -go-mods.inc will append SRC_URI with all of the Go modules that are
8# dependencies of this recipe.
9#
10# -licenses.inc will append LICENSE and LIC_FILES_CHKSUM with the found licenses
11# in the modules.
12#
13# These files are machine-generated and should not be modified.
14
15python do_update_modules() {
16 import subprocess, tempfile, json, re, urllib.parse
17 from oe.license import tidy_licenses
18 from oe.license_finder import find_licenses
19
20 def unescape_path(path):
21 """Unescape capital letters using exclamation points."""
22 return re.sub(r'!([a-z])', lambda m: m.group(1).upper(), path)
23
24 def fold_uri(uri):
25 """Fold URI for sorting shorter module paths before longer."""
26 return uri.replace(';', ' ').replace('/', '!')
27
28 def parse_existing_licenses():
29 hashes = {}
30 for url in d.getVar("LIC_FILES_CHKSUM").split():
31 (method, host, path, user, pswd, parm) = bb.fetch.decodeurl(url)
32 if "spdx" in parm and parm["spdx"] != "Unknown":
33 hashes[parm["md5"]] = urllib.parse.unquote_plus(parm["spdx"])
34 return hashes
35
36 bpn = d.getVar("BPN")
37 thisdir = d.getVar("THISDIR")
38 s_dir = d.getVar("S")
39
40 with tempfile.TemporaryDirectory(prefix='go-mod-') as mod_cache_dir:
41 notice = """
42# This file has been generated by go-mod-update-modules.bbclass
43#
44# Do not modify it by hand, as the contents will be replaced when
45# running the update-modules task.
46
47"""
48
49 env = dict(os.environ, GOMODCACHE=mod_cache_dir)
50
51 source = d.expand("${UNPACKDIR}/${GO_SRCURI_DESTSUFFIX}")
52 output = subprocess.check_output(("go", "mod", "edit", "-json"), cwd=source, env=env, text=True)
53 go_mod = json.loads(output)
54
55 output = subprocess.check_output(("go", "list", "-json=Dir,Module", "-deps", f"{go_mod['Module']['Path']}/..."), cwd=source, env=env, text=True)
56
57 #
58 # Licenses
59 #
60
61 # load hashes from the existing licenses.inc
62 extra_hashes = parse_existing_licenses()
63
64 # The output of this isn't actually valid JSON, but a series of dicts.
65 # Wrap in [] and join the dicts with ,
66 # Very frustrating that the json parser in python can't repeatedly
67 # parse from a stream.
68 pkgs = json.loads('[' + output.replace('}\n{', '},\n{') + ']')
69 # Collect licenses for the dependencies.
70 licenses = set()
71 lic_files_chksum = []
72 lic_files = {}
73
74 for pkg in pkgs:
75 mod = pkg.get('Module', None)
76 if not mod or mod.get('Main', False):
77 continue
78
79 mod_dir = mod['Dir']
80
81 if not mod_dir.startswith(mod_cache_dir):
82 continue
83
84 path = os.path.relpath(mod_dir, mod_cache_dir)
85
86 for license_name, license_file, license_md5 in find_licenses(mod['Dir'], d, first_only=True, extra_hashes=extra_hashes):
87 lic_files[os.path.join(path, license_file)] = (license_name, license_md5)
88
89 for lic_file in lic_files:
90 license_name, license_md5 = lic_files[lic_file]
91 if license_name == "Unknown":
92 bb.warn(f"Unknown license: {lic_file} {license_md5}")
93
94 licenses.add(lic_files[lic_file][0])
95 lic_files_chksum.append(
96 f'file://pkg/mod/{lic_file};md5={license_md5};spdx={urllib.parse.quote_plus(license_name)}')
97
98 licenses_filename = os.path.join(thisdir, f"{bpn}-licenses.inc")
99 with open(licenses_filename, "w") as f:
100 f.write(notice)
101 f.write(f'LICENSE += "& {" & ".join(tidy_licenses(licenses))}"\n\n')
102 f.write('LIC_FILES_CHKSUM += "\\\n')
103 for lic in sorted(lic_files_chksum, key=fold_uri):
104 f.write(' ' + lic + ' \\\n')
105 f.write('"\n')
106
107 #
108 # Sources
109 #
110
111 # Collect the module cache files downloaded by the go list command as
112 # the go list command knows best what the go list command needs and it
113 # needs more files in the module cache than the go install command as
114 # it doesn't do the dependency pruning mentioned in the Go module
115 # reference, https://go.dev/ref/mod, for go 1.17 or higher.
116 src_uris = []
117 downloaddir = os.path.join(mod_cache_dir, 'cache', 'download')
118 for dirpath, _, filenames in os.walk(downloaddir):
119 # We want to process files under @v directories
120 path, base = os.path.split(os.path.relpath(dirpath, downloaddir))
121 if base != '@v':
122 continue
123
124 path = unescape_path(path)
125 zipver = None
126 for name in filenames:
127 ver, ext = os.path.splitext(name)
128 if ext == '.zip':
129 chksum = bb.utils.sha256_file(os.path.join(dirpath, name))
130 src_uris.append(f'gomod://{path};version={ver};sha256sum={chksum}')
131 zipver = ver
132 break
133 for name in filenames:
134 ver, ext = os.path.splitext(name)
135 if ext == '.mod' and ver != zipver:
136 chksum = bb.utils.sha256_file(os.path.join(dirpath, name))
137 src_uris.append(f'gomod://{path};version={ver};mod=1;sha256sum={chksum}')
138
139
140 go_mods_filename = os.path.join(thisdir, f"{bpn}-go-mods.inc")
141 with open(go_mods_filename, "w") as f:
142 f.write(notice)
143 f.write('SRC_URI += "\\\n')
144 for uri in sorted(src_uris, key=fold_uri):
145 f.write(' ' + uri + ' \\\n')
146 f.write('"\n')
147
148 subprocess.check_output(("go", "clean", "-modcache"), cwd=source, env=env, text=True)
149}
150
151# This doesn't work as we need to wipe the inc files first so we don't try looking for LICENSE files that don't yet exist
152# RECIPE_UPGRADE_EXTRA_TASKS += "do_update_modules"
diff --git a/meta/classes-recipe/go-mod.bbclass b/meta/classes-recipe/go-mod.bbclass
index 93ae72235f..a15dda8f0e 100644
--- a/meta/classes-recipe/go-mod.bbclass
+++ b/meta/classes-recipe/go-mod.bbclass
@@ -23,7 +23,7 @@ GOBUILDFLAGS:append = " -modcacherw"
23inherit go 23inherit go
24 24
25export GOMODCACHE = "${S}/pkg/mod" 25export GOMODCACHE = "${S}/pkg/mod"
26GO_MOD_CACHE_DIR = "${@os.path.relpath(d.getVar('GOMODCACHE'), d.getVar('WORKDIR'))}" 26GO_MOD_CACHE_DIR = "${@os.path.relpath(d.getVar('GOMODCACHE'), d.getVar('UNPACKDIR'))}"
27do_unpack[cleandirs] += "${GOMODCACHE}" 27do_unpack[cleandirs] += "${GOMODCACHE}"
28 28
29GO_WORKDIR ?= "${GO_IMPORT}" 29GO_WORKDIR ?= "${GO_IMPORT}"
diff --git a/meta/classes-recipe/kernelsrc.bbclass b/meta/classes-recipe/kernelsrc.bbclass
index ecb02dc9ed..9336184298 100644
--- a/meta/classes-recipe/kernelsrc.bbclass
+++ b/meta/classes-recipe/kernelsrc.bbclass
@@ -15,3 +15,7 @@ LOCAL_VERSION = "${@get_kernellocalversion_file("${STAGING_KERNEL_BUILDDIR}")}"
15 15
16inherit linux-kernel-base 16inherit linux-kernel-base
17 17
18# The final packages get the kernel version instead of the default 1.0
19python do_package:prepend() {
20 d.setVar('PKGV', d.getVar("KERNEL_VERSION").split("-")[0])
21}
diff --git a/meta/classes-recipe/populate_sdk_base.bbclass b/meta/classes-recipe/populate_sdk_base.bbclass
index 8ef4b2be77..e6685cde97 100644
--- a/meta/classes-recipe/populate_sdk_base.bbclass
+++ b/meta/classes-recipe/populate_sdk_base.bbclass
@@ -373,7 +373,6 @@ EOF
373 -e 's#@SDK_VERSION@#${SDK_VERSION}#g' \ 373 -e 's#@SDK_VERSION@#${SDK_VERSION}#g' \
374 -e '/@SDK_PRE_INSTALL_COMMAND@/d' \ 374 -e '/@SDK_PRE_INSTALL_COMMAND@/d' \
375 -e '/@SDK_POST_INSTALL_COMMAND@/d' \ 375 -e '/@SDK_POST_INSTALL_COMMAND@/d' \
376 -e 's#@SDK_GCC_VER@#${@oe.utils.host_gcc_version(d, taskcontextonly=True)}#g' \
377 -e 's#@SDK_ARCHIVE_TYPE@#${SDK_ARCHIVE_TYPE}#g' \ 376 -e 's#@SDK_ARCHIVE_TYPE@#${SDK_ARCHIVE_TYPE}#g' \
378 ${SDKDEPLOYDIR}/${TOOLCHAIN_OUTPUTNAME}.sh 377 ${SDKDEPLOYDIR}/${TOOLCHAIN_OUTPUTNAME}.sh
379 378
diff --git a/meta/classes-recipe/populate_sdk_ext.bbclass b/meta/classes-recipe/populate_sdk_ext.bbclass
index 2d7d661d25..20dfdf02d4 100644
--- a/meta/classes-recipe/populate_sdk_ext.bbclass
+++ b/meta/classes-recipe/populate_sdk_ext.bbclass
@@ -150,7 +150,6 @@ def create_filtered_tasklist(d, sdkbasepath, tasklistfile, conf_initpath):
150 with open(sdkbasepath + '/conf/local.conf', 'a') as f: 150 with open(sdkbasepath + '/conf/local.conf', 'a') as f:
151 # Force the use of sstate from the build system 151 # Force the use of sstate from the build system
152 f.write('\nSSTATE_DIR:forcevariable = "%s"\n' % d.getVar('SSTATE_DIR')) 152 f.write('\nSSTATE_DIR:forcevariable = "%s"\n' % d.getVar('SSTATE_DIR'))
153 f.write('SSTATE_MIRRORS:forcevariable = "file://universal/(.*) file://universal-4.9/\\1 file://universal-4.9/(.*) file://universal-4.8/\\1"\n')
154 # Ensure TMPDIR is the default so that clean_esdk_builddir() can delete it 153 # Ensure TMPDIR is the default so that clean_esdk_builddir() can delete it
155 f.write('TMPDIR:forcevariable = "${TOPDIR}/tmp"\n') 154 f.write('TMPDIR:forcevariable = "${TOPDIR}/tmp"\n')
156 # Drop uninative if the build isn't using it (or else NATIVELSBSTRING will 155 # Drop uninative if the build isn't using it (or else NATIVELSBSTRING will
@@ -380,9 +379,6 @@ def write_local_conf(d, baseoutpath, derivative, core_meta_subdir, uninative_che
380 f.write('# Provide a flag to indicate we are in the EXT_SDK Context\n') 379 f.write('# Provide a flag to indicate we are in the EXT_SDK Context\n')
381 f.write('WITHIN_EXT_SDK = "1"\n\n') 380 f.write('WITHIN_EXT_SDK = "1"\n\n')
382 381
383 # Map gcc-dependent uninative sstate cache for installer usage
384 f.write('SSTATE_MIRRORS += " file://universal/(.*) file://universal-4.9/\\1 file://universal-4.9/(.*) file://universal-4.8/\\1"\n\n')
385
386 if d.getVar("PRSERV_HOST"): 382 if d.getVar("PRSERV_HOST"):
387 # Override this, we now include PR data, so it should only point ot the local database 383 # Override this, we now include PR data, so it should only point ot the local database
388 f.write('PRSERV_HOST = "localhost:0"\n\n') 384 f.write('PRSERV_HOST = "localhost:0"\n\n')
@@ -491,8 +487,8 @@ def prepare_locked_cache(d, baseoutpath, derivative, conf_initpath):
491 sstate_out = baseoutpath + '/sstate-cache' 487 sstate_out = baseoutpath + '/sstate-cache'
492 bb.utils.remove(sstate_out, True) 488 bb.utils.remove(sstate_out, True)
493 489
494 # uninative.bbclass sets NATIVELSBSTRING to 'universal%s' % oe.utils.host_gcc_version(d) 490 # uninative.bbclass sets NATIVELSBSTRING to 'universal'
495 fixedlsbstring = "universal%s" % oe.utils.host_gcc_version(d) if bb.data.inherits_class('uninative', d) else "" 491 fixedlsbstring = "universal" if bb.data.inherits_class('uninative', d) else ""
496 492
497 sdk_include_toolchain = (d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1') 493 sdk_include_toolchain = (d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1')
498 sdk_ext_type = d.getVar('SDK_EXT_TYPE') 494 sdk_ext_type = d.getVar('SDK_EXT_TYPE')
diff --git a/meta/classes-recipe/testsdk.bbclass b/meta/classes-recipe/testsdk.bbclass
index 59d2834c99..b1c4fa67e6 100644
--- a/meta/classes-recipe/testsdk.bbclass
+++ b/meta/classes-recipe/testsdk.bbclass
@@ -19,6 +19,7 @@ TESTSDK_SUITES ?= ""
19 19
20TESTSDK_CLASS_NAME ?= "oeqa.sdk.testsdk.TestSDK" 20TESTSDK_CLASS_NAME ?= "oeqa.sdk.testsdk.TestSDK"
21TESTSDKEXT_CLASS_NAME ?= "oeqa.sdkext.testsdk.TestSDKExt" 21TESTSDKEXT_CLASS_NAME ?= "oeqa.sdkext.testsdk.TestSDKExt"
22TESTSDK_CASE_DIRS ?= "sdk"
22 23
23def import_and_run(name, d): 24def import_and_run(name, d):
24 import importlib 25 import importlib