diff options
Diffstat (limited to 'meta')
34 files changed, 539 insertions, 66 deletions
diff --git a/meta/classes-global/base.bbclass b/meta/classes-global/base.bbclass index b86f50e283..ac145d9fd6 100644 --- a/meta/classes-global/base.bbclass +++ b/meta/classes-global/base.bbclass | |||
@@ -154,6 +154,7 @@ do_fetch[file-checksums] = "${@bb.fetch.get_checksum_file_list(d)}" | |||
154 | do_fetch[file-checksums] += " ${@get_lic_checksum_file_list(d)}" | 154 | do_fetch[file-checksums] += " ${@get_lic_checksum_file_list(d)}" |
155 | do_fetch[prefuncs] += "fetcher_hashes_dummyfunc" | 155 | do_fetch[prefuncs] += "fetcher_hashes_dummyfunc" |
156 | do_fetch[network] = "1" | 156 | do_fetch[network] = "1" |
157 | do_fetch[umask] = "${OE_SHARED_UMASK}" | ||
157 | python base_do_fetch() { | 158 | python base_do_fetch() { |
158 | 159 | ||
159 | src_uri = (d.getVar('SRC_URI') or "").split() | 160 | src_uri = (d.getVar('SRC_URI') or "").split() |
diff --git a/meta/classes-global/sstate.bbclass b/meta/classes-global/sstate.bbclass index 2968cc4c2e..53bc2e3940 100644 --- a/meta/classes-global/sstate.bbclass +++ b/meta/classes-global/sstate.bbclass | |||
@@ -745,7 +745,7 @@ def pstaging_fetch(sstatefetch, d): | |||
745 | if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False): | 745 | if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False): |
746 | uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)] | 746 | uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)] |
747 | 747 | ||
748 | with bb.utils.umask(0o002): | 748 | with bb.utils.umask(bb.utils.to_filemode(d.getVar("OE_SHARED_UMASK"))): |
749 | bb.utils.mkdirhier(dldir) | 749 | bb.utils.mkdirhier(dldir) |
750 | 750 | ||
751 | for srcuri in uris: | 751 | for srcuri in uris: |
@@ -776,9 +776,10 @@ sstate_task_prefunc[dirs] = "${WORKDIR}" | |||
776 | python sstate_task_postfunc () { | 776 | python sstate_task_postfunc () { |
777 | shared_state = sstate_state_fromvars(d) | 777 | shared_state = sstate_state_fromvars(d) |
778 | 778 | ||
779 | omask = os.umask(0o002) | 779 | shared_umask = bb.utils.to_filemode(d.getVar("OE_SHARED_UMASK")) |
780 | if omask != 0o002: | 780 | omask = os.umask(shared_umask) |
781 | bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask) | 781 | if omask != shared_umask: |
782 | bb.note("Using umask %0o (not %0o) for sstate packaging" % (shared_umask, omask)) | ||
782 | sstate_package(shared_state, d) | 783 | sstate_package(shared_state, d) |
783 | os.umask(omask) | 784 | os.umask(omask) |
784 | 785 | ||
@@ -843,7 +844,8 @@ python sstate_create_and_sign_package () { | |||
843 | 844 | ||
844 | # Create the required sstate directory if it is not present. | 845 | # Create the required sstate directory if it is not present. |
845 | if not sstate_pkg.parent.is_dir(): | 846 | if not sstate_pkg.parent.is_dir(): |
846 | with bb.utils.umask(0o002): | 847 | shared_umask = bb.utils.to_filemode(d.getVar("OE_SHARED_UMASK")) |
848 | with bb.utils.umask(shared_umask): | ||
847 | bb.utils.mkdirhier(str(sstate_pkg.parent)) | 849 | bb.utils.mkdirhier(str(sstate_pkg.parent)) |
848 | 850 | ||
849 | if sign_pkg: | 851 | if sign_pkg: |
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 @@ | |||
1 | addtask do_update_modules after do_configure | ||
2 | do_update_modules[nostamp] = "1" | ||
3 | do_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 | |||
15 | python 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" | |||
23 | inherit go | 23 | inherit go |
24 | 24 | ||
25 | export GOMODCACHE = "${S}/pkg/mod" | 25 | export GOMODCACHE = "${S}/pkg/mod" |
26 | GO_MOD_CACHE_DIR = "${@os.path.relpath(d.getVar('GOMODCACHE'), d.getVar('WORKDIR'))}" | 26 | GO_MOD_CACHE_DIR = "${@os.path.relpath(d.getVar('GOMODCACHE'), d.getVar('UNPACKDIR'))}" |
27 | do_unpack[cleandirs] += "${GOMODCACHE}" | 27 | do_unpack[cleandirs] += "${GOMODCACHE}" |
28 | 28 | ||
29 | GO_WORKDIR ?= "${GO_IMPORT}" | 29 | GO_WORKDIR ?= "${GO_IMPORT}" |
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 | ||
20 | TESTSDK_CLASS_NAME ?= "oeqa.sdk.testsdk.TestSDK" | 20 | TESTSDK_CLASS_NAME ?= "oeqa.sdk.testsdk.TestSDK" |
21 | TESTSDKEXT_CLASS_NAME ?= "oeqa.sdkext.testsdk.TestSDKExt" | 21 | TESTSDKEXT_CLASS_NAME ?= "oeqa.sdkext.testsdk.TestSDKExt" |
22 | TESTSDK_CASE_DIRS ?= "sdk" | ||
22 | 23 | ||
23 | def import_and_run(name, d): | 24 | def import_and_run(name, d): |
24 | import importlib | 25 | import importlib |
diff --git a/meta/classes/create-spdx-2.2.bbclass b/meta/classes/create-spdx-2.2.bbclass index 6fc60a1d97..94e0108815 100644 --- a/meta/classes/create-spdx-2.2.bbclass +++ b/meta/classes/create-spdx-2.2.bbclass | |||
@@ -23,6 +23,8 @@ def get_namespace(d, name): | |||
23 | namespace_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, d.getVar("SPDX_UUID_NAMESPACE")) | 23 | namespace_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, d.getVar("SPDX_UUID_NAMESPACE")) |
24 | return "%s/%s-%s" % (d.getVar("SPDX_NAMESPACE_PREFIX"), name, str(uuid.uuid5(namespace_uuid, name))) | 24 | return "%s/%s-%s" % (d.getVar("SPDX_NAMESPACE_PREFIX"), name, str(uuid.uuid5(namespace_uuid, name))) |
25 | 25 | ||
26 | SPDX_PACKAGE_VERSION ??= "${PV}" | ||
27 | SPDX_PACKAGE_VERSION[doc] = "The version of a package, versionInfo in recipe, package and image" | ||
26 | 28 | ||
27 | def create_annotation(d, comment): | 29 | def create_annotation(d, comment): |
28 | from datetime import datetime, timezone | 30 | from datetime import datetime, timezone |
@@ -447,7 +449,7 @@ python do_create_spdx() { | |||
447 | 449 | ||
448 | recipe = oe.spdx.SPDXPackage() | 450 | recipe = oe.spdx.SPDXPackage() |
449 | recipe.name = d.getVar("PN") | 451 | recipe.name = d.getVar("PN") |
450 | recipe.versionInfo = d.getVar("PV") | 452 | recipe.versionInfo = d.getVar("SPDX_PACKAGE_VERSION") |
451 | recipe.SPDXID = oe.sbom.get_recipe_spdxid(d) | 453 | recipe.SPDXID = oe.sbom.get_recipe_spdxid(d) |
452 | recipe.supplier = d.getVar("SPDX_SUPPLIER") | 454 | recipe.supplier = d.getVar("SPDX_SUPPLIER") |
453 | if bb.data.inherits_class("native", d) or bb.data.inherits_class("cross", d): | 455 | if bb.data.inherits_class("native", d) or bb.data.inherits_class("cross", d): |
@@ -556,7 +558,7 @@ python do_create_spdx() { | |||
556 | 558 | ||
557 | spdx_package.SPDXID = oe.sbom.get_package_spdxid(pkg_name) | 559 | spdx_package.SPDXID = oe.sbom.get_package_spdxid(pkg_name) |
558 | spdx_package.name = pkg_name | 560 | spdx_package.name = pkg_name |
559 | spdx_package.versionInfo = d.getVar("PV") | 561 | spdx_package.versionInfo = d.getVar("SPDX_PACKAGE_VERSION") |
560 | spdx_package.licenseDeclared = convert_license_to_spdx(package_license, license_data, package_doc, d, found_licenses) | 562 | spdx_package.licenseDeclared = convert_license_to_spdx(package_license, license_data, package_doc, d, found_licenses) |
561 | spdx_package.supplier = d.getVar("SPDX_SUPPLIER") | 563 | spdx_package.supplier = d.getVar("SPDX_SUPPLIER") |
562 | 564 | ||
@@ -832,7 +834,7 @@ def combine_spdx(d, rootfs_name, rootfs_deploydir, rootfs_spdxid, packages, spdx | |||
832 | 834 | ||
833 | image = oe.spdx.SPDXPackage() | 835 | image = oe.spdx.SPDXPackage() |
834 | image.name = d.getVar("PN") | 836 | image.name = d.getVar("PN") |
835 | image.versionInfo = d.getVar("PV") | 837 | image.versionInfo = d.getVar("SPDX_PACKAGE_VERSION") |
836 | image.SPDXID = rootfs_spdxid | 838 | image.SPDXID = rootfs_spdxid |
837 | image.supplier = d.getVar("SPDX_SUPPLIER") | 839 | image.supplier = d.getVar("SPDX_SUPPLIER") |
838 | 840 | ||
diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf index a3300fc172..b1f8ac5b11 100644 --- a/meta/conf/bitbake.conf +++ b/meta/conf/bitbake.conf | |||
@@ -944,6 +944,8 @@ TRANSLATED_TARGET_ARCH ??= "${@d.getVar('TARGET_ARCH').replace("_", "-")}" | |||
944 | 944 | ||
945 | # Set a default umask to use for tasks for determinism | 945 | # Set a default umask to use for tasks for determinism |
946 | BB_DEFAULT_UMASK ??= "022" | 946 | BB_DEFAULT_UMASK ??= "022" |
947 | # The umask to use for shared files (e.g. DL_DIR and SSTATE_DIR) | ||
948 | OE_SHARED_UMASK ??= "002" | ||
947 | 949 | ||
948 | # Complete output from bitbake | 950 | # Complete output from bitbake |
949 | BB_CONSOLELOG ?= "${LOG_DIR}/cooker/${MACHINE}/${DATETIME}.log" | 951 | BB_CONSOLELOG ?= "${LOG_DIR}/cooker/${MACHINE}/${DATETIME}.log" |
diff --git a/meta/conf/distro/include/maintainers.inc b/meta/conf/distro/include/maintainers.inc index d94fb693e3..4d51219c94 100644 --- a/meta/conf/distro/include/maintainers.inc +++ b/meta/conf/distro/include/maintainers.inc | |||
@@ -718,6 +718,8 @@ RECIPE_MAINTAINER:pn-python3-snowballstemmer = "Tim Orling <tim.orling@konsulko. | |||
718 | RECIPE_MAINTAINER:pn-python3-sortedcontainers = "Tim Orling <tim.orling@konsulko.com>" | 718 | RECIPE_MAINTAINER:pn-python3-sortedcontainers = "Tim Orling <tim.orling@konsulko.com>" |
719 | RECIPE_MAINTAINER:pn-python3-spdx-tools = "Marta Rybczynska <marta.rybczynska@ygreky.com>" | 719 | RECIPE_MAINTAINER:pn-python3-spdx-tools = "Marta Rybczynska <marta.rybczynska@ygreky.com>" |
720 | RECIPE_MAINTAINER:pn-python3-sphinx = "Trevor Gamblin <tgamblin@baylibre.com>" | 720 | RECIPE_MAINTAINER:pn-python3-sphinx = "Trevor Gamblin <tgamblin@baylibre.com>" |
721 | RECIPE_MAINTAINER:pn-python3-sphinx-argparse = "Antonin Godard <antonin.godard@bootlin.com>" | ||
722 | RECIPE_MAINTAINER:pn-python3-sphinx-copybutton = "Antonin Godard <antonin.godard@bootlin.com>" | ||
721 | RECIPE_MAINTAINER:pn-python3-sphinx-rtd-theme = "Tim Orling <tim.orling@konsulko.com>" | 723 | RECIPE_MAINTAINER:pn-python3-sphinx-rtd-theme = "Tim Orling <tim.orling@konsulko.com>" |
722 | RECIPE_MAINTAINER:pn-python3-sphinxcontrib-applehelp = "Tim Orling <tim.orling@konsulko.com>" | 724 | RECIPE_MAINTAINER:pn-python3-sphinxcontrib-applehelp = "Tim Orling <tim.orling@konsulko.com>" |
723 | RECIPE_MAINTAINER:pn-python3-sphinxcontrib-devhelp = "Tim Orling <tim.orling@konsulko.com>" | 725 | RECIPE_MAINTAINER:pn-python3-sphinxcontrib-devhelp = "Tim Orling <tim.orling@konsulko.com>" |
diff --git a/meta/conf/distro/include/ptest-packagelists.inc b/meta/conf/distro/include/ptest-packagelists.inc index e06731ece7..4253c7b062 100644 --- a/meta/conf/distro/include/ptest-packagelists.inc +++ b/meta/conf/distro/include/ptest-packagelists.inc | |||
@@ -78,6 +78,7 @@ PTESTS_FAST = "\ | |||
78 | python3-uritools \ | 78 | python3-uritools \ |
79 | python3-wcwidth \ | 79 | python3-wcwidth \ |
80 | python3-webcolors \ | 80 | python3-webcolors \ |
81 | python3-wheel \ | ||
81 | qemu \ | 82 | qemu \ |
82 | quilt \ | 83 | quilt \ |
83 | rpm-sequoia \ | 84 | rpm-sequoia \ |
diff --git a/meta/conf/sanity.conf b/meta/conf/sanity.conf index 3692007e96..474816797a 100644 --- a/meta/conf/sanity.conf +++ b/meta/conf/sanity.conf | |||
@@ -3,7 +3,7 @@ | |||
3 | # See sanity.bbclass | 3 | # See sanity.bbclass |
4 | # | 4 | # |
5 | # Expert users can confirm their sanity with "touch conf/sanity.conf" | 5 | # Expert users can confirm their sanity with "touch conf/sanity.conf" |
6 | BB_MIN_VERSION = "2.15.0" | 6 | BB_MIN_VERSION = "2.15.1" |
7 | 7 | ||
8 | SANITY_ABIFILE = "${TMPDIR}/abi_version" | 8 | SANITY_ABIFILE = "${TMPDIR}/abi_version" |
9 | 9 | ||
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py index 6f882c3812..6e55fa1e7f 100644 --- a/meta/lib/oe/license.py +++ b/meta/lib/oe/license.py | |||
@@ -462,3 +462,18 @@ def skip_incompatible_package_licenses(d, pkgs): | |||
462 | skipped_pkgs[pkg] = incompatible_lic | 462 | skipped_pkgs[pkg] = incompatible_lic |
463 | 463 | ||
464 | return skipped_pkgs | 464 | return skipped_pkgs |
465 | |||
466 | def tidy_licenses(value): | ||
467 | """ | ||
468 | Flat, split and sort licenses. | ||
469 | """ | ||
470 | from oe.license import flattened_licenses | ||
471 | |||
472 | def _choose(a, b): | ||
473 | str_a, str_b = sorted((" & ".join(a), " & ".join(b)), key=str.casefold) | ||
474 | return ["(%s | %s)" % (str_a, str_b)] | ||
475 | |||
476 | if not isinstance(value, str): | ||
477 | value = " & ".join(value) | ||
478 | |||
479 | return sorted(list(set(flattened_licenses(value, _choose))), key=str.casefold) | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-docs-cases/README b/meta/lib/oeqa/buildtools-docs/cases/README index f8edbc7dad..f8edbc7dad 100644 --- a/meta/lib/oeqa/sdk/buildtools-docs-cases/README +++ b/meta/lib/oeqa/buildtools-docs/cases/README | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-docs-cases/build.py b/meta/lib/oeqa/buildtools-docs/cases/build.py index 6e3ee94292..6e3ee94292 100644 --- a/meta/lib/oeqa/sdk/buildtools-docs-cases/build.py +++ b/meta/lib/oeqa/buildtools-docs/cases/build.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/README b/meta/lib/oeqa/buildtools/cases/README index d4f20faa9f..d4f20faa9f 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/README +++ b/meta/lib/oeqa/buildtools/cases/README | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/build.py b/meta/lib/oeqa/buildtools/cases/build.py index c85c32496b..c85c32496b 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/build.py +++ b/meta/lib/oeqa/buildtools/cases/build.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/gcc.py b/meta/lib/oeqa/buildtools/cases/gcc.py index a62c4d0bc4..a62c4d0bc4 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/gcc.py +++ b/meta/lib/oeqa/buildtools/cases/gcc.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/https.py b/meta/lib/oeqa/buildtools/cases/https.py index 4525e3d758..4525e3d758 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/https.py +++ b/meta/lib/oeqa/buildtools/cases/https.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/sanity.py b/meta/lib/oeqa/buildtools/cases/sanity.py index a55d456656..a55d456656 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/sanity.py +++ b/meta/lib/oeqa/buildtools/cases/sanity.py | |||
diff --git a/meta/lib/oeqa/sdk/testsdk.py b/meta/lib/oeqa/sdk/testsdk.py index 52b702b6a2..cffcf9f49a 100644 --- a/meta/lib/oeqa/sdk/testsdk.py +++ b/meta/lib/oeqa/sdk/testsdk.py | |||
@@ -31,6 +31,28 @@ class TestSDK(TestSDKBase): | |||
31 | context_class = OESDKTestContext | 31 | context_class = OESDKTestContext |
32 | test_type = 'sdk' | 32 | test_type = 'sdk' |
33 | 33 | ||
34 | def sdk_dir_names(self, d): | ||
35 | """Return list from TESTSDK_CASE_DIRS.""" | ||
36 | testdirs = d.getVar("TESTSDK_CASE_DIRS") | ||
37 | if testdirs: | ||
38 | return testdirs.split() | ||
39 | |||
40 | bb.fatal("TESTSDK_CASE_DIRS unset, can't find SDK test directories.") | ||
41 | |||
42 | def get_sdk_paths(self, d): | ||
43 | """ | ||
44 | Return a list of paths where SDK test cases reside. | ||
45 | |||
46 | SDK tests are expected in <LAYER_DIR>/lib/oeqa/<dirname>/cases | ||
47 | """ | ||
48 | paths = [] | ||
49 | for layer in d.getVar("BBLAYERS").split(): | ||
50 | for dirname in self.sdk_dir_names(d): | ||
51 | case_path = os.path.join(layer, "lib", "oeqa", dirname, "cases") | ||
52 | if os.path.isdir(case_path): | ||
53 | paths.append(case_path) | ||
54 | return paths | ||
55 | |||
34 | def get_tcname(self, d): | 56 | def get_tcname(self, d): |
35 | """ | 57 | """ |
36 | Get the name of the SDK file | 58 | Get the name of the SDK file |
@@ -115,7 +137,7 @@ class TestSDK(TestSDKBase): | |||
115 | 137 | ||
116 | try: | 138 | try: |
117 | modules = (d.getVar("TESTSDK_SUITES") or "").split() | 139 | modules = (d.getVar("TESTSDK_SUITES") or "").split() |
118 | tc.loadTests(self.context_executor_class.default_cases, modules) | 140 | tc.loadTests(self.get_sdk_paths(d), modules) |
119 | except Exception as e: | 141 | except Exception as e: |
120 | import traceback | 142 | import traceback |
121 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) | 143 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) |
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 74a7727cc0..05f228f03e 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py | |||
@@ -154,7 +154,7 @@ class DevtoolTestCase(OESelftestTestCase): | |||
154 | value = invalue | 154 | value = invalue |
155 | invar = None | 155 | invar = None |
156 | elif '=' in line: | 156 | elif '=' in line: |
157 | splitline = line.split('=', 1) | 157 | splitline = re.split(r"[?+:]*=[+]?", line, 1) |
158 | var = splitline[0].rstrip() | 158 | var = splitline[0].rstrip() |
159 | value = splitline[1].strip().strip('"') | 159 | value = splitline[1].strip().strip('"') |
160 | if value.endswith('\\'): | 160 | if value.endswith('\\'): |
diff --git a/meta/lib/oeqa/selftest/cases/recipetool.py b/meta/lib/oeqa/selftest/cases/recipetool.py index 2a91f6c7ae..0bd724c8ee 100644 --- a/meta/lib/oeqa/selftest/cases/recipetool.py +++ b/meta/lib/oeqa/selftest/cases/recipetool.py | |||
@@ -757,13 +757,12 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
757 | 757 | ||
758 | def test_recipetool_create_go(self): | 758 | def test_recipetool_create_go(self): |
759 | # Basic test to check go recipe generation | 759 | # Basic test to check go recipe generation |
760 | self.maxDiff = None | ||
761 | |||
760 | temprecipe = os.path.join(self.tempdir, 'recipe') | 762 | temprecipe = os.path.join(self.tempdir, 'recipe') |
761 | os.makedirs(temprecipe) | 763 | os.makedirs(temprecipe) |
762 | 764 | ||
763 | recipefile = os.path.join(temprecipe, 'recipetool-go-test_git.bb') | 765 | recipefile = os.path.join(temprecipe, 'recipetool-go-test_git.bb') |
764 | deps_require_file = os.path.join(temprecipe, 'recipetool-go-test', 'recipetool-go-test-modules.inc') | ||
765 | lics_require_file = os.path.join(temprecipe, 'recipetool-go-test', 'recipetool-go-test-licenses.inc') | ||
766 | modules_txt_file = os.path.join(temprecipe, 'recipetool-go-test', 'modules.txt') | ||
767 | 766 | ||
768 | srcuri = 'https://git.yoctoproject.org/recipetool-go-test.git' | 767 | srcuri = 'https://git.yoctoproject.org/recipetool-go-test.git' |
769 | srcrev = "c3e213c01b6c1406b430df03ef0d1ae77de5d2f7" | 768 | srcrev = "c3e213c01b6c1406b430df03ef0d1ae77de5d2f7" |
@@ -771,13 +770,11 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
771 | 770 | ||
772 | result = runCmd('recipetool create -o %s %s -S %s -B %s' % (temprecipe, srcuri, srcrev, srcbranch)) | 771 | result = runCmd('recipetool create -o %s %s -S %s -B %s' % (temprecipe, srcuri, srcrev, srcbranch)) |
773 | 772 | ||
774 | self.maxDiff = None | 773 | inherits = ['go-mod', 'go-mod-update-modules'] |
775 | inherits = ['go-vendor'] | ||
776 | 774 | ||
777 | checkvars = {} | 775 | checkvars = {} |
778 | checkvars['GO_IMPORT'] = "git.yoctoproject.org/recipetool-go-test" | 776 | checkvars['GO_IMPORT'] = "git.yoctoproject.org/recipetool-go-test" |
779 | checkvars['SRC_URI'] = {'git://${GO_IMPORT};destsuffix=git/src/${GO_IMPORT};nobranch=1;name=${BPN};protocol=https', | 777 | checkvars['SRC_URI'] = {'git://${GO_IMPORT};protocol=https;nobranch=1;destsuffix=${GO_SRCURI_DESTSUFFIX}'} |
780 | 'file://modules.txt'} | ||
781 | checkvars['LIC_FILES_CHKSUM'] = { | 778 | checkvars['LIC_FILES_CHKSUM'] = { |
782 | 'file://src/${GO_IMPORT}/LICENSE;md5=4e3933dd47afbf115e484d11385fb3bd', | 779 | 'file://src/${GO_IMPORT}/LICENSE;md5=4e3933dd47afbf115e484d11385fb3bd', |
783 | 'file://src/${GO_IMPORT}/is/LICENSE;md5=62beaee5a116dd1e80161667b1df39ab' | 780 | 'file://src/${GO_IMPORT}/is/LICENSE;md5=62beaee5a116dd1e80161667b1df39ab' |
@@ -786,26 +783,16 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
786 | self._test_recipe_contents(recipefile, checkvars, inherits) | 783 | self._test_recipe_contents(recipefile, checkvars, inherits) |
787 | self.assertNotIn('Traceback', result.output) | 784 | self.assertNotIn('Traceback', result.output) |
788 | 785 | ||
786 | lics_require_file = os.path.join(temprecipe, 'recipetool-go-test-licenses.inc') | ||
787 | self.assertFileExists(lics_require_file) | ||
789 | checkvars = {} | 788 | checkvars = {} |
790 | checkvars['VENDORED_LIC_FILES_CHKSUM'] = set( | 789 | checkvars['LIC_FILES_CHKSUM'] = {'file://pkg/mod/github.com/godbus/dbus/v5@v5.1.0/LICENSE;md5=09042bd5c6c96a2b9e45ddf1bc517eed;spdx=BSD-2-Clause'} |
791 | ['file://src/${GO_IMPORT}/vendor/github.com/godbus/dbus/v5/LICENSE;md5=09042bd5c6c96a2b9e45ddf1bc517eed', | ||
792 | 'file://src/${GO_IMPORT}/vendor/github.com/matryer/is/LICENSE;md5=62beaee5a116dd1e80161667b1df39ab']) | ||
793 | self.assertTrue(os.path.isfile(lics_require_file)) | ||
794 | self._test_recipe_contents(lics_require_file, checkvars, []) | 790 | self._test_recipe_contents(lics_require_file, checkvars, []) |
795 | 791 | ||
796 | # make sure that dependencies don't mention local directory ./matryer/is | 792 | deps_require_file = os.path.join(temprecipe, 'recipetool-go-test-go-mods.inc') |
797 | dependencies = \ | 793 | self.assertFileExists(deps_require_file) |
798 | [ ('github.com/godbus/dbus','v5.1.0', 'github.com/godbus/dbus/v5', '/v5', ''), | ||
799 | ] | ||
800 | |||
801 | src_uri = set() | ||
802 | for d in dependencies: | ||
803 | src_uri.add(self._go_urifiy(*d)) | ||
804 | |||
805 | checkvars = {} | 794 | checkvars = {} |
806 | checkvars['GO_DEPENDENCIES_SRC_URI'] = src_uri | 795 | checkvars['SRC_URI'] = {'gomod://github.com/godbus/dbus/v5;version=v5.1.0;sha256sum=03dfa8e71089a6f477310d15c4d3a036d82d028532881b50fee254358e782ad9'} |
807 | |||
808 | self.assertTrue(os.path.isfile(deps_require_file)) | ||
809 | self._test_recipe_contents(deps_require_file, checkvars, []) | 796 | self._test_recipe_contents(deps_require_file, checkvars, []) |
810 | 797 | ||
811 | class RecipetoolTests(RecipetoolBase): | 798 | class RecipetoolTests(RecipetoolBase): |
diff --git a/meta/recipes-core/meta/buildtools-docs-tarball.bb b/meta/recipes-core/meta/buildtools-docs-tarball.bb index b9ef68eb6d..98d47f7b71 100644 --- a/meta/recipes-core/meta/buildtools-docs-tarball.bb +++ b/meta/recipes-core/meta/buildtools-docs-tarball.bb | |||
@@ -7,6 +7,8 @@ LICENSE = "MIT" | |||
7 | # Add nativesdk equivalent of build-essentials | 7 | # Add nativesdk equivalent of build-essentials |
8 | TOOLCHAIN_HOST_TASK += "\ | 8 | TOOLCHAIN_HOST_TASK += "\ |
9 | nativesdk-python3-sphinx \ | 9 | nativesdk-python3-sphinx \ |
10 | nativesdk-python3-sphinx-argparse \ | ||
11 | nativesdk-python3-sphinx-copybutton \ | ||
10 | nativesdk-python3-sphinx-rtd-theme \ | 12 | nativesdk-python3-sphinx-rtd-theme \ |
11 | nativesdk-python3-pyyaml \ | 13 | nativesdk-python3-pyyaml \ |
12 | nativesdk-rsvg \ | 14 | nativesdk-rsvg \ |
@@ -16,4 +18,5 @@ TOOLCHAIN_OUTPUTNAME = "${SDK_ARCH}-buildtools-docs-nativesdk-standalone-${DISTR | |||
16 | 18 | ||
17 | SDK_TITLE = "Docs Build tools tarball" | 19 | SDK_TITLE = "Docs Build tools tarball" |
18 | 20 | ||
19 | TESTSDK_CASES = "buildtools-docs-cases" | 21 | # Directory that contains testcases |
22 | TESTSDK_CASE_DIRS = "buildtools-docs" \ No newline at end of file | ||
diff --git a/meta/recipes-core/meta/buildtools-tarball.bb b/meta/recipes-core/meta/buildtools-tarball.bb index 6fa6d93a3d..02117ab84d 100644 --- a/meta/recipes-core/meta/buildtools-tarball.bb +++ b/meta/recipes-core/meta/buildtools-tarball.bb | |||
@@ -124,22 +124,7 @@ TOOLCHAIN_NEED_CONFIGSITE_CACHE = "" | |||
124 | # The recipe doesn't need any default deps | 124 | # The recipe doesn't need any default deps |
125 | INHIBIT_DEFAULT_DEPS = "1" | 125 | INHIBIT_DEFAULT_DEPS = "1" |
126 | 126 | ||
127 | # Directory in testsdk that contains testcases | 127 | inherit testsdk |
128 | TESTSDK_CASES = "buildtools-cases" | ||
129 | 128 | ||
130 | # We have our own code, avoid deferred inherit | 129 | # Directory that contains testcases |
131 | SDK_CLASSES:remove = "testsdk" | 130 | TESTSDK_CASE_DIRS = "buildtools" \ No newline at end of file |
132 | |||
133 | python do_testsdk() { | ||
134 | import oeqa.sdk.testsdk | ||
135 | testsdk = oeqa.sdk.testsdk.TestSDK() | ||
136 | |||
137 | cases_path = os.path.join(os.path.abspath(os.path.dirname(oeqa.sdk.testsdk.__file__)), d.getVar("TESTSDK_CASES")) | ||
138 | testsdk.context_executor_class.default_cases = [cases_path,] | ||
139 | |||
140 | testsdk.run(d) | ||
141 | } | ||
142 | addtask testsdk | ||
143 | do_testsdk[nostamp] = "1" | ||
144 | do_testsdk[network] = "1" | ||
145 | do_testsdk[depends] += "xz-native:do_populate_sysroot" | ||
diff --git a/meta/recipes-devtools/dosfstools/dosfstools/0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch b/meta/recipes-devtools/dosfstools/dosfstools/0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch new file mode 100644 index 0000000000..3d2ce48723 --- /dev/null +++ b/meta/recipes-devtools/dosfstools/dosfstools/0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch | |||
@@ -0,0 +1,214 @@ | |||
1 | From 9d165145b9f9c20a56e111360fbc2003c2b28cba Mon Sep 17 00:00:00 2001 | ||
2 | From: Ricardo Simoes <ricardo.simoes@pt.bosch.com> | ||
3 | Date: Thu, 26 Jun 2025 08:14:29 +0100 | ||
4 | Subject: [PATCH] fsck.fat: Adhere to the fsck exit codes | ||
5 | |||
6 | fsck.fat is used as a filesystem-specific checker for the `fsck`. This | ||
7 | also causes `fsck` to return the same exit-codes given by `fsck.fat`. | ||
8 | |||
9 | In most cases this is already the case. One exception to that comes when | ||
10 | checking a read-only filesystem. In that case `fsck.fat` will return 6, | ||
11 | which for `fsck` means "Fiesystem errors left uncorrected" and "System | ||
12 | should reboot". When a more proper response would be to return 8, | ||
13 | "Operational Error". | ||
14 | |||
15 | This commit solves that problem by introducing a new header file which | ||
16 | standardizes the exit codes used by `fsck.fat`. | ||
17 | |||
18 | Signed-off-by: Ricardo Ungerer <ungerer.ricardo@gmail.com> | ||
19 | |||
20 | Upstream-Status: Inactive-Upstream [lastcommit: 2023, lastrelease: 2021] | ||
21 | Upstream-Status: Submitted [https://github.com/dosfstools/dosfstools/pull/217] | ||
22 | --- | ||
23 | src/Makefile.am | 4 ++-- | ||
24 | src/common.c | 8 ++++---- | ||
25 | src/exit_codes.h | 15 +++++++++++++++ | ||
26 | src/fsck.fat.c | 23 ++++++++++++----------- | ||
27 | src/io.c | 3 ++- | ||
28 | 5 files changed, 35 insertions(+), 18 deletions(-) | ||
29 | create mode 100644 src/exit_codes.h | ||
30 | |||
31 | diff --git a/src/Makefile.am b/src/Makefile.am | ||
32 | index a389046..48f00dd 100644 | ||
33 | --- a/src/Makefile.am | ||
34 | +++ b/src/Makefile.am | ||
35 | @@ -23,7 +23,7 @@ EXTRA_DIST = blkdev/README | ||
36 | |||
37 | charconv_common_sources = charconv.c charconv.h | ||
38 | charconv_common_ldadd = $(LIBICONV) | ||
39 | -fscklabel_common_sources = boot.c boot.h common.c common.h \ | ||
40 | +fscklabel_common_sources = boot.c boot.h common.c common.h exit_codes.h \ | ||
41 | fat.c fat.h io.c io.h msdos_fs.h \ | ||
42 | $(charconv_common_sources) \ | ||
43 | fsck.fat.h endian_compat.h | ||
44 | @@ -38,7 +38,7 @@ devinfo_common_sources = device_info.c device_info.h \ | ||
45 | blkdev/blkdev.c blkdev/blkdev.h \ | ||
46 | blkdev/linux_version.c blkdev/linux_version.h | ||
47 | mkfs_fat_SOURCES = mkfs.fat.c msdos_fs.h common.c common.h endian_compat.h \ | ||
48 | - $(charconv_common_sources) $(devinfo_common_sources) | ||
49 | + exit_codes.h $(charconv_common_sources) $(devinfo_common_sources) | ||
50 | mkfs_fat_CPPFLAGS = -I$(srcdir)/blkdev | ||
51 | mkfs_fat_CFLAGS = $(AM_CFLAGS) | ||
52 | mkfs_fat_LDADD = $(charconv_common_ldadd) | ||
53 | diff --git a/src/common.c b/src/common.c | ||
54 | index 4f1afcb..089d4b3 100644 | ||
55 | --- a/src/common.c | ||
56 | +++ b/src/common.c | ||
57 | @@ -38,7 +38,7 @@ | ||
58 | |||
59 | #include "common.h" | ||
60 | #include "charconv.h" | ||
61 | - | ||
62 | +#include "exit_codes.h" | ||
63 | |||
64 | int interactive; | ||
65 | int write_immed; | ||
66 | @@ -62,7 +62,7 @@ void die(const char *msg, ...) | ||
67 | vfprintf(stderr, msg, args); | ||
68 | va_end(args); | ||
69 | fprintf(stderr, "\n"); | ||
70 | - exit(1); | ||
71 | + exit(OPERATIONAL_ERROR); | ||
72 | } | ||
73 | |||
74 | void pdie(const char *msg, ...) | ||
75 | @@ -205,7 +205,7 @@ int get_choice(int noninteractive_result, const char *noninteractive_msg, | ||
76 | } while (choice == '\n'); /* filter out enter presses */ | ||
77 | |||
78 | if (choice == EOF) | ||
79 | - exit(1); | ||
80 | + exit(USAGE_OR_SYNTAX_ERROR); | ||
81 | |||
82 | printf("%c\n", choice); | ||
83 | |||
84 | @@ -235,7 +235,7 @@ int get_choice(int noninteractive_result, const char *noninteractive_msg, | ||
85 | inhibit_quit_choice = 0; | ||
86 | |||
87 | if (quit_choice == 1) | ||
88 | - exit(0); | ||
89 | + exit(NO_ERRORS); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | diff --git a/src/exit_codes.h b/src/exit_codes.h | ||
94 | new file mode 100644 | ||
95 | index 0000000..f67d22e | ||
96 | --- /dev/null | ||
97 | +++ b/src/exit_codes.h | ||
98 | @@ -0,0 +1,15 @@ | ||
99 | +#ifndef _EXIT_CODES_H | ||
100 | +#define _EXIT_CODES_H | ||
101 | + | ||
102 | +/* Codes as defined by fsck. | ||
103 | + For more information, see fsck manpage. */ | ||
104 | +#define NO_ERRORS 0 | ||
105 | +#define FS_ERRORS_CORRECTED 1 | ||
106 | +#define SYSTEM_SHOULD_BE_REBOOTED 2 | ||
107 | +#define FS_ERRORS_LEFT_UNCORRECTED 4 | ||
108 | +#define OPERATIONAL_ERROR 8 | ||
109 | +#define USAGE_OR_SYNTAX_ERROR 16 | ||
110 | +#define CHECKING_CANCELED_BY_USER 32 | ||
111 | +#define SHARED_LIB_ERROR 128 | ||
112 | + | ||
113 | +#endif | ||
114 | diff --git a/src/fsck.fat.c b/src/fsck.fat.c | ||
115 | index 8b02b57..42e3ab4 100644 | ||
116 | --- a/src/fsck.fat.c | ||
117 | +++ b/src/fsck.fat.c | ||
118 | @@ -46,6 +46,7 @@ | ||
119 | #include "file.h" | ||
120 | #include "check.h" | ||
121 | #include "charconv.h" | ||
122 | +#include "exit_codes.h" | ||
123 | |||
124 | int rw = 0, list = 0, test = 0, verbose = 0; | ||
125 | long fat_table = 0; | ||
126 | @@ -147,10 +148,10 @@ int main(int argc, char **argv) | ||
127 | codepage = strtol(optarg, &tmp, 10); | ||
128 | if (!*optarg || isspace(*optarg) || *tmp || errno || codepage < 0 || codepage > INT_MAX) { | ||
129 | fprintf(stderr, "Invalid codepage : %s\n", optarg); | ||
130 | - usage(argv[0], 2); | ||
131 | + usage(argv[0], USAGE_OR_SYNTAX_ERROR); | ||
132 | } | ||
133 | if (!set_dos_codepage(codepage)) | ||
134 | - usage(argv[0], 2); | ||
135 | + usage(argv[0], USAGE_OR_SYNTAX_ERROR); | ||
136 | break; | ||
137 | case 'd': | ||
138 | file_add(optarg, fdt_drop); | ||
139 | @@ -163,7 +164,7 @@ int main(int argc, char **argv) | ||
140 | fat_table = strtol(optarg, &tmp, 10); | ||
141 | if (!*optarg || isspace(*optarg) || *tmp || errno || fat_table < 0 || fat_table > 255) { | ||
142 | fprintf(stderr, "Invalid FAT table : %s\n", optarg); | ||
143 | - usage(argv[0], 2); | ||
144 | + usage(argv[0], USAGE_OR_SYNTAX_ERROR); | ||
145 | } | ||
146 | break; | ||
147 | case 'l': | ||
148 | @@ -202,31 +203,31 @@ int main(int argc, char **argv) | ||
149 | atari_format = 1; | ||
150 | } else { | ||
151 | fprintf(stderr, "Unknown variant: %s\n", optarg); | ||
152 | - usage(argv[0], 2); | ||
153 | + usage(argv[0], USAGE_OR_SYNTAX_ERROR); | ||
154 | } | ||
155 | break; | ||
156 | case 'w': | ||
157 | write_immed = 1; | ||
158 | break; | ||
159 | case OPT_HELP: | ||
160 | - usage(argv[0], 0); | ||
161 | + usage(argv[0], EXIT_SUCCESS); | ||
162 | break; | ||
163 | case '?': | ||
164 | - usage(argv[0], 2); | ||
165 | + usage(argv[0], USAGE_OR_SYNTAX_ERROR); | ||
166 | break; | ||
167 | default: | ||
168 | fprintf(stderr, | ||
169 | "Internal error: getopt_long() returned unexpected value %d\n", c); | ||
170 | - exit(3); | ||
171 | + exit(OPERATIONAL_ERROR); | ||
172 | } | ||
173 | if (!set_dos_codepage(-1)) /* set default codepage if none was given in command line */ | ||
174 | - exit(2); | ||
175 | + exit(OPERATIONAL_ERROR); | ||
176 | if ((test || write_immed) && !rw) { | ||
177 | fprintf(stderr, "-t and -w can not be used in read only mode\n"); | ||
178 | - exit(2); | ||
179 | + exit(USAGE_OR_SYNTAX_ERROR); | ||
180 | } | ||
181 | if (optind != argc - 1) | ||
182 | - usage(argv[0], 2); | ||
183 | + usage(argv[0], USAGE_OR_SYNTAX_ERROR); | ||
184 | |||
185 | printf("fsck.fat " VERSION " (" VERSION_DATE ")\n"); | ||
186 | fs_open(argv[optind], rw); | ||
187 | @@ -285,5 +286,5 @@ exit: | ||
188 | n_files, (unsigned long)fs.data_clusters - free_clusters, | ||
189 | (unsigned long)fs.data_clusters); | ||
190 | |||
191 | - return fs_close(rw) ? 1 : 0; | ||
192 | + return fs_close(rw) ? FS_ERRORS_CORRECTED : NO_ERRORS; | ||
193 | } | ||
194 | diff --git a/src/io.c b/src/io.c | ||
195 | index 8c0c3b2..8bd1ae5 100644 | ||
196 | --- a/src/io.c | ||
197 | +++ b/src/io.c | ||
198 | @@ -44,6 +44,7 @@ | ||
199 | #include "fsck.fat.h" | ||
200 | #include "common.h" | ||
201 | #include "io.h" | ||
202 | +#include "exit_codes.h" | ||
203 | |||
204 | typedef struct _change { | ||
205 | void *data; | ||
206 | @@ -60,7 +61,7 @@ void fs_open(const char *path, int rw) | ||
207 | { | ||
208 | if ((fd = open(path, rw ? O_RDWR : O_RDONLY)) < 0) { | ||
209 | perror("open"); | ||
210 | - exit(6); | ||
211 | + exit(OPERATIONAL_ERROR); | ||
212 | } | ||
213 | changes = last = NULL; | ||
214 | did_change = 0; | ||
diff --git a/meta/recipes-devtools/dosfstools/dosfstools/0002-manpages-Document-fsck.fat-new-exit-codes.patch b/meta/recipes-devtools/dosfstools/dosfstools/0002-manpages-Document-fsck.fat-new-exit-codes.patch new file mode 100644 index 0000000000..29bba7b093 --- /dev/null +++ b/meta/recipes-devtools/dosfstools/dosfstools/0002-manpages-Document-fsck.fat-new-exit-codes.patch | |||
@@ -0,0 +1,46 @@ | |||
1 | From 8d703216d2ea3247092a08adb0c37b38eb77ccc7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ricardo Ungerer <ungerer.ricardo@gmail.com> | ||
3 | Date: Wed, 21 May 2025 07:18:15 +0100 | ||
4 | Subject: [PATCH 2/3] manpages: Document fsck.fat new exit codes | ||
5 | |||
6 | Signed-off-by: Ricardo Ungerer <ungerer.ricardo@gmail.com> | ||
7 | |||
8 | Upstream-Status: Inactive-Upstream [lastcommit: 2023, lastrelease: 2021] | ||
9 | Upstream-Status: Submitted [https://github.com/dosfstools/dosfstools/pull/217] | ||
10 | --- | ||
11 | manpages/fsck.fat.8.in | 18 +++++++++++++----- | ||
12 | 1 file changed, 13 insertions(+), 5 deletions(-) | ||
13 | |||
14 | diff --git a/manpages/fsck.fat.8.in b/manpages/fsck.fat.8.in | ||
15 | index 824a83d..557aa4c 100644 | ||
16 | --- a/manpages/fsck.fat.8.in | ||
17 | +++ b/manpages/fsck.fat.8.in | ||
18 | @@ -222,13 +222,21 @@ Display help message describing usage and options then exit. | ||
19 | .\" ---------------------------------------------------------------------------- | ||
20 | .SH "EXIT STATUS" | ||
21 | .IP "0" 4 | ||
22 | -No recoverable errors have been detected. | ||
23 | +No errors | ||
24 | .IP "1" 4 | ||
25 | -Recoverable errors have been detected or \fBfsck.fat\fP has discovered an | ||
26 | -internal inconsistency. | ||
27 | +Filesystem errors corrected | ||
28 | .IP "2" 4 | ||
29 | -Usage error. | ||
30 | -\fBfsck.fat\fP did not access the filesystem. | ||
31 | +System should be rebooted | ||
32 | +.IP "4" 4 | ||
33 | +Filesystem errors left uncorrected | ||
34 | +.IP "8" 4 | ||
35 | +Operational error | ||
36 | +.IP "16" 4 | ||
37 | +Usage or syntax error | ||
38 | +.IP "32" 4 | ||
39 | +Checking canceled by user request | ||
40 | +.IP "128" 4 | ||
41 | +Shared-library error | ||
42 | .\" ---------------------------------------------------------------------------- | ||
43 | .SH FILES | ||
44 | .IP "\fIfsck0000.rec\fP, \fIfsck0001.rec\fP, ..." 4 | ||
45 | -- | ||
46 | 2.25.1 | ||
diff --git a/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb b/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb index 175fa265ef..86fb68f664 100644 --- a/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb +++ b/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb | |||
@@ -10,11 +10,12 @@ LICENSE = "GPL-3.0-only" | |||
10 | LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" | 10 | LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" |
11 | 11 | ||
12 | SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/${BP}.tar.gz \ | 12 | SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/${BP}.tar.gz \ |
13 | " | 13 | file://source-date-epoch.patch \ |
14 | file://0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch \ | ||
15 | file://0002-manpages-Document-fsck.fat-new-exit-codes.patch \ | ||
16 | " | ||
14 | SRC_URI[sha256sum] = "64926eebf90092dca21b14259a5301b7b98e7b1943e8a201c7d726084809b527" | 17 | SRC_URI[sha256sum] = "64926eebf90092dca21b14259a5301b7b98e7b1943e8a201c7d726084809b527" |
15 | 18 | ||
16 | SRC_URI += "file://source-date-epoch.patch" | ||
17 | |||
18 | inherit autotools gettext pkgconfig update-alternatives github-releases | 19 | inherit autotools gettext pkgconfig update-alternatives github-releases |
19 | 20 | ||
20 | EXTRA_OECONF = "--enable-compat-symlinks --without-iconv" | 21 | EXTRA_OECONF = "--enable-compat-symlinks --without-iconv" |
diff --git a/meta/recipes-devtools/json-c/json-c_0.18.bb b/meta/recipes-devtools/json-c/json-c_0.18.bb index ece320d66c..c112aacf4b 100644 --- a/meta/recipes-devtools/json-c/json-c_0.18.bb +++ b/meta/recipes-devtools/json-c/json-c_0.18.bb | |||
@@ -19,8 +19,7 @@ UPSTREAM_CHECK_REGEX = "json-c-(?P<pver>\d+(\.\d+)+)-\d+" | |||
19 | 19 | ||
20 | RPROVIDES:${PN} = "libjson" | 20 | RPROVIDES:${PN} = "libjson" |
21 | 21 | ||
22 | # - '-Werror' must be disabled for ICECC builds | 22 | # Apps aren't needed/packaged and their CMakeLists.txt is incompatible with CMake 4+. |
23 | # - Apps aren't needed/packaged and their CMakeLists.txt is incompatible with CMake 4+. | ||
24 | EXTRA_OECMAKE = "-DDISABLE_WERROR=ON \ | 23 | EXTRA_OECMAKE = "-DDISABLE_WERROR=ON \ |
25 | -DBUILD_APPS=OFF \ | 24 | -DBUILD_APPS=OFF \ |
26 | " | 25 | " |
diff --git a/meta/recipes-devtools/mtools/mtools_4.0.48.bb b/meta/recipes-devtools/mtools/mtools_4.0.49.bb index 646735f3b3..294b2f37b2 100644 --- a/meta/recipes-devtools/mtools/mtools_4.0.48.bb +++ b/meta/recipes-devtools/mtools/mtools_4.0.49.bb | |||
@@ -24,7 +24,7 @@ RRECOMMENDS:${PN}:libc-glibc = "\ | |||
24 | glibc-gconv-ibm866 \ | 24 | glibc-gconv-ibm866 \ |
25 | glibc-gconv-ibm869 \ | 25 | glibc-gconv-ibm869 \ |
26 | " | 26 | " |
27 | SRC_URI[sha256sum] = "03c29aac8735dd7154a989fbc29eaf2b506121ae1c3a35cd0bf2a02e94d271a9" | 27 | SRC_URI[sha256sum] = "6fe5193583d6e7c59da75e63d7234f76c0b07caf33b103894f46f66a871ffc9f" |
28 | 28 | ||
29 | SRC_URI = "${GNU_MIRROR}/mtools/mtools-${PV}.tar.bz2 \ | 29 | SRC_URI = "${GNU_MIRROR}/mtools/mtools-${PV}.tar.bz2 \ |
30 | file://mtools-makeinfo.patch \ | 30 | file://mtools-makeinfo.patch \ |
diff --git a/meta/recipes-devtools/ninja/ninja_1.12.1.bb b/meta/recipes-devtools/ninja/ninja_1.13.0.bb index 5aff82edec..a5fa8f1c9e 100644 --- a/meta/recipes-devtools/ninja/ninja_1.12.1.bb +++ b/meta/recipes-devtools/ninja/ninja_1.13.0.bb | |||
@@ -1,14 +1,18 @@ | |||
1 | SUMMARY = "Ninja is a small build system with a focus on speed." | 1 | SUMMARY = "Ninja is a small build system with a focus on speed." |
2 | HOMEPAGE = "https://ninja-build.org/" | 2 | HOMEPAGE = "https://ninja-build.org/" |
3 | DESCRIPTION = "Ninja is a small build system with a focus on speed. It differs from other build systems in two major respects: it is designed to have its input files generated by a higher-level build system, and it is designed to run builds as fast as possible." | 3 | DESCRIPTION = "Ninja is a small build system with a focus on speed. \ |
4 | It differs from other build systems in two major respects: \ | ||
5 | it is designed to have its input files generated by a higher-level build system, \ | ||
6 | and it is designed to run builds as fast as possible." | ||
7 | |||
4 | LICENSE = "Apache-2.0" | 8 | LICENSE = "Apache-2.0" |
5 | LIC_FILES_CHKSUM = "file://COPYING;md5=a81586a64ad4e476c791cda7e2f2c52e" | 9 | LIC_FILES_CHKSUM = "file://COPYING;md5=a81586a64ad4e476c791cda7e2f2c52e" |
6 | 10 | ||
7 | DEPENDS = "re2c-native ninja-native" | 11 | DEPENDS = "re2c-native ninja-native" |
8 | 12 | ||
9 | SRCREV = "2daa09ba270b0a43e1929d29b073348aa985dfaa" | 13 | SRCREV = "b4d51f6ed5bed09dd2b70324df0d9cb4ecad2638" |
10 | 14 | ||
11 | SRC_URI = "git://github.com/ninja-build/ninja.git;branch=release;protocol=https" | 15 | SRC_URI = "git://github.com/ninja-build/ninja.git;branch=release;protocol=https;tag=v${PV}" |
12 | UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>.*)" | 16 | UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>.*)" |
13 | 17 | ||
14 | do_configure[noexec] = "1" | 18 | do_configure[noexec] = "1" |
diff --git a/meta/recipes-devtools/python/python3-sphinx-argparse_0.5.2.bb b/meta/recipes-devtools/python/python3-sphinx-argparse_0.5.2.bb new file mode 100644 index 0000000000..554fb3eb51 --- /dev/null +++ b/meta/recipes-devtools/python/python3-sphinx-argparse_0.5.2.bb | |||
@@ -0,0 +1,13 @@ | |||
1 | SUMMARY = "A sphinx extension that automatically documents argparse commands and options" | ||
2 | HOMEPAGE = "https://sphinx-argparse.readthedocs.io/" | ||
3 | LICENSE = "MIT" | ||
4 | LIC_FILES_CHKSUM = "file://LICENCE.rst;md5=5c1cd8f13774629fee215681e66a1056" | ||
5 | |||
6 | SRC_URI[sha256sum] = "e5352f8fa894b6fb6fda0498ba28a9f8d435971ef4bbc1a6c9c6414e7644f032" | ||
7 | |||
8 | PYPI_PACKAGE = "sphinx_argparse" | ||
9 | UPSTREAM_CHECK_PYPI_PACKAGE = "${PYPI_PACKAGE}" | ||
10 | |||
11 | inherit pypi python_flit_core | ||
12 | |||
13 | BBCLASSEXTEND = "native nativesdk" | ||
diff --git a/meta/recipes-devtools/python/python3-sphinx-copybutton_0.5.2.bb b/meta/recipes-devtools/python/python3-sphinx-copybutton_0.5.2.bb new file mode 100644 index 0000000000..0441804661 --- /dev/null +++ b/meta/recipes-devtools/python/python3-sphinx-copybutton_0.5.2.bb | |||
@@ -0,0 +1,10 @@ | |||
1 | SUMMARY = "Add a copy button to code blocks in Sphinx" | ||
2 | HOMEPAGE = "https://sphinx-copybutton.readthedocs.io" | ||
3 | LICENSE = "MIT" | ||
4 | LIC_FILES_CHKSUM = "file://LICENSE;md5=c60e920848b6d2ecec51ea44a1a33bf0" | ||
5 | |||
6 | SRC_URI[sha256sum] = "4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd" | ||
7 | |||
8 | inherit setuptools3 pypi | ||
9 | |||
10 | BBCLASSEXTEND = "native nativesdk" | ||
diff --git a/meta/recipes-devtools/python/python3-urllib3_2.4.0.bb b/meta/recipes-devtools/python/python3-urllib3_2.5.0.bb index 7a4bffc05e..a4f3995730 100644 --- a/meta/recipes-devtools/python/python3-urllib3_2.4.0.bb +++ b/meta/recipes-devtools/python/python3-urllib3_2.5.0.bb | |||
@@ -3,7 +3,7 @@ HOMEPAGE = "https://github.com/urllib3/urllib3" | |||
3 | LICENSE = "MIT" | 3 | LICENSE = "MIT" |
4 | LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=52d273a3054ced561275d4d15260ecda" | 4 | LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=52d273a3054ced561275d4d15260ecda" |
5 | 5 | ||
6 | SRC_URI[sha256sum] = "414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466" | 6 | SRC_URI[sha256sum] = "3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760" |
7 | 7 | ||
8 | inherit pypi python_hatchling | 8 | inherit pypi python_hatchling |
9 | 9 | ||
diff --git a/meta/recipes-devtools/python/python3-wheel_0.45.1.bb b/meta/recipes-devtools/python/python3-wheel_0.46.1.bb index 8274e83747..058af2f0e7 100644 --- a/meta/recipes-devtools/python/python3-wheel_0.45.1.bb +++ b/meta/recipes-devtools/python/python3-wheel_0.46.1.bb | |||
@@ -4,9 +4,14 @@ SECTION = "devel/python" | |||
4 | LICENSE = "MIT" | 4 | LICENSE = "MIT" |
5 | LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=7ffb0db04527cfe380e4f2726bd05ebf" | 5 | LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=7ffb0db04527cfe380e4f2726bd05ebf" |
6 | 6 | ||
7 | SRC_URI[sha256sum] = "661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729" | 7 | SRC_URI[sha256sum] = "fd477efb5da0f7df1d3c76c73c14394002c844451bd63229d8570f376f5e6a38" |
8 | 8 | ||
9 | inherit python_flit_core pypi | 9 | inherit python_flit_core pypi ptest-python-pytest |
10 | |||
11 | RDEPENDS:${PN} += "python3-packaging" | ||
12 | |||
13 | # One test is skipped but requires the "full" python3-flit, not just python3-flit-core | ||
14 | RDEPENDS:${PN}-ptest += "python3-setuptools" | ||
10 | 15 | ||
11 | BBCLASSEXTEND = "native nativesdk" | 16 | BBCLASSEXTEND = "native nativesdk" |
12 | 17 | ||
diff --git a/meta/recipes-devtools/tcf-agent/tcf-agent_1.8.0.bb b/meta/recipes-devtools/tcf-agent/tcf-agent_1.8.0.bb index 1639ae84e9..f008c0c6de 100644 --- a/meta/recipes-devtools/tcf-agent/tcf-agent_1.8.0.bb +++ b/meta/recipes-devtools/tcf-agent/tcf-agent_1.8.0.bb | |||
@@ -49,6 +49,12 @@ CFLAGS:append:riscv64 = " ${LCL_STOP_SERVICES}" | |||
49 | CFLAGS:append:riscv32 = " ${LCL_STOP_SERVICES}" | 49 | CFLAGS:append:riscv32 = " ${LCL_STOP_SERVICES}" |
50 | CFLAGS:append:loongarch64 = " ${LCL_STOP_SERVICES}" | 50 | CFLAGS:append:loongarch64 = " ${LCL_STOP_SERVICES}" |
51 | 51 | ||
52 | # This works with gcc-ranlib wrapper only because it exists without error if nothing | ||
53 | # is passed as argument but binutils ranlib and llvm ranlib do not and expect an input | ||
54 | # passing $@ ensures that Makefile default target which is the archive name in tcf makefiles | ||
55 | # is passed to RANLIB, ensures that whichever ranlib is used, the behavior is identical | ||
56 | RANLIB:append = " $@" | ||
57 | |||
52 | do_install() { | 58 | do_install() { |
53 | oe_runmake install INSTALLROOT=${D} | 59 | oe_runmake install INSTALLROOT=${D} |
54 | install -d ${D}${sysconfdir}/init.d/ | 60 | install -d ${D}${sysconfdir}/init.d/ |