kbuild-fixes needs to be based on 6.19 to apply some fixes for 62089b804895 ("kbuild: rpm-pkg: Generate debuginfo package manually") which landed in 6.19-rc1 but the new material of 7.0 needs fixes merged as well.
Showing the changes to scripts (41 of 63 files). Show all
Unified · Split
| @@ -73,8 +73,6 @@ rustc-llvm-version := $(shell,$(srctree)/scripts/rustc-llvm-version.sh $(RUSTC)) · 72 unmodified lines | |||
| 73 | 73 | ||
| 74 | # $(rustc-option,<flag>) | 74 | # $(rustc-option,<flag>) |
| 75 | # Return y if the Rust compiler supports <flag>, n otherwise | 75 | # Return y if the Rust compiler supports <flag>, n otherwise |
| 76 | # Calls to this should be guarded so that they are not evaluated if | ||
| 77 | # CONFIG_RUST_IS_AVAILABLE is not set. | ||
| 78 | # If you are testing for unstable features, consider testing RUSTC_VERSION | 76 | # If you are testing for unstable features, consider testing RUSTC_VERSION |
| 79 | # instead, as features may have different completeness while available. | 77 | # instead, as features may have different completeness while available. |
| 80 | rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib) | 78 | rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib) |
| @@ -400,7 +400,7 @@ FIT_COMPRESSION ?= gzip · 399 unmodified lines | |||
| 400 | 400 | ||
| 401 | quiet_cmd_fit = FIT $@ | 401 | quiet_cmd_fit = FIT $@ |
| 402 | cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ | 402 | cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ |
| 403 | --name '$(UIMAGE_NAME)' \ | 403 | --name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \ |
| 404 | $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ | 404 | $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ |
| 405 | $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ | 405 | $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ |
| 406 | --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) | 406 | --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) |
| @@ -201,7 +201,6 @@ quiet_cmd_cpio = CPIO $@ · 200 unmodified lines | |||
| 201 | cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $< | 201 | cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $< |
| 202 | 202 | ||
| 203 | modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio | 203 | modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio |
| 204 | $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio | ||
| 205 | $(call cmd,cpio) | 204 | $(call cmd,cpio) |
| 206 | 205 | ||
| 207 | PHONY += modules-cpio-pkg | 206 | PHONY += modules-cpio-pkg |
| @@ -16,7 +16,7 @@ KBUILD_CFLAGS += -Werror=return-type · 15 unmodified lines | |||
| 16 | KBUILD_CFLAGS += -Werror=strict-prototypes | 16 | KBUILD_CFLAGS += -Werror=strict-prototypes |
| 17 | KBUILD_CFLAGS += -Wno-format-security | 17 | KBUILD_CFLAGS += -Wno-format-security |
| 18 | KBUILD_CFLAGS += -Wno-trigraphs | 18 | KBUILD_CFLAGS += -Wno-trigraphs |
| 19 | KBUILD_CFLAGS += $(call cc-option, -Wno-frame-address) | 19 | KBUILD_CFLAGS += -Wno-frame-address |
| 20 | KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member) | 20 | KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member) |
| 21 | KBUILD_CFLAGS += -Wmissing-declarations | 21 | KBUILD_CFLAGS += -Wmissing-declarations |
| 22 | KBUILD_CFLAGS += -Wmissing-prototypes | 22 | KBUILD_CFLAGS += -Wmissing-prototypes |
| @@ -55,6 +55,9 @@ else · 32 unmodified lines | |||
| 55 | KBUILD_CFLAGS += -Wno-main | 55 | KBUILD_CFLAGS += -Wno-main |
| 56 | endif | 56 | endif |
| 57 | 57 | ||
| 58 | # Too noisy on range checks and in macros handling both signed and unsigned. | ||
| 59 | KBUILD_CFLAGS += -Wno-type-limits | ||
| 60 | |||
| 58 | # These result in bogus false positives | 61 | # These result in bogus false positives |
| 59 | KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer) | 62 | KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer) |
| 60 | 63 | ||
| @@ -72,7 +75,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign · 11 unmodified lines | |||
| 72 | # In order to make sure new function cast mismatches are not introduced | 75 | # In order to make sure new function cast mismatches are not introduced |
| 73 | # in the kernel (to avoid tripping CFI checking), the kernel should be | 76 | # in the kernel (to avoid tripping CFI checking), the kernel should be |
| 74 | # globally built with -Wcast-function-type. | 77 | # globally built with -Wcast-function-type. |
| 75 | KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type) | 78 | KBUILD_CFLAGS += -Wcast-function-type |
| 76 | 79 | ||
| 77 | # Currently, disable -Wstringop-overflow for GCC 11, globally. | 80 | # Currently, disable -Wstringop-overflow for GCC 11, globally. |
| 78 | KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) | 81 | KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) |
| @@ -99,7 +102,7 @@ KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) · 20 unmodified lines | |||
| 99 | KBUILD_CFLAGS += -Werror=date-time | 102 | KBUILD_CFLAGS += -Werror=date-time |
| 100 | 103 | ||
| 101 | # enforce correct pointer usage | 104 | # enforce correct pointer usage |
| 102 | KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) | 105 | KBUILD_CFLAGS += -Werror=incompatible-pointer-types |
| 103 | 106 | ||
| 104 | # Require designated initializers for all marked structures | 107 | # Require designated initializers for all marked structures |
| 105 | KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) | 108 | KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) |
| @@ -116,7 +119,7 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) · 10 unmodified lines | |||
| 116 | 119 | ||
| 117 | KBUILD_CFLAGS += -Wmissing-format-attribute | 120 | KBUILD_CFLAGS += -Wmissing-format-attribute |
| 118 | KBUILD_CFLAGS += -Wmissing-include-dirs | 121 | KBUILD_CFLAGS += -Wmissing-include-dirs |
| 119 | KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable) | 122 | KBUILD_CFLAGS += -Wunused-const-variable |
| 120 | 123 | ||
| 121 | KBUILD_CPPFLAGS += -Wundef | 124 | KBUILD_CPPFLAGS += -Wundef |
| 122 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 | 125 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 |
| @@ -125,12 +128,12 @@ else · 2 unmodified lines | |||
| 125 | 128 | ||
| 126 | # Some diagnostics enabled by default are noisy. | 129 | # Some diagnostics enabled by default are noisy. |
| 127 | # Suppress them by using -Wno... except for W=1. | 130 | # Suppress them by using -Wno... except for W=1. |
| 128 | KBUILD_CFLAGS += $(call cc-option, -Wno-unused-but-set-variable) | 131 | KBUILD_CFLAGS += -Wno-unused-but-set-variable |
| 129 | KBUILD_CFLAGS += $(call cc-option, -Wno-unused-const-variable) | 132 | KBUILD_CFLAGS += -Wno-unused-const-variable |
| 130 | KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned) | 133 | KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned) |
| 131 | KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow) | 134 | KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow) |
| 132 | ifdef CONFIG_CC_IS_GCC | 135 | ifdef CONFIG_CC_IS_GCC |
| 133 | KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation) | 136 | KBUILD_CFLAGS += -Wno-format-truncation |
| 134 | endif | 137 | endif |
| 135 | KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation) | 138 | KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation) |
| 136 | 139 | ||
| @@ -145,14 +148,11 @@ KBUILD_CFLAGS += -Wno-format · 8 unmodified lines | |||
| 145 | # problematic. | 148 | # problematic. |
| 146 | KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier | 149 | KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier |
| 147 | KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull | 150 | KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull |
| 148 | # Requires clang-12+. | ||
| 149 | ifeq ($(call clang-min-version, 120000),y) | ||
| 150 | KBUILD_CFLAGS += -Wformat-insufficient-args | 151 | KBUILD_CFLAGS += -Wformat-insufficient-args |
| 151 | endif | 152 | endif |
| 152 | endif | 153 | KBUILD_CFLAGS += -Wno-pointer-to-enum-cast |
| 153 | KBUILD_CFLAGS += $(call cc-option, -Wno-pointer-to-enum-cast) | ||
| 154 | KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare | 154 | KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare |
| 155 | KBUILD_CFLAGS += $(call cc-option, -Wno-unaligned-access) | 155 | KBUILD_CFLAGS += -Wno-unaligned-access |
| 156 | KBUILD_CFLAGS += -Wno-enum-compare-conditional | 156 | KBUILD_CFLAGS += -Wno-enum-compare-conditional |
| 157 | endif | 157 | endif |
| 158 | 158 | ||
| @@ -166,7 +166,7 @@ ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) · 7 unmodified lines | |||
| 166 | KBUILD_CFLAGS += -Wdisabled-optimization | 166 | KBUILD_CFLAGS += -Wdisabled-optimization |
| 167 | KBUILD_CFLAGS += -Wshadow | 167 | KBUILD_CFLAGS += -Wshadow |
| 168 | KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) | 168 | KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) |
| 169 | KBUILD_CFLAGS += $(call cc-option, -Wunused-macros) | 169 | KBUILD_CFLAGS += -Wunused-macros |
| 170 | 170 | ||
| 171 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 | 171 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 |
| 172 | 172 | ||
| @@ -174,7 +174,6 @@ else · 1 unmodified line | |||
| 174 | 174 | ||
| 175 | # The following turn off the warnings enabled by -Wextra | 175 | # The following turn off the warnings enabled by -Wextra |
| 176 | KBUILD_CFLAGS += -Wno-missing-field-initializers | 176 | KBUILD_CFLAGS += -Wno-missing-field-initializers |
| 177 | KBUILD_CFLAGS += -Wno-type-limits | ||
| 178 | KBUILD_CFLAGS += -Wno-shift-negative-value | 177 | KBUILD_CFLAGS += -Wno-shift-negative-value |
| 179 | 178 | ||
| 180 | ifdef CONFIG_CC_IS_CLANG | 179 | ifdef CONFIG_CC_IS_CLANG |
| @@ -0,0 +1,199 @@ | |||
| 1 | #!/usr/bin/env python3 | ||
| 2 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 3 | # Copyright (C) 2025 Guillaume Tucker | ||
| 4 | |||
| 5 | """Containerized builds""" | ||
| 6 | |||
| 7 | import abc | ||
| 8 | import argparse | ||
| 9 | import logging | ||
| 10 | import os | ||
| 11 | import pathlib | ||
| 12 | import shutil | ||
| 13 | import subprocess | ||
| 14 | import sys | ||
| 15 | import uuid | ||
| 16 | |||
| 17 | |||
| 18 | class ContainerRuntime(abc.ABC): | ||
| 19 | """Base class for a container runtime implementation""" | ||
| 20 | |||
| 21 | name = None # Property defined in each implementation class | ||
| 22 | |||
| 23 | def __init__(self, args, logger): | ||
| 24 | self._uid = args.uid or os.getuid() | ||
| 25 | self._gid = args.gid or args.uid or os.getgid() | ||
| 26 | self._env_file = args.env_file | ||
| 27 | self._shell = args.shell | ||
| 28 | self._logger = logger | ||
| 29 | |||
| 30 | @classmethod | ||
| 31 | def is_present(cls): | ||
| 32 | """Determine whether the runtime is present on the system""" | ||
| 33 | return shutil.which(cls.name) is not None | ||
| 34 | |||
| 35 | @abc.abstractmethod | ||
| 36 | def _do_run(self, image, cmd, container_name): | ||
| 37 | """Runtime-specific handler to run a command in a container""" | ||
| 38 | |||
| 39 | @abc.abstractmethod | ||
| 40 | def _do_abort(self, container_name): | ||
| 41 | """Runtime-specific handler to abort a running container""" | ||
| 42 | |||
| 43 | def run(self, image, cmd): | ||
| 44 | """Run a command in a runtime container""" | ||
| 45 | container_name = str(uuid.uuid4()) | ||
| 46 | self._logger.debug("container: %s", container_name) | ||
| 47 | try: | ||
| 48 | return self._do_run(image, cmd, container_name) | ||
| 49 | except KeyboardInterrupt: | ||
| 50 | self._logger.error("user aborted") | ||
| 51 | self._do_abort(container_name) | ||
| 52 | return 1 | ||
| 53 | |||
| 54 | |||
| 55 | class CommonRuntime(ContainerRuntime): | ||
| 56 | """Common logic for Docker and Podman""" | ||
| 57 | |||
| 58 | def _do_run(self, image, cmd, container_name): | ||
| 59 | cmdline = [self.name, 'run'] | ||
| 60 | cmdline += self._get_opts(container_name) | ||
| 61 | cmdline.append(image) | ||
| 62 | cmdline += cmd | ||
| 63 | self._logger.debug('command: %s', ' '.join(cmdline)) | ||
| 64 | return subprocess.call(cmdline) | ||
| 65 | |||
| 66 | def _get_opts(self, container_name): | ||
| 67 | opts = [ | ||
| 68 | '--name', container_name, | ||
| 69 | '--rm', | ||
| 70 | '--volume', f'{pathlib.Path.cwd()}:/src', | ||
| 71 | '--workdir', '/src', | ||
| 72 | ] | ||
| 73 | if self._env_file: | ||
| 74 | opts += ['--env-file', self._env_file] | ||
| 75 | if self._shell: | ||
| 76 | opts += ['--interactive', '--tty'] | ||
| 77 | return opts | ||
| 78 | |||
| 79 | def _do_abort(self, container_name): | ||
| 80 | subprocess.call([self.name, 'kill', container_name]) | ||
| 81 | |||
| 82 | |||
| 83 | class DockerRuntime(CommonRuntime): | ||
| 84 | """Run a command in a Docker container""" | ||
| 85 | |||
| 86 | name = 'docker' | ||
| 87 | |||
| 88 | def _get_opts(self, container_name): | ||
| 89 | return super()._get_opts(container_name) + [ | ||
| 90 | '--user', f'{self._uid}:{self._gid}' | ||
| 91 | ] | ||
| 92 | |||
| 93 | |||
| 94 | class PodmanRuntime(CommonRuntime): | ||
| 95 | """Run a command in a Podman container""" | ||
| 96 | |||
| 97 | name = 'podman' | ||
| 98 | |||
| 99 | def _get_opts(self, container_name): | ||
| 100 | return super()._get_opts(container_name) + [ | ||
| 101 | '--userns', f'keep-id:uid={self._uid},gid={self._gid}', | ||
| 102 | ] | ||
| 103 | |||
| 104 | |||
| 105 | class Runtimes: | ||
| 106 | """List of all supported runtimes""" | ||
| 107 | |||
| 108 | runtimes = [PodmanRuntime, DockerRuntime] | ||
| 109 | |||
| 110 | @classmethod | ||
| 111 | def get_names(cls): | ||
| 112 | """Get a list of all the runtime names""" | ||
| 113 | return list(runtime.name for runtime in cls.runtimes) | ||
| 114 | |||
| 115 | @classmethod | ||
| 116 | def get(cls, name): | ||
| 117 | """Get a single runtime class matching the given name""" | ||
| 118 | for runtime in cls.runtimes: | ||
| 119 | if runtime.name == name: | ||
| 120 | if not runtime.is_present(): | ||
| 121 | raise ValueError(f"runtime not found: {name}") | ||
| 122 | return runtime | ||
| 123 | raise ValueError(f"unknown runtime: {name}") | ||
| 124 | |||
| 125 | @classmethod | ||
| 126 | def find(cls): | ||
| 127 | """Find the first runtime present on the system""" | ||
| 128 | for runtime in cls.runtimes: | ||
| 129 | if runtime.is_present(): | ||
| 130 | return runtime | ||
| 131 | raise ValueError("no runtime found") | ||
| 132 | |||
| 133 | |||
| 134 | def _get_logger(verbose): | ||
| 135 | """Set up a logger with the appropriate level""" | ||
| 136 | logger = logging.getLogger('container') | ||
| 137 | handler = logging.StreamHandler() | ||
| 138 | handler.setFormatter(logging.Formatter( | ||
| 139 | fmt='[container {levelname}] {message}', style='{' | ||
| 140 | )) | ||
| 141 | logger.addHandler(handler) | ||
| 142 | logger.setLevel(logging.DEBUG if verbose is True else logging.INFO) | ||
| 143 | return logger | ||
| 144 | |||
| 145 | |||
| 146 | def main(args): | ||
| 147 | """Main entry point for the container tool""" | ||
| 148 | logger = _get_logger(args.verbose) | ||
| 149 | try: | ||
| 150 | cls = Runtimes.get(args.runtime) if args.runtime else Runtimes.find() | ||
| 151 | except ValueError as ex: | ||
| 152 | logger.error(ex) | ||
| 153 | return 1 | ||
| 154 | logger.debug("runtime: %s", cls.name) | ||
| 155 | logger.debug("image: %s", args.image) | ||
| 156 | return cls(args, logger).run(args.image, args.cmd) | ||
| 157 | |||
| 158 | |||
| 159 | if __name__ == '__main__': | ||
| 160 | parser = argparse.ArgumentParser( | ||
| 161 | 'container', | ||
| 162 | description="See the documentation for more details: " | ||
| 163 | "https://docs.kernel.org/dev-tools/container.html" | ||
| 164 | ) | ||
| 165 | parser.add_argument( | ||
| 166 | '-e', '--env-file', | ||
| 167 | help="Path to an environment file to load in the container." | ||
| 168 | ) | ||
| 169 | parser.add_argument( | ||
| 170 | '-g', '--gid', | ||
| 171 | help="Group ID to use inside the container." | ||
| 172 | ) | ||
| 173 | parser.add_argument( | ||
| 174 | '-i', '--image', required=True, | ||
| 175 | help="Container image name." | ||
| 176 | ) | ||
| 177 | parser.add_argument( | ||
| 178 | '-r', '--runtime', choices=Runtimes.get_names(), | ||
| 179 | help="Container runtime name. If not specified, the first one found " | ||
| 180 | "on the system will be used i.e. Podman if present, otherwise Docker." | ||
| 181 | ) | ||
| 182 | parser.add_argument( | ||
| 183 | '-s', '--shell', action='store_true', | ||
| 184 | help="Run the container in an interactive shell." | ||
| 185 | ) | ||
| 186 | parser.add_argument( | ||
| 187 | '-u', '--uid', | ||
| 188 | help="User ID to use inside the container. If the -g option is not " | ||
| 189 | "specified, the user ID will also be set as the group ID." | ||
| 190 | ) | ||
| 191 | parser.add_argument( | ||
| 192 | '-v', '--verbose', action='store_true', | ||
| 193 | help="Enable verbose output." | ||
| 194 | ) | ||
| 195 | parser.add_argument( | ||
| 196 | 'cmd', nargs='+', | ||
| 197 | help="Command to run in the container" | ||
| 198 | ) | ||
| 199 | sys.exit(main(parser.parse_args(sys.argv[1:]))) | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 3 | |||
| 4 | true | ||
| @@ -46,7 +46,6 @@ struct addr_range { · 45 unmodified lines | |||
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | static unsigned long long _text; | 48 | static unsigned long long _text; |
| 49 | static unsigned long long relative_base; | ||
| 50 | static struct addr_range text_ranges[] = { | 49 | static struct addr_range text_ranges[] = { |
| 51 | { "_stext", "_etext" }, | 50 | { "_stext", "_etext" }, |
| 52 | { "_sinittext", "_einittext" }, | 51 | { "_sinittext", "_einittext" }, |
| @@ -57,6 +56,7 @@ static struct addr_range text_ranges[] = { · 4 unmodified lines | |||
| 57 | static struct sym_entry **table; | 56 | static struct sym_entry **table; |
| 58 | static unsigned int table_size, table_cnt; | 57 | static unsigned int table_size, table_cnt; |
| 59 | static int all_symbols; | 58 | static int all_symbols; |
| 59 | static int pc_relative; | ||
| 60 | 60 | ||
| 61 | static int token_profit[0x10000]; | 61 | static int token_profit[0x10000]; |
| 62 | 62 | ||
| @@ -280,7 +280,7 @@ static void read_map(const char *in) · 217 unmodified lines | |||
| 280 | static void output_label(const char *label) | 280 | static void output_label(const char *label) |
| 281 | { | 281 | { |
| 282 | printf(".globl %s\n", label); | 282 | printf(".globl %s\n", label); |
| 283 | printf("\tALGN\n"); | 283 | printf("\t.balign 4\n"); |
| 284 | printf("%s:\n", label); | 284 | printf("%s:\n", label); |
| 285 | } | 285 | } |
| 286 | 286 | ||
| @@ -343,15 +343,6 @@ static void write_src(void) · 56 unmodified lines | |||
| 343 | unsigned int *markers, markers_cnt; | 343 | unsigned int *markers, markers_cnt; |
| 344 | char buf[KSYM_NAME_LEN]; | 344 | char buf[KSYM_NAME_LEN]; |
| 345 | 345 | ||
| 346 | printf("#include <asm/bitsperlong.h>\n"); | ||
| 347 | printf("#if BITS_PER_LONG == 64\n"); | ||
| 348 | printf("#define PTR .quad\n"); | ||
| 349 | printf("#define ALGN .balign 8\n"); | ||
| 350 | printf("#else\n"); | ||
| 351 | printf("#define PTR .long\n"); | ||
| 352 | printf("#define ALGN .balign 4\n"); | ||
| 353 | printf("#endif\n"); | ||
| 354 | |||
| 355 | printf("\t.section .rodata, \"a\"\n"); | 346 | printf("\t.section .rodata, \"a\"\n"); |
| 356 | 347 | ||
| 357 | output_label("kallsyms_num_syms"); | 348 | output_label("kallsyms_num_syms"); |
| @@ -434,34 +425,24 @@ static void write_src(void) · 76 unmodified lines | |||
| 434 | output_label("kallsyms_offsets"); | 425 | output_label("kallsyms_offsets"); |
| 435 | 426 | ||
| 436 | for (i = 0; i < table_cnt; i++) { | 427 | for (i = 0; i < table_cnt; i++) { |
| 437 | /* | 428 | if (pc_relative) { |
| 438 | * Use the offset relative to the lowest value | 429 | long long offset = table[i]->addr - _text; |
| 439 | * encountered of all relative symbols, and emit | 430 | |
| 440 | * non-relocatable fixed offsets that will be fixed | 431 | if (offset < INT_MIN || offset > INT_MAX) { |
| 441 | * up at runtime. | 432 | fprintf(stderr, "kallsyms failure: " |
| 442 | */ | 433 | "relative symbol value %#llx out of range\n", |
| 443 | 434 | table[i]->addr); | |
| 444 | long long offset; | 435 | exit(EXIT_FAILURE); |
| 445 | 436 | } | |
| 446 | offset = table[i]->addr - relative_base; | 437 | printf("\t.long\t_text - . + (%d)\t/* %s */\n", |
| 447 | if (offset < 0 || offset > UINT_MAX) { | 438 | (int)offset, table[i]->sym); |
| 448 | fprintf(stderr, "kallsyms failure: " | 439 | } else { |
| 449 | "relative symbol value %#llx out of range\n", | 440 | printf("\t.long\t%#x\t/* %s */\n", |
| 450 | table[i]->addr); | 441 | (unsigned int)table[i]->addr, table[i]->sym); |
| 451 | exit(EXIT_FAILURE); | ||
| 452 | } | 442 | } |
| 453 | printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym); | ||
| 454 | } | 443 | } |
| 455 | printf("\n"); | 444 | printf("\n"); |
| 456 | 445 | ||
| 457 | output_label("kallsyms_relative_base"); | ||
| 458 | /* Provide proper symbols relocatability by their '_text' relativeness. */ | ||
| 459 | if (_text <= relative_base) | ||
| 460 | printf("\tPTR\t_text + %#llx\n", relative_base - _text); | ||
| 461 | else | ||
| 462 | printf("\tPTR\t_text - %#llx\n", _text - relative_base); | ||
| 463 | printf("\n"); | ||
| 464 | |||
| 465 | sort_symbols_by_name(); | 446 | sort_symbols_by_name(); |
| 466 | output_label("kallsyms_seqs_of_names"); | 447 | output_label("kallsyms_seqs_of_names"); |
| 467 | for (i = 0; i < table_cnt; i++) | 448 | for (i = 0; i < table_cnt; i++) |
| @@ -701,22 +682,12 @@ static void sort_symbols(void) · 233 unmodified lines | |||
| 701 | qsort(table, table_cnt, sizeof(table[0]), compare_symbols); | 682 | qsort(table, table_cnt, sizeof(table[0]), compare_symbols); |
| 702 | } | 683 | } |
| 703 | 684 | ||
| 704 | /* find the minimum non-absolute symbol address */ | ||
| 705 | static void record_relative_base(void) | ||
| 706 | { | ||
| 707 | /* | ||
| 708 | * The table is sorted by address. | ||
| 709 | * Take the first symbol value. | ||
| 710 | */ | ||
| 711 | if (table_cnt) | ||
| 712 | relative_base = table[0]->addr; | ||
| 713 | } | ||
| 714 | |||
| 715 | int main(int argc, char **argv) | 685 | int main(int argc, char **argv) |
| 716 | { | 686 | { |
| 717 | while (1) { | 687 | while (1) { |
| 718 | static const struct option long_options[] = { | 688 | static const struct option long_options[] = { |
| 719 | {"all-symbols", no_argument, &all_symbols, 1}, | 689 | {"all-symbols", no_argument, &all_symbols, 1}, |
| 690 | {"pc-relative", no_argument, &pc_relative, 1}, | ||
| 720 | {}, | 691 | {}, |
| 721 | }; | 692 | }; |
| 722 | 693 | ||
| @@ -734,7 +705,6 @@ int main(int argc, char **argv) · 11 unmodified lines | |||
| 734 | read_map(argv[optind]); | 705 | read_map(argv[optind]); |
| 735 | shrink_table(); | 706 | shrink_table(); |
| 736 | sort_symbols(); | 707 | sort_symbols(); |
| 737 | record_relative_base(); | ||
| 738 | optimize_token_table(); | 708 | optimize_token_table(); |
| 739 | write_src(); | 709 | write_src(); |
| 740 | 710 | ||
| @@ -201,7 +201,7 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): | $(obj)/mconf-cflags · 200 unmodified lines | |||
| 201 | # qconf: Used for the xconfig target based on Qt | 201 | # qconf: Used for the xconfig target based on Qt |
| 202 | hostprogs += qconf | 202 | hostprogs += qconf |
| 203 | qconf-cxxobjs := qconf.o qconf-moc.o | 203 | qconf-cxxobjs := qconf.o qconf-moc.o |
| 204 | qconf-objs := images.o $(common-objs) | 204 | qconf-objs := $(common-objs) |
| 205 | 205 | ||
| 206 | HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs) | 206 | HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs) |
| 207 | HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags) | 207 | HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags) |
| @@ -219,7 +219,7 @@ targets += qconf-moc.cc · 11 unmodified lines | |||
| 219 | 219 | ||
| 220 | # gconf: Used for the gconfig target based on GTK+ | 220 | # gconf: Used for the gconfig target based on GTK+ |
| 221 | hostprogs += gconf | 221 | hostprogs += gconf |
| 222 | gconf-objs := gconf.o images.o $(common-objs) | 222 | gconf-objs := gconf.o $(common-objs) |
| 223 | 223 | ||
| 224 | HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs) | 224 | HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs) |
| 225 | HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags) | 225 | HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags) |
| @@ -5,7 +5,6 @@ · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| 7 | #include "lkc.h" | 7 | #include "lkc.h" |
| 8 | #include "images.h" | ||
| 9 | 8 | ||
| 10 | #include <gtk/gtk.h> | 9 | #include <gtk/gtk.h> |
| 11 | 10 | ||
| @@ -951,12 +950,24 @@ static void fixup_rootmenu(struct menu *menu) · 939 unmodified lines | |||
| 951 | } | 950 | } |
| 952 | 951 | ||
| 953 | /* Main Window Initialization */ | 952 | /* Main Window Initialization */ |
| 954 | static void replace_button_icon(GtkWidget *widget, const char * const xpm[]) | 953 | static void replace_button_icon(GtkWidget *widget, const char *filename) |
| 955 | { | 954 | { |
| 956 | GdkPixbuf *pixbuf; | 955 | GdkPixbuf *pixbuf; |
| 957 | GtkWidget *image; | 956 | GtkWidget *image; |
| 957 | GError *err = NULL; | ||
| 958 | |||
| 959 | char *env = getenv(SRCTREE); | ||
| 960 | gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/", filename, NULL); | ||
| 961 | |||
| 962 | pixbuf = gdk_pixbuf_new_from_file(path, &err); | ||
| 963 | g_free(path); | ||
| 964 | |||
| 965 | if (err) { | ||
| 966 | g_warning("Failed to load icon %s: %s", filename, err->message); | ||
| 967 | g_error_free(err); | ||
| 968 | return; | ||
| 969 | } | ||
| 958 | 970 | ||
| 959 | pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm); | ||
| 960 | image = gtk_image_new_from_pixbuf(pixbuf); | 971 | image = gtk_image_new_from_pixbuf(pixbuf); |
| 961 | g_object_unref(pixbuf); | 972 | g_object_unref(pixbuf); |
| 962 | 973 | ||
| @@ -1078,17 +1089,17 @@ static void init_main_window(const gchar *glade_file) · 115 unmodified lines | |||
| 1078 | single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); | 1089 | single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); |
| 1079 | g_signal_connect(single_btn, "clicked", | 1090 | g_signal_connect(single_btn, "clicked", |
| 1080 | G_CALLBACK(on_single_clicked), NULL); | 1091 | G_CALLBACK(on_single_clicked), NULL); |
| 1081 | replace_button_icon(single_btn, xpm_single_view); | 1092 | replace_button_icon(single_btn, "single_view.xpm"); |
| 1082 | 1093 | ||
| 1083 | split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5")); | 1094 | split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5")); |
| 1084 | g_signal_connect(split_btn, "clicked", | 1095 | g_signal_connect(split_btn, "clicked", |
| 1085 | G_CALLBACK(on_split_clicked), NULL); | 1096 | G_CALLBACK(on_split_clicked), NULL); |
| 1086 | replace_button_icon(split_btn, xpm_split_view); | 1097 | replace_button_icon(split_btn, "split_view.xpm"); |
| 1087 | 1098 | ||
| 1088 | full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6")); | 1099 | full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6")); |
| 1089 | g_signal_connect(full_btn, "clicked", | 1100 | g_signal_connect(full_btn, "clicked", |
| 1090 | G_CALLBACK(on_full_clicked), NULL); | 1101 | G_CALLBACK(on_full_clicked), NULL); |
| 1091 | replace_button_icon(full_btn, xpm_tree_view); | 1102 | replace_button_icon(full_btn, "tree_view.xpm"); |
| 1092 | 1103 | ||
| 1093 | widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7")); | 1104 | widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7")); |
| 1094 | g_signal_connect(widget, "clicked", | 1105 | g_signal_connect(widget, "clicked", |
| @@ -1269,7 +1280,17 @@ static void init_right_tree(void) · 174 unmodified lines | |||
| 1269 | g_signal_connect(G_OBJECT(renderer), "edited", | 1280 | g_signal_connect(G_OBJECT(renderer), "edited", |
| 1270 | G_CALLBACK(renderer_edited), tree2_w); | 1281 | G_CALLBACK(renderer_edited), tree2_w); |
| 1271 | 1282 | ||
| 1272 | pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu); | 1283 | char *env = getenv(SRCTREE); |
| 1284 | gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/menu.xpm", NULL); | ||
| 1285 | GError *err = NULL; | ||
| 1286 | |||
| 1287 | pix_menu = gdk_pixbuf_new_from_file(path, &err); | ||
| 1288 | g_free(path); | ||
| 1289 | |||
| 1290 | if (err) { | ||
| 1291 | g_warning("Failed to load menu icon: %s", err->message); | ||
| 1292 | g_error_free(err); | ||
| 1293 | } | ||
| 1273 | 1294 | ||
| 1274 | for (i = 0; i < COL_VALUE; i++) { | 1295 | for (i = 0; i < COL_VALUE; i++) { |
| 1275 | column = gtk_tree_view_get_column(view, i); | 1296 | column = gtk_tree_view_get_column(view, i); |
| @@ -0,0 +1,29 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * back_xpm[] = { | ||
| 3 | "22 22 3 1", | ||
| 4 | ". c None", | ||
| 5 | "# c #000083", | ||
| 6 | "a c #838183", | ||
| 7 | "......................", | ||
| 8 | "......................", | ||
| 9 | "......................", | ||
| 10 | "......................", | ||
| 11 | "......................", | ||
| 12 | "...........######a....", | ||
| 13 | "..#......##########...", | ||
| 14 | "..##...####......##a..", | ||
| 15 | "..###.###.........##..", | ||
| 16 | "..######..........##..", | ||
| 17 | "..#####...........##..", | ||
| 18 | "..######..........##..", | ||
| 19 | "..#######.........##..", | ||
| 20 | "..########.......##a..", | ||
| 21 | "...............a###...", | ||
| 22 | "...............###....", | ||
| 23 | "......................", | ||
| 24 | "......................", | ||
| 25 | "......................", | ||
| 26 | "......................", | ||
| 27 | "......................", | ||
| 28 | "......................" | ||
| 29 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * choice_no_xpm[] = { | ||
| 3 | "12 12 2 1", | ||
| 4 | " c white", | ||
| 5 | ". c black", | ||
| 6 | " ", | ||
| 7 | " .... ", | ||
| 8 | " .. .. ", | ||
| 9 | " . . ", | ||
| 10 | " . . ", | ||
| 11 | " . . ", | ||
| 12 | " . . ", | ||
| 13 | " . . ", | ||
| 14 | " . . ", | ||
| 15 | " .. .. ", | ||
| 16 | " .... ", | ||
| 17 | " " | ||
| 18 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * choice_yes_xpm[] = { | ||
| 3 | "12 12 2 1", | ||
| 4 | " c white", | ||
| 5 | ". c black", | ||
| 6 | " ", | ||
| 7 | " .... ", | ||
| 8 | " .. .. ", | ||
| 9 | " . . ", | ||
| 10 | " . .. . ", | ||
| 11 | " . .... . ", | ||
| 12 | " . .... . ", | ||
| 13 | " . .. . ", | ||
| 14 | " . . ", | ||
| 15 | " .. .. ", | ||
| 16 | " .... ", | ||
| 17 | " " | ||
| 18 | }; | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * load_xpm[] = { | ||
| 3 | "22 22 5 1", | ||
| 4 | ". c None", | ||
| 5 | "# c #000000", | ||
| 6 | "c c #838100", | ||
| 7 | "a c #ffff00", | ||
| 8 | "b c #ffffff", | ||
| 9 | "......................", | ||
| 10 | "......................", | ||
| 11 | "......................", | ||
| 12 | "............####....#.", | ||
| 13 | "...........#....##.##.", | ||
| 14 | "..................###.", | ||
| 15 | ".................####.", | ||
| 16 | ".####...........#####.", | ||
| 17 | "#abab##########.......", | ||
| 18 | "#babababababab#.......", | ||
| 19 | "#ababababababa#.......", | ||
| 20 | "#babababababab#.......", | ||
| 21 | "#ababab###############", | ||
| 22 | "#babab##cccccccccccc##", | ||
| 23 | "#abab##cccccccccccc##.", | ||
| 24 | "#bab##cccccccccccc##..", | ||
| 25 | "#ab##cccccccccccc##...", | ||
| 26 | "#b##cccccccccccc##....", | ||
| 27 | "###cccccccccccc##.....", | ||
| 28 | "##cccccccccccc##......", | ||
| 29 | "###############.......", | ||
| 30 | "......................" | ||
| 31 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * menu_xpm[] = { | ||
| 3 | "12 12 2 1", | ||
| 4 | " c white", | ||
| 5 | ". c black", | ||
| 6 | " ", | ||
| 7 | " .......... ", | ||
| 8 | " . . ", | ||
| 9 | " . .. . ", | ||
| 10 | " . .... . ", | ||
| 11 | " . ...... . ", | ||
| 12 | " . ...... . ", | ||
| 13 | " . .... . ", | ||
| 14 | " . .. . ", | ||
| 15 | " . . ", | ||
| 16 | " .......... ", | ||
| 17 | " " | ||
| 18 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * menuback_xpm[] = { | ||
| 3 | "12 12 2 1", | ||
| 4 | " c white", | ||
| 5 | ". c black", | ||
| 6 | " ", | ||
| 7 | " .......... ", | ||
| 8 | " . . ", | ||
| 9 | " . .. . ", | ||
| 10 | " . .... . ", | ||
| 11 | " . ...... . ", | ||
| 12 | " . ...... . ", | ||
| 13 | " . .... . ", | ||
| 14 | " . .. . ", | ||
| 15 | " . . ", | ||
| 16 | " .......... ", | ||
| 17 | " " | ||
| 18 | }; | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * save_xpm[] = { | ||
| 3 | "22 22 5 1", | ||
| 4 | ". c None", | ||
| 5 | "# c #000000", | ||
| 6 | "a c #838100", | ||
| 7 | "b c #c5c2c5", | ||
| 8 | "c c #cdb6d5", | ||
| 9 | "......................", | ||
| 10 | ".####################.", | ||
| 11 | ".#aa#bbbbbbbbbbbb#bb#.", | ||
| 12 | ".#aa#bbbbbbbbbbbb#bb#.", | ||
| 13 | ".#aa#bbbbbbbbbcbb####.", | ||
| 14 | ".#aa#bbbccbbbbbbb#aa#.", | ||
| 15 | ".#aa#bbbccbbbbbbb#aa#.", | ||
| 16 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 17 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 18 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 19 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 20 | ".#aaa############aaa#.", | ||
| 21 | ".#aaaaaaaaaaaaaaaaaa#.", | ||
| 22 | ".#aaaaaaaaaaaaaaaaaa#.", | ||
| 23 | ".#aaa#############aa#.", | ||
| 24 | ".#aaa#########bbb#aa#.", | ||
| 25 | ".#aaa#########bbb#aa#.", | ||
| 26 | ".#aaa#########bbb#aa#.", | ||
| 27 | ".#aaa#########bbb#aa#.", | ||
| 28 | ".#aaa#########bbb#aa#.", | ||
| 29 | "..##################..", | ||
| 30 | "......................" | ||
| 31 | }; | ||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * single_view_xpm[] = { | ||
| 3 | "22 22 2 1", | ||
| 4 | ". c None", | ||
| 5 | "# c #000000", | ||
| 6 | "......................", | ||
| 7 | "......................", | ||
| 8 | "..........#...........", | ||
| 9 | "..........#...........", | ||
| 10 | "..........#...........", | ||
| 11 | "..........#...........", | ||
| 12 | "..........#...........", | ||
| 13 | "..........#...........", | ||
| 14 | "..........#...........", | ||
| 15 | "..........#...........", | ||
| 16 | "..........#...........", | ||
| 17 | "..........#...........", | ||
| 18 | "..........#...........", | ||
| 19 | "..........#...........", | ||
| 20 | "..........#...........", | ||
| 21 | "..........#...........", | ||
| 22 | "..........#...........", | ||
| 23 | "..........#...........", | ||
| 24 | "..........#...........", | ||
| 25 | "..........#...........", | ||
| 26 | "......................", | ||
| 27 | "......................" | ||
| 28 | }; | ||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * split_view_xpm[] = { | ||
| 3 | "22 22 2 1", | ||
| 4 | ". c None", | ||
| 5 | "# c #000000", | ||
| 6 | "......................", | ||
| 7 | "......................", | ||
| 8 | "......#......#........", | ||
| 9 | "......#......#........", | ||
| 10 | "......#......#........", | ||
| 11 | "......#......#........", | ||
| 12 | "......#......#........", | ||
| 13 | "......#......#........", | ||
| 14 | "......#......#........", | ||
| 15 | "......#......#........", | ||
| 16 | "......#......#........", | ||
| 17 | "......#......#........", | ||
| 18 | "......#......#........", | ||
| 19 | "......#......#........", | ||
| 20 | "......#......#........", | ||
| 21 | "......#......#........", | ||
| 22 | "......#......#........", | ||
| 23 | "......#......#........", | ||
| 24 | "......#......#........", | ||
| 25 | "......#......#........", | ||
| 26 | "......................", | ||
| 27 | "......................" | ||
| 28 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * symbol_mod_xpm[] = { | ||
| 3 | "12 12 2 1", | ||
| 4 | " c white", | ||
| 5 | ". c black", | ||
| 6 | " ", | ||
| 7 | " .......... ", | ||
| 8 | " . . ", | ||
| 9 | " . . ", | ||
| 10 | " . .. . ", | ||
| 11 | " . .... . ", | ||
| 12 | " . .... . ", | ||
| 13 | " . .. . ", | ||
| 14 | " . . ", | ||
| 15 | " . . ", | ||
| 16 | " .......... ", | ||
| 17 | " " | ||
| 18 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * symbol_no_xpm[] = { | ||
| 3 | "12 12 2 1", | ||
| 4 | " c white", | ||
| 5 | ". c black", | ||
| 6 | " ", | ||
| 7 | " .......... ", | ||
| 8 | " . . ", | ||
| 9 | " . . ", | ||
| 10 | " . . ", | ||
| 11 | " . . ", | ||
| 12 | " . . ", | ||
| 13 | " . . ", | ||
| 14 | " . . ", | ||
| 15 | " . . ", | ||
| 16 | " .......... ", | ||
| 17 | " " | ||
| 18 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * symbol_yes_xpm[] = { | ||
| 3 | "12 12 2 1", | ||
| 4 | " c white", | ||
| 5 | ". c black", | ||
| 6 | " ", | ||
| 7 | " .......... ", | ||
| 8 | " . . ", | ||
| 9 | " . . ", | ||
| 10 | " . . . ", | ||
| 11 | " . .. . ", | ||
| 12 | " . . .. . ", | ||
| 13 | " . .... . ", | ||
| 14 | " . .. . ", | ||
| 15 | " . . ", | ||
| 16 | " .......... ", | ||
| 17 | " " | ||
| 18 | }; | ||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* XPM */ | ||
| 2 | static char * tree_view_xpm[] = { | ||
| 3 | "22 22 2 1", | ||
| 4 | ". c None", | ||
| 5 | "# c #000000", | ||
| 6 | "......................", | ||
| 7 | "......................", | ||
| 8 | "......#...............", | ||
| 9 | "......#...............", | ||
| 10 | "......#...............", | ||
| 11 | "......#...............", | ||
| 12 | "......#...............", | ||
| 13 | "......########........", | ||
| 14 | "......#...............", | ||
| 15 | "......#...............", | ||
| 16 | "......#...............", | ||
| 17 | "......#...............", | ||
| 18 | "......#...............", | ||
| 19 | "......########........", | ||
| 20 | "......#...............", | ||
| 21 | "......#...............", | ||
| 22 | "......#...............", | ||
| 23 | "......#...............", | ||
| 24 | "......#...............", | ||
| 25 | "......########........", | ||
| 26 | "......................", | ||
| 27 | "......................" | ||
| 28 | }; | ||
| @@ -1,328 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "images.h" | ||
| 7 | |||
| 8 | const char * const xpm_load[] = { | ||
| 9 | "22 22 5 1", | ||
| 10 | ". c None", | ||
| 11 | "# c #000000", | ||
| 12 | "c c #838100", | ||
| 13 | "a c #ffff00", | ||
| 14 | "b c #ffffff", | ||
| 15 | "......................", | ||
| 16 | "......................", | ||
| 17 | "......................", | ||
| 18 | "............####....#.", | ||
| 19 | "...........#....##.##.", | ||
| 20 | "..................###.", | ||
| 21 | ".................####.", | ||
| 22 | ".####...........#####.", | ||
| 23 | "#abab##########.......", | ||
| 24 | "#babababababab#.......", | ||
| 25 | "#ababababababa#.......", | ||
| 26 | "#babababababab#.......", | ||
| 27 | "#ababab###############", | ||
| 28 | "#babab##cccccccccccc##", | ||
| 29 | "#abab##cccccccccccc##.", | ||
| 30 | "#bab##cccccccccccc##..", | ||
| 31 | "#ab##cccccccccccc##...", | ||
| 32 | "#b##cccccccccccc##....", | ||
| 33 | "###cccccccccccc##.....", | ||
| 34 | "##cccccccccccc##......", | ||
| 35 | "###############.......", | ||
| 36 | "......................"}; | ||
| 37 | |||
| 38 | const char * const xpm_save[] = { | ||
| 39 | "22 22 5 1", | ||
| 40 | ". c None", | ||
| 41 | "# c #000000", | ||
| 42 | "a c #838100", | ||
| 43 | "b c #c5c2c5", | ||
| 44 | "c c #cdb6d5", | ||
| 45 | "......................", | ||
| 46 | ".####################.", | ||
| 47 | ".#aa#bbbbbbbbbbbb#bb#.", | ||
| 48 | ".#aa#bbbbbbbbbbbb#bb#.", | ||
| 49 | ".#aa#bbbbbbbbbcbb####.", | ||
| 50 | ".#aa#bbbccbbbbbbb#aa#.", | ||
| 51 | ".#aa#bbbccbbbbbbb#aa#.", | ||
| 52 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 53 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 54 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 55 | ".#aa#bbbbbbbbbbbb#aa#.", | ||
| 56 | ".#aaa############aaa#.", | ||
| 57 | ".#aaaaaaaaaaaaaaaaaa#.", | ||
| 58 | ".#aaaaaaaaaaaaaaaaaa#.", | ||
| 59 | ".#aaa#############aa#.", | ||
| 60 | ".#aaa#########bbb#aa#.", | ||
| 61 | ".#aaa#########bbb#aa#.", | ||
| 62 | ".#aaa#########bbb#aa#.", | ||
| 63 | ".#aaa#########bbb#aa#.", | ||
| 64 | ".#aaa#########bbb#aa#.", | ||
| 65 | "..##################..", | ||
| 66 | "......................"}; | ||
| 67 | |||
| 68 | const char * const xpm_back[] = { | ||
| 69 | "22 22 3 1", | ||
| 70 | ". c None", | ||
| 71 | "# c #000083", | ||
| 72 | "a c #838183", | ||
| 73 | "......................", | ||
| 74 | "......................", | ||
| 75 | "......................", | ||
| 76 | "......................", | ||
| 77 | "......................", | ||
| 78 | "...........######a....", | ||
| 79 | "..#......##########...", | ||
| 80 | "..##...####......##a..", | ||
| 81 | "..###.###.........##..", | ||
| 82 | "..######..........##..", | ||
| 83 | "..#####...........##..", | ||
| 84 | "..######..........##..", | ||
| 85 | "..#######.........##..", | ||
| 86 | "..########.......##a..", | ||
| 87 | "...............a###...", | ||
| 88 | "...............###....", | ||
| 89 | "......................", | ||
| 90 | "......................", | ||
| 91 | "......................", | ||
| 92 | "......................", | ||
| 93 | "......................", | ||
| 94 | "......................"}; | ||
| 95 | |||
| 96 | const char * const xpm_tree_view[] = { | ||
| 97 | "22 22 2 1", | ||
| 98 | ". c None", | ||
| 99 | "# c #000000", | ||
| 100 | "......................", | ||
| 101 | "......................", | ||
| 102 | "......#...............", | ||
| 103 | "......#...............", | ||
| 104 | "......#...............", | ||
| 105 | "......#...............", | ||
| 106 | "......#...............", | ||
| 107 | "......########........", | ||
| 108 | "......#...............", | ||
| 109 | "......#...............", | ||
| 110 | "......#...............", | ||
| 111 | "......#...............", | ||
| 112 | "......#...............", | ||
| 113 | "......########........", | ||
| 114 | "......#...............", | ||
| 115 | "......#...............", | ||
| 116 | "......#...............", | ||
| 117 | "......#...............", | ||
| 118 | "......#...............", | ||
| 119 | "......########........", | ||
| 120 | "......................", | ||
| 121 | "......................"}; | ||
| 122 | |||
| 123 | const char * const xpm_single_view[] = { | ||
| 124 | "22 22 2 1", | ||
| 125 | ". c None", | ||
| 126 | "# c #000000", | ||
| 127 | "......................", | ||
| 128 | "......................", | ||
| 129 | "..........#...........", | ||
| 130 | "..........#...........", | ||
| 131 | "..........#...........", | ||
| 132 | "..........#...........", | ||
| 133 | "..........#...........", | ||
| 134 | "..........#...........", | ||
| 135 | "..........#...........", | ||
| 136 | "..........#...........", | ||
| 137 | "..........#...........", | ||
| 138 | "..........#...........", | ||
| 139 | "..........#...........", | ||
| 140 | "..........#...........", | ||
| 141 | "..........#...........", | ||
| 142 | "..........#...........", | ||
| 143 | "..........#...........", | ||
| 144 | "..........#...........", | ||
| 145 | "..........#...........", | ||
| 146 | "..........#...........", | ||
| 147 | "......................", | ||
| 148 | "......................"}; | ||
| 149 | |||
| 150 | const char * const xpm_split_view[] = { | ||
| 151 | "22 22 2 1", | ||
| 152 | ". c None", | ||
| 153 | "# c #000000", | ||
| 154 | "......................", | ||
| 155 | "......................", | ||
| 156 | "......#......#........", | ||
| 157 | "......#......#........", | ||
| 158 | "......#......#........", | ||
| 159 | "......#......#........", | ||
| 160 | "......#......#........", | ||
| 161 | "......#......#........", | ||
| 162 | "......#......#........", | ||
| 163 | "......#......#........", | ||
| 164 | "......#......#........", | ||
| 165 | "......#......#........", | ||
| 166 | "......#......#........", | ||
| 167 | "......#......#........", | ||
| 168 | "......#......#........", | ||
| 169 | "......#......#........", | ||
| 170 | "......#......#........", | ||
| 171 | "......#......#........", | ||
| 172 | "......#......#........", | ||
| 173 | "......#......#........", | ||
| 174 | "......................", | ||
| 175 | "......................"}; | ||
| 176 | |||
| 177 | const char * const xpm_symbol_no[] = { | ||
| 178 | "12 12 2 1", | ||
| 179 | " c white", | ||
| 180 | ". c black", | ||
| 181 | " ", | ||
| 182 | " .......... ", | ||
| 183 | " . . ", | ||
| 184 | " . . ", | ||
| 185 | " . . ", | ||
| 186 | " . . ", | ||
| 187 | " . . ", | ||
| 188 | " . . ", | ||
| 189 | " . . ", | ||
| 190 | " . . ", | ||
| 191 | " .......... ", | ||
| 192 | " "}; | ||
| 193 | |||
| 194 | const char * const xpm_symbol_mod[] = { | ||
| 195 | "12 12 2 1", | ||
| 196 | " c white", | ||
| 197 | ". c black", | ||
| 198 | " ", | ||
| 199 | " .......... ", | ||
| 200 | " . . ", | ||
| 201 | " . . ", | ||
| 202 | " . .. . ", | ||
| 203 | " . .... . ", | ||
| 204 | " . .... . ", | ||
| 205 | " . .. . ", | ||
| 206 | " . . ", | ||
| 207 | " . . ", | ||
| 208 | " .......... ", | ||
| 209 | " "}; | ||
| 210 | |||
| 211 | const char * const xpm_symbol_yes[] = { | ||
| 212 | "12 12 2 1", | ||
| 213 | " c white", | ||
| 214 | ". c black", | ||
| 215 | " ", | ||
| 216 | " .......... ", | ||
| 217 | " . . ", | ||
| 218 | " . . ", | ||
| 219 | " . . . ", | ||
| 220 | " . .. . ", | ||
| 221 | " . . .. . ", | ||
| 222 | " . .... . ", | ||
| 223 | " . .. . ", | ||
| 224 | " . . ", | ||
| 225 | " .......... ", | ||
| 226 | " "}; | ||
| 227 | |||
| 228 | const char * const xpm_choice_no[] = { | ||
| 229 | "12 12 2 1", | ||
| 230 | " c white", | ||
| 231 | ". c black", | ||
| 232 | " ", | ||
| 233 | " .... ", | ||
| 234 | " .. .. ", | ||
| 235 | " . . ", | ||
| 236 | " . . ", | ||
| 237 | " . . ", | ||
| 238 | " . . ", | ||
| 239 | " . . ", | ||
| 240 | " . . ", | ||
| 241 | " .. .. ", | ||
| 242 | " .... ", | ||
| 243 | " "}; | ||
| 244 | |||
| 245 | const char * const xpm_choice_yes[] = { | ||
| 246 | "12 12 2 1", | ||
| 247 | " c white", | ||
| 248 | ". c black", | ||
| 249 | " ", | ||
| 250 | " .... ", | ||
| 251 | " .. .. ", | ||
| 252 | " . . ", | ||
| 253 | " . .. . ", | ||
| 254 | " . .... . ", | ||
| 255 | " . .... . ", | ||
| 256 | " . .. . ", | ||
| 257 | " . . ", | ||
| 258 | " .. .. ", | ||
| 259 | " .... ", | ||
| 260 | " "}; | ||
| 261 | |||
| 262 | const char * const xpm_menu[] = { | ||
| 263 | "12 12 2 1", | ||
| 264 | " c white", | ||
| 265 | ". c black", | ||
| 266 | " ", | ||
| 267 | " .......... ", | ||
| 268 | " . . ", | ||
| 269 | " . .. . ", | ||
| 270 | " . .... . ", | ||
| 271 | " . ...... . ", | ||
| 272 | " . ...... . ", | ||
| 273 | " . .... . ", | ||
| 274 | " . .. . ", | ||
| 275 | " . . ", | ||
| 276 | " .......... ", | ||
| 277 | " "}; | ||
| 278 | |||
| 279 | const char * const xpm_menu_inv[] = { | ||
| 280 | "12 12 2 1", | ||
| 281 | " c white", | ||
| 282 | ". c black", | ||
| 283 | " ", | ||
| 284 | " .......... ", | ||
| 285 | " .......... ", | ||
| 286 | " .. ...... ", | ||
| 287 | " .. .... ", | ||
| 288 | " .. .. ", | ||
| 289 | " .. .. ", | ||
| 290 | " .. .... ", | ||
| 291 | " .. ...... ", | ||
| 292 | " .......... ", | ||
| 293 | " .......... ", | ||
| 294 | " "}; | ||
| 295 | |||
| 296 | const char * const xpm_menuback[] = { | ||
| 297 | "12 12 2 1", | ||
| 298 | " c white", | ||
| 299 | ". c black", | ||
| 300 | " ", | ||
| 301 | " .......... ", | ||
| 302 | " . . ", | ||
| 303 | " . .. . ", | ||
| 304 | " . .... . ", | ||
| 305 | " . ...... . ", | ||
| 306 | " . ...... . ", | ||
| 307 | " . .... . ", | ||
| 308 | " . .. . ", | ||
| 309 | " . . ", | ||
| 310 | " .......... ", | ||
| 311 | " "}; | ||
| 312 | |||
| 313 | const char * const xpm_void[] = { | ||
| 314 | "12 12 2 1", | ||
| 315 | " c white", | ||
| 316 | ". c black", | ||
| 317 | " ", | ||
| 318 | " ", | ||
| 319 | " ", | ||
| 320 | " ", | ||
| 321 | " ", | ||
| 322 | " ", | ||
| 323 | " ", | ||
| 324 | " ", | ||
| 325 | " ", | ||
| 326 | " ", | ||
| 327 | " ", | ||
| 328 | " "}; | ||
| @@ -1,33 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef IMAGES_H | ||
| 7 | #define IMAGES_H | ||
| 8 | |||
| 9 | #ifdef __cplusplus | ||
| 10 | extern "C" { | ||
| 11 | #endif | ||
| 12 | |||
| 13 | extern const char * const xpm_load[]; | ||
| 14 | extern const char * const xpm_save[]; | ||
| 15 | extern const char * const xpm_back[]; | ||
| 16 | extern const char * const xpm_tree_view[]; | ||
| 17 | extern const char * const xpm_single_view[]; | ||
| 18 | extern const char * const xpm_split_view[]; | ||
| 19 | extern const char * const xpm_symbol_no[]; | ||
| 20 | extern const char * const xpm_symbol_mod[]; | ||
| 21 | extern const char * const xpm_symbol_yes[]; | ||
| 22 | extern const char * const xpm_choice_no[]; | ||
| 23 | extern const char * const xpm_choice_yes[]; | ||
| 24 | extern const char * const xpm_menu[]; | ||
| 25 | extern const char * const xpm_menu_inv[]; | ||
| 26 | extern const char * const xpm_menuback[]; | ||
| 27 | extern const char * const xpm_void[]; | ||
| 28 | |||
| 29 | #ifdef __cplusplus | ||
| 30 | } | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #endif /* IMAGES_H */ | ||
| @@ -82,7 +82,7 @@ void menu_warn(const struct menu *menu, const char *fmt, ...); · 81 unmodified lines | |||
| 82 | struct menu *menu_add_menu(void); | 82 | struct menu *menu_add_menu(void); |
| 83 | void menu_end_menu(void); | 83 | void menu_end_menu(void); |
| 84 | void menu_add_entry(struct symbol *sym, enum menu_type type); | 84 | void menu_add_entry(struct symbol *sym, enum menu_type type); |
| 85 | void menu_add_dep(struct expr *dep); | 85 | void menu_add_dep(struct expr *dep, struct expr *cond); |
| 86 | void menu_add_visibility(struct expr *dep); | 86 | void menu_add_visibility(struct expr *dep); |
| 87 | struct property *menu_add_prompt(enum prop_type type, const char *prompt, | 87 | struct property *menu_add_prompt(enum prop_type type, const char *prompt, |
| 88 | struct expr *dep); | 88 | struct expr *dep); |
| @@ -127,8 +127,18 @@ static struct expr *rewrite_m(struct expr *e) · 126 unmodified lines | |||
| 127 | return e; | 127 | return e; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | void menu_add_dep(struct expr *dep) | 130 | void menu_add_dep(struct expr *dep, struct expr *cond) |
| 131 | { | 131 | { |
| 132 | if (cond) { | ||
| 133 | /* | ||
| 134 | * We have "depends on X if Y" and we want: | ||
| 135 | * Y != n --> X | ||
| 136 | * Y == n --> y | ||
| 137 | * That simplifies to: (X || (Y == n)) | ||
| 138 | */ | ||
| 139 | dep = expr_alloc_or(dep, | ||
| 140 | expr_trans_compare(cond, E_EQUAL, &symbol_no)); | ||
| 141 | } | ||
| 132 | current_entry->dep = expr_alloc_and(current_entry->dep, dep); | 142 | current_entry->dep = expr_alloc_and(current_entry->dep, dep); |
| 133 | } | 143 | } |
| 134 | 144 | ||
| @@ -16,8 +16,8 @@ · 15 unmodified lines | |||
| 16 | set -e | 16 | set -e |
| 17 | 17 | ||
| 18 | clean_up() { | 18 | clean_up() { |
| 19 | rm -f $TMP_FILE | 19 | rm -f "$TMP_FILE" |
| 20 | rm -f $MERGE_FILE | 20 | rm -f "$TMP_FILE.new" |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | usage() { | 23 | usage() { |
| @@ -43,6 +43,10 @@ STRICT=false · 19 unmodified lines | |||
| 43 | CONFIG_PREFIX=${CONFIG_-CONFIG_} | 43 | CONFIG_PREFIX=${CONFIG_-CONFIG_} |
| 44 | WARNOVERRIDE=echo | 44 | WARNOVERRIDE=echo |
| 45 | 45 | ||
| 46 | if [ -z "$AWK" ]; then | ||
| 47 | AWK=awk | ||
| 48 | fi | ||
| 49 | |||
| 46 | while true; do | 50 | while true; do |
| 47 | case $1 in | 51 | case $1 in |
| 48 | "-n") | 52 | "-n") |
| @@ -117,11 +121,8 @@ if [ ! -r "$INITFILE" ]; then · 68 unmodified lines | |||
| 117 | fi | 121 | fi |
| 118 | 122 | ||
| 119 | MERGE_LIST=$* | 123 | MERGE_LIST=$* |
| 120 | SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p" | ||
| 121 | SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p" | ||
| 122 | 124 | ||
| 123 | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) | 125 | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) |
| 124 | MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX) | ||
| 125 | 126 | ||
| 126 | echo "Using $INITFILE as base" | 127 | echo "Using $INITFILE as base" |
| 127 | 128 | ||
| @@ -129,6 +130,8 @@ trap clean_up EXIT · 1 unmodified line | |||
| 129 | 130 | ||
| 130 | cat $INITFILE > $TMP_FILE | 131 | cat $INITFILE > $TMP_FILE |
| 131 | 132 | ||
| 133 | PROCESSED_FILES="" | ||
| 134 | |||
| 132 | # Merge files, printing warnings on overridden values | 135 | # Merge files, printing warnings on overridden values |
| 133 | for ORIG_MERGE_FILE in $MERGE_LIST ; do | 136 | for ORIG_MERGE_FILE in $MERGE_LIST ; do |
| 134 | echo "Merging $ORIG_MERGE_FILE" | 137 | echo "Merging $ORIG_MERGE_FILE" |
| @@ -136,42 +139,138 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do · 1 unmodified line | |||
| 136 | echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 | 139 | echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 |
| 137 | exit 1 | 140 | exit 1 |
| 138 | fi | 141 | fi |
| 139 | cat $ORIG_MERGE_FILE > $MERGE_FILE | ||
| 140 | CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE) | ||
| 141 | |||
| 142 | for CFG in $CFG_LIST ; do | ||
| 143 | grep -q -w $CFG $TMP_FILE || continue | ||
| 144 | PREV_VAL=$(grep -w $CFG $TMP_FILE) | ||
| 145 | NEW_VAL=$(grep -w $CFG $MERGE_FILE) | ||
| 146 | BUILTIN_FLAG=false | ||
| 147 | if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then | ||
| 148 | ${WARNOVERRIDE} Previous value: $PREV_VAL | ||
| 149 | ${WARNOVERRIDE} New value: $NEW_VAL | ||
| 150 | ${WARNOVERRIDE} -y passed, will not demote y to m | ||
| 151 | ${WARNOVERRIDE} | ||
| 152 | BUILTIN_FLAG=true | ||
| 153 | elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then | ||
| 154 | ${WARNOVERRIDE} Value of $CFG is redefined by fragment $ORIG_MERGE_FILE: | ||
| 155 | ${WARNOVERRIDE} Previous value: $PREV_VAL | ||
| 156 | ${WARNOVERRIDE} New value: $NEW_VAL | ||
| 157 | ${WARNOVERRIDE} | ||
| 158 | if [ "$STRICT" = "true" ]; then | ||
| 159 | STRICT_MODE_VIOLATED=true | ||
| 160 | fi | ||
| 161 | elif [ "$WARNREDUN" = "true" ]; then | ||
| 162 | ${WARNOVERRIDE} Value of $CFG is redundant by fragment $ORIG_MERGE_FILE: | ||
| 163 | fi | ||
| 164 | if [ "$BUILTIN_FLAG" = "false" ]; then | ||
| 165 | sed -i "/$CFG[ =]/d" $TMP_FILE | ||
| 166 | else | ||
| 167 | sed -i "/$CFG[ =]/d" $MERGE_FILE | ||
| 168 | fi | ||
| 169 | done | ||
| 170 | # In case the previous file lacks a new line at the end | ||
| 171 | echo >> $TMP_FILE | ||
| 172 | cat $MERGE_FILE >> $TMP_FILE | ||
| 173 | done | ||
| 174 | 142 | ||
| 143 | # Check for duplicate input files | ||
| 144 | case " $PROCESSED_FILES " in | ||
| 145 | *" $ORIG_MERGE_FILE "*) | ||
| 146 | ${WARNOVERRIDE} "WARNING: Input file provided multiple times: $ORIG_MERGE_FILE" | ||
| 147 | ;; | ||
| 148 | esac | ||
| 149 | |||
| 150 | # Use awk for single-pass processing instead of per-symbol grep/sed | ||
| 151 | if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ | ||
| 152 | -v warnoverride="$WARNOVERRIDE" \ | ||
| 153 | -v strict="$STRICT" \ | ||
| 154 | -v builtin="$BUILTIN" \ | ||
| 155 | -v warnredun="$WARNREDUN" ' | ||
| 156 | BEGIN { | ||
| 157 | strict_violated = 0 | ||
| 158 | cfg_regex = "^" prefix "[a-zA-Z0-9_]+" | ||
| 159 | notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" | ||
| 160 | } | ||
| 161 | |||
| 162 | # Extract config name from a line, returns "" if not a config line | ||
| 163 | function get_cfg(line) { | ||
| 164 | if (match(line, cfg_regex)) { | ||
| 165 | return substr(line, RSTART, RLENGTH) | ||
| 166 | } else if (match(line, notset_regex)) { | ||
| 167 | # Extract CONFIG_FOO from "# CONFIG_FOO is not set" | ||
| 168 | sub(/^# /, "", line) | ||
| 169 | sub(/ is not set$/, "", line) | ||
| 170 | return line | ||
| 171 | } | ||
| 172 | return "" | ||
| 173 | } | ||
| 174 | |||
| 175 | function warn_builtin(cfg, prev, new) { | ||
| 176 | if (warnoverride == "true") return | ||
| 177 | print cfg ": -y passed, will not demote y to m" | ||
| 178 | print "Previous value: " prev | ||
| 179 | print "New value: " new | ||
| 180 | print "" | ||
| 181 | } | ||
| 182 | |||
| 183 | function warn_redefined(cfg, prev, new) { | ||
| 184 | if (warnoverride == "true") return | ||
| 185 | print "Value of " cfg " is redefined by fragment " mergefile ":" | ||
| 186 | print "Previous value: " prev | ||
| 187 | print "New value: " new | ||
| 188 | print "" | ||
| 189 | } | ||
| 190 | |||
| 191 | function warn_redundant(cfg) { | ||
| 192 | if (warnredun != "true" || warnoverride == "true") return | ||
| 193 | print "Value of " cfg " is redundant by fragment " mergefile ":" | ||
| 194 | } | ||
| 195 | |||
| 196 | # First pass: read merge file, store all lines and index | ||
| 197 | FILENAME == ARGV[1] { | ||
| 198 | mergefile = FILENAME | ||
| 199 | merge_lines[FNR] = $0 | ||
| 200 | merge_total = FNR | ||
| 201 | cfg = get_cfg($0) | ||
| 202 | if (cfg != "") { | ||
| 203 | merge_cfg[cfg] = $0 | ||
| 204 | merge_cfg_line[cfg] = FNR | ||
| 205 | } | ||
| 206 | next | ||
| 207 | } | ||
| 208 | |||
| 209 | # Second pass: process base file (TMP_FILE) | ||
| 210 | FILENAME == ARGV[2] { | ||
| 211 | cfg = get_cfg($0) | ||
| 212 | |||
| 213 | # Not a config or not in merge file - keep it | ||
| 214 | if (cfg == "" || !(cfg in merge_cfg)) { | ||
| 215 | print $0 >> ARGV[3] | ||
| 216 | next | ||
| 217 | } | ||
| 218 | |||
| 219 | prev_val = $0 | ||
| 220 | new_val = merge_cfg[cfg] | ||
| 221 | |||
| 222 | # BUILTIN: do not demote y to m | ||
| 223 | if (builtin == "true" && new_val ~ /=m$/ && prev_val ~ /=y$/) { | ||
| 224 | warn_builtin(cfg, prev_val, new_val) | ||
| 225 | print $0 >> ARGV[3] | ||
| 226 | skip_merge[merge_cfg_line[cfg]] = 1 | ||
| 227 | next | ||
| 228 | } | ||
| 229 | |||
| 230 | # Values equal - redundant | ||
| 231 | if (prev_val == new_val) { | ||
| 232 | warn_redundant(cfg) | ||
| 233 | next | ||
| 234 | } | ||
| 235 | |||
| 236 | # "=n" is the same as "is not set" | ||
| 237 | if (prev_val ~ /=n$/ && new_val ~ / is not set$/) { | ||
| 238 | print $0 >> ARGV[3] | ||
| 239 | next | ||
| 240 | } | ||
| 241 | |||
| 242 | # Values differ - redefined | ||
| 243 | warn_redefined(cfg, prev_val, new_val) | ||
| 244 | if (strict == "true") { | ||
| 245 | strict_violated = 1 | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | # output file, skip all lines | ||
| 250 | FILENAME == ARGV[3] { | ||
| 251 | nextfile | ||
| 252 | } | ||
| 253 | |||
| 254 | END { | ||
| 255 | # Newline in case base file lacks trailing newline | ||
| 256 | print "" >> ARGV[3] | ||
| 257 | # Append merge file, skipping lines marked for builtin preservation | ||
| 258 | for (i = 1; i <= merge_total; i++) { | ||
| 259 | if (!(i in skip_merge)) { | ||
| 260 | print merge_lines[i] >> ARGV[3] | ||
| 261 | } | ||
| 262 | } | ||
| 263 | if (strict_violated) { | ||
| 264 | exit 1 | ||
| 265 | } | ||
| 266 | }' \ | ||
| 267 | "$ORIG_MERGE_FILE" "$TMP_FILE" "$TMP_FILE.new"; then | ||
| 268 | # awk exited non-zero, strict mode was violated | ||
| 269 | STRICT_MODE_VIOLATED=true | ||
| 270 | fi | ||
| 271 | mv "$TMP_FILE.new" "$TMP_FILE" | ||
| 272 | PROCESSED_FILES="$PROCESSED_FILES $ORIG_MERGE_FILE" | ||
| 273 | done | ||
| 175 | if [ "$STRICT_MODE_VIOLATED" = "true" ]; then | 274 | if [ "$STRICT_MODE_VIOLATED" = "true" ]; then |
| 176 | echo "The fragment redefined a value and strict mode had been passed." | 275 | echo "The fragment redefined a value and strict mode had been passed." |
| 177 | exit 1 | 276 | exit 1 |
| @@ -198,16 +297,91 @@ fi · 20 unmodified lines | |||
| 198 | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set | 297 | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set |
| 199 | make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET | 298 | make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET |
| 200 | 299 | ||
| 300 | # Check all specified config values took effect (might have missed-dependency issues) | ||
| 301 | if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ | ||
| 302 | -v warnoverride="$WARNOVERRIDE" \ | ||
| 303 | -v strict="$STRICT" \ | ||
| 304 | -v warnredun="$WARNREDUN" ' | ||
| 305 | BEGIN { | ||
| 306 | strict_violated = 0 | ||
| 307 | cfg_regex = "^" prefix "[a-zA-Z0-9_]+" | ||
| 308 | notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" | ||
| 309 | } | ||
| 201 | 310 | ||
| 202 | # Check all specified config values took (might have missed-dependency issues) | 311 | # Extract config name from a line, returns "" if not a config line |
| 203 | for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do | 312 | function get_cfg(line) { |
| 313 | if (match(line, cfg_regex)) { | ||
| 314 | return substr(line, RSTART, RLENGTH) | ||
| 315 | } else if (match(line, notset_regex)) { | ||
| 316 | # Extract CONFIG_FOO from "# CONFIG_FOO is not set" | ||
| 317 | sub(/^# /, "", line) | ||
| 318 | sub(/ is not set$/, "", line) | ||
| 319 | return line | ||
| 320 | } | ||
| 321 | return "" | ||
| 322 | } | ||
| 204 | 323 | ||
| 205 | REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) | 324 | function warn_mismatch(cfg, merged, final) { |
| 206 | ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) | 325 | if (warnredun == "true") return |
| 207 | if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then | 326 | if (final == "" && !(merged ~ / is not set$/ || merged ~ /=n$/)) { |
| 208 | echo "Value requested for $CFG not in final .config" | 327 | print "WARNING: Value requested for " cfg " not in final .config" |
| 209 | echo "Requested value: $REQUESTED_VAL" | 328 | print "Requested value: " merged |
| 210 | echo "Actual value: $ACTUAL_VAL" | 329 | print "Actual value: " final |
| 211 | echo "" | 330 | } else if (final == "" && merged ~ / is not set$/) { |
| 212 | fi | 331 | # not set, pass |
| 213 | done | 332 | } else if (merged == "" && final != "") { |
| 333 | print "WARNING: " cfg " not in merged config but added in final .config:" | ||
| 334 | print "Requested value: " merged | ||
| 335 | print "Actual value: " final | ||
| 336 | } else { | ||
| 337 | print "WARNING: " cfg " differs:" | ||
| 338 | print "Requested value: " merged | ||
| 339 | print "Actual value: " final | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | # First pass: read effective config file, store all lines | ||
| 344 | FILENAME == ARGV[1] { | ||
| 345 | cfg = get_cfg($0) | ||
| 346 | if (cfg != "") { | ||
| 347 | config_cfg[cfg] = $0 | ||
| 348 | } | ||
| 349 | next | ||
| 350 | } | ||
| 351 | |||
| 352 | # Second pass: process merged config and compare against effective config | ||
| 353 | { | ||
| 354 | cfg = get_cfg($0) | ||
| 355 | if (cfg == "") next | ||
| 356 | |||
| 357 | # strip trailing comment | ||
| 358 | sub(/[[:space:]]+#.*/, "", $0) | ||
| 359 | merged_val = $0 | ||
| 360 | final_val = config_cfg[cfg] | ||
| 361 | |||
| 362 | if (merged_val == final_val) next | ||
| 363 | |||
| 364 | if (merged_val ~ /=n$/ && final_val ~ / is not set$/) next | ||
| 365 | if (merged_val ~ /=n$/ && final_val == "") next | ||
| 366 | |||
| 367 | warn_mismatch(cfg, merged_val, final_val) | ||
| 368 | |||
| 369 | if (strict == "true") { | ||
| 370 | strict_violated = 1 | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | END { | ||
| 375 | if (strict_violated) { | ||
| 376 | exit 1 | ||
| 377 | } | ||
| 378 | }' \ | ||
| 379 | "$KCONFIG_CONFIG" "$TMP_FILE"; then | ||
| 380 | # awk exited non-zero, strict mode was violated | ||
| 381 | STRICT_MODE_VIOLATED=true | ||
| 382 | fi | ||
| 383 | |||
| 384 | if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then | ||
| 385 | echo "Requested and effective config differ" | ||
| 386 | exit 1 | ||
| 387 | fi | ||
| @@ -323,7 +323,7 @@ if_entry: T_IF expr T_EOL · 322 unmodified lines | |||
| 323 | { | 323 | { |
| 324 | printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno); | 324 | printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno); |
| 325 | menu_add_entry(NULL, M_IF); | 325 | menu_add_entry(NULL, M_IF); |
| 326 | menu_add_dep($2); | 326 | menu_add_dep($2, NULL); |
| 327 | $$ = menu_add_menu(); | 327 | $$ = menu_add_menu(); |
| 328 | }; | 328 | }; |
| 329 | 329 | ||
| @@ -422,9 +422,9 @@ help: help_start T_HELPTEXT · 92 unmodified lines | |||
| 422 | 422 | ||
| 423 | /* depends option */ | 423 | /* depends option */ |
| 424 | 424 | ||
| 425 | depends: T_DEPENDS T_ON expr T_EOL | 425 | depends: T_DEPENDS T_ON expr if_expr T_EOL |
| 426 | { | 426 | { |
| 427 | menu_add_dep($3); | 427 | menu_add_dep($3, $4); |
| 428 | printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno); | 428 | printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno); |
| 429 | }; | 429 | }; |
| 430 | 430 | ||
| @@ -26,8 +26,6 @@ · 25 unmodified lines | |||
| 26 | #include "lkc.h" | 26 | #include "lkc.h" |
| 27 | #include "qconf.h" | 27 | #include "qconf.h" |
| 28 | 28 | ||
| 29 | #include "images.h" | ||
| 30 | |||
| 31 | 29 | ||
| 32 | static QApplication *configApp; | 30 | static QApplication *configApp; |
| 33 | static ConfigSettings *configSettings; | 31 | static ConfigSettings *configSettings; |
| @@ -1283,13 +1281,14 @@ ConfigMainWindow::ConfigMainWindow(void) · 1249 unmodified lines | |||
| 1283 | move(x.toInt(), y.toInt()); | 1281 | move(x.toInt(), y.toInt()); |
| 1284 | 1282 | ||
| 1285 | // set up icons | 1283 | // set up icons |
| 1286 | ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes)); | 1284 | QString iconsDir = QString(getenv(SRCTREE) ? getenv(SRCTREE) : QDir::currentPath()) + "/scripts/kconfig/icons/"; |
| 1287 | ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod)); | 1285 | ConfigItem::symbolYesIcon = QIcon(QPixmap(iconsDir + "symbol_yes.xpm")); |
| 1288 | ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no)); | 1286 | ConfigItem::symbolModIcon = QIcon(QPixmap(iconsDir + "symbol_mod.xpm")); |
| 1289 | ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes)); | 1287 | ConfigItem::symbolNoIcon = QIcon(QPixmap(iconsDir + "symbol_no.xpm")); |
| 1290 | ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no)); | 1288 | ConfigItem::choiceYesIcon = QIcon(QPixmap(iconsDir + "choice_yes.xpm")); |
| 1291 | ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu)); | 1289 | ConfigItem::choiceNoIcon = QIcon(QPixmap(iconsDir + "choice_no.xpm")); |
| 1292 | ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); | 1290 | ConfigItem::menuIcon = QIcon(QPixmap(iconsDir + "menu.xpm")); |
| 1291 | ConfigItem::menubackIcon = QIcon(QPixmap(iconsDir + "menuback.xpm")); | ||
| 1293 | 1292 | ||
| 1294 | QWidget *widget = new QWidget(this); | 1293 | QWidget *widget = new QWidget(this); |
| 1295 | setCentralWidget(widget); | 1294 | setCentralWidget(widget); |
| @@ -1312,7 +1311,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 16 unmodified lines | |||
| 1312 | 1311 | ||
| 1313 | configList->setFocus(); | 1312 | configList->setFocus(); |
| 1314 | 1313 | ||
| 1315 | backAction = new QAction(QPixmap(xpm_back), "Back", this); | 1314 | backAction = new QAction(QPixmap(iconsDir + "back.xpm"), "Back", this); |
| 1316 | backAction->setShortcut(QKeySequence::Back); | 1315 | backAction->setShortcut(QKeySequence::Back); |
| 1317 | connect(backAction, &QAction::triggered, | 1316 | connect(backAction, &QAction::triggered, |
| 1318 | this, &ConfigMainWindow::goBack); | 1317 | this, &ConfigMainWindow::goBack); |
| @@ -1322,12 +1321,12 @@ ConfigMainWindow::ConfigMainWindow(void) · 3 unmodified lines | |||
| 1322 | connect(quitAction, &QAction::triggered, | 1321 | connect(quitAction, &QAction::triggered, |
| 1323 | this, &ConfigMainWindow::close); | 1322 | this, &ConfigMainWindow::close); |
| 1324 | 1323 | ||
| 1325 | QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); | 1324 | QAction *loadAction = new QAction(QPixmap(iconsDir + "load.xpm"), "&Open", this); |
| 1326 | loadAction->setShortcut(QKeySequence::Open); | 1325 | loadAction->setShortcut(QKeySequence::Open); |
| 1327 | connect(loadAction, &QAction::triggered, | 1326 | connect(loadAction, &QAction::triggered, |
| 1328 | this, &ConfigMainWindow::loadConfig); | 1327 | this, &ConfigMainWindow::loadConfig); |
| 1329 | 1328 | ||
| 1330 | saveAction = new QAction(QPixmap(xpm_save), "&Save", this); | 1329 | saveAction = new QAction(QPixmap(iconsDir + "save.xpm"), "&Save", this); |
| 1331 | saveAction->setShortcut(QKeySequence::Save); | 1330 | saveAction->setShortcut(QKeySequence::Save); |
| 1332 | connect(saveAction, &QAction::triggered, | 1331 | connect(saveAction, &QAction::triggered, |
| 1333 | this, &ConfigMainWindow::saveConfig); | 1332 | this, &ConfigMainWindow::saveConfig); |
| @@ -1344,15 +1343,15 @@ ConfigMainWindow::ConfigMainWindow(void) · 10 unmodified lines | |||
| 1344 | searchAction->setShortcut(QKeySequence::Find); | 1343 | searchAction->setShortcut(QKeySequence::Find); |
| 1345 | connect(searchAction, &QAction::triggered, | 1344 | connect(searchAction, &QAction::triggered, |
| 1346 | this, &ConfigMainWindow::searchConfig); | 1345 | this, &ConfigMainWindow::searchConfig); |
| 1347 | singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); | 1346 | singleViewAction = new QAction(QPixmap(iconsDir + "single_view.xpm"), "Single View", this); |
| 1348 | singleViewAction->setCheckable(true); | 1347 | singleViewAction->setCheckable(true); |
| 1349 | connect(singleViewAction, &QAction::triggered, | 1348 | connect(singleViewAction, &QAction::triggered, |
| 1350 | this, &ConfigMainWindow::showSingleView); | 1349 | this, &ConfigMainWindow::showSingleView); |
| 1351 | splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); | 1350 | splitViewAction = new QAction(QPixmap(iconsDir + "split_view.xpm"), "Split View", this); |
| 1352 | splitViewAction->setCheckable(true); | 1351 | splitViewAction->setCheckable(true); |
| 1353 | connect(splitViewAction, &QAction::triggered, | 1352 | connect(splitViewAction, &QAction::triggered, |
| 1354 | this, &ConfigMainWindow::showSplitView); | 1353 | this, &ConfigMainWindow::showSplitView); |
| 1355 | fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); | 1354 | fullViewAction = new QAction(QPixmap(iconsDir + "tree_view.xpm"), "Full View", this); |
| 1356 | fullViewAction->setCheckable(true); | 1355 | fullViewAction->setCheckable(true); |
| 1357 | connect(fullViewAction, &QAction::triggered, | 1356 | connect(fullViewAction, &QAction::triggered, |
| 1358 | this, &ConfigMainWindow::showFullView); | 1357 | this, &ConfigMainWindow::showFullView); |
| @@ -415,7 +415,7 @@ foreach my $module (keys(%modules)) { · 414 unmodified lines | |||
| 415 | } | 415 | } |
| 416 | } else { | 416 | } else { |
| 417 | # Most likely, someone has a custom (binary?) module loaded. | 417 | # Most likely, someone has a custom (binary?) module loaded. |
| 418 | print STDERR "$module config not found!!\n"; | 418 | print STDERR "$module config not found!\n"; |
| 419 | } | 419 | } |
| 420 | } | 420 | } |
| 421 | 421 | ||
| @@ -0,0 +1,32 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | # Test Kconfig file for conditional dependencies. | ||
| 3 | |||
| 4 | # Enable module support for tristate testing | ||
| 5 | config MODULES | ||
| 6 | bool "Enable loadable module support" | ||
| 7 | modules | ||
| 8 | default y | ||
| 9 | |||
| 10 | config FOO | ||
| 11 | bool "FOO symbol" | ||
| 12 | |||
| 13 | config BAR | ||
| 14 | bool "BAR symbol" | ||
| 15 | |||
| 16 | config TEST_BASIC | ||
| 17 | bool "Test basic conditional dependency" | ||
| 18 | depends on FOO if BAR | ||
| 19 | default y | ||
| 20 | |||
| 21 | config TEST_COMPLEX | ||
| 22 | bool "Test complex conditional dependency" | ||
| 23 | depends on (FOO && BAR) if (FOO || BAR) | ||
| 24 | default y | ||
| 25 | |||
| 26 | config BAZ | ||
| 27 | tristate "BAZ symbol" | ||
| 28 | |||
| 29 | config TEST_OPTIONAL | ||
| 30 | tristate "Test simple optional dependency" | ||
| 31 | depends on BAZ if BAZ | ||
| 32 | default y | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | """ | ||
| 3 | Correctly handle conditional dependencies. | ||
| 4 | """ | ||
| 5 | |||
| 6 | def test(conf): | ||
| 7 | assert conf.oldconfig('test_config1') == 0 | ||
| 8 | assert conf.config_matches('expected_config1') | ||
| 9 | |||
| 10 | assert conf.oldconfig('test_config2') == 0 | ||
| 11 | assert conf.config_matches('expected_config2') | ||
| 12 | |||
| 13 | assert conf.oldconfig('test_config3') == 0 | ||
| 14 | assert conf.config_matches('expected_config3') | ||
| @@ -0,0 +1,11 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated file; DO NOT EDIT. | ||
| 3 | # Main menu | ||
| 4 | # | ||
| 5 | CONFIG_MODULES=y | ||
| 6 | CONFIG_FOO=y | ||
| 7 | CONFIG_BAR=y | ||
| 8 | CONFIG_TEST_BASIC=y | ||
| 9 | CONFIG_TEST_COMPLEX=y | ||
| 10 | CONFIG_BAZ=m | ||
| 11 | CONFIG_TEST_OPTIONAL=m | ||
| @@ -0,0 +1,9 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated file; DO NOT EDIT. | ||
| 3 | # Main menu | ||
| 4 | # | ||
| 5 | CONFIG_MODULES=y | ||
| 6 | # CONFIG_FOO is not set | ||
| 7 | CONFIG_BAR=y | ||
| 8 | CONFIG_BAZ=y | ||
| 9 | CONFIG_TEST_OPTIONAL=y | ||
| @@ -0,0 +1,11 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated file; DO NOT EDIT. | ||
| 3 | # Main menu | ||
| 4 | # | ||
| 5 | CONFIG_MODULES=y | ||
| 6 | # CONFIG_FOO is not set | ||
| 7 | # CONFIG_BAR is not set | ||
| 8 | CONFIG_TEST_BASIC=y | ||
| 9 | CONFIG_TEST_COMPLEX=y | ||
| 10 | # CONFIG_BAZ is not set | ||
| 11 | CONFIG_TEST_OPTIONAL=y | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | # Basic check that everything can be configured if selected. | ||
| 2 | CONFIG_FOO=y | ||
| 3 | CONFIG_BAR=y | ||
| 4 | CONFIG_BAZ=m | ||
| 5 | # Ensure that TEST_OPTIONAL=y with BAZ=m is converted to TEST_OPTIONAL=m | ||
| 6 | CONFIG_TEST_OPTIONAL=y | ||
| @@ -0,0 +1,7 @@ | |||
| 1 | # If FOO is not selected, then TEST_BASIC should fail the conditional | ||
| 2 | # dependency since BAR is set. | ||
| 3 | # TEST_COMPLEX will fail dependency as it depends on both FOO and BAR | ||
| 4 | # if either of those is selected. | ||
| 5 | CONFIG_FOO=n | ||
| 6 | CONFIG_BAR=y | ||
| 7 | CONFIG_BAZ=y | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | # If FOO is not selected, but BAR is also not selected, then TEST_BASIC | ||
| 2 | # should pass since the dependency on FOO is conditional on BAR. | ||
| 3 | # TEST_COMPLEX should be also set since neither FOO nor BAR are selected | ||
| 4 | # so it has no dependencies. | ||
| 5 | CONFIG_FOO=n | ||
| 6 | CONFIG_BAR=n | ||
| @@ -143,6 +143,10 @@ kallsyms() · 142 unmodified lines | |||
| 143 | kallsymopt="${kallsymopt} --all-symbols" | 143 | kallsymopt="${kallsymopt} --all-symbols" |
| 144 | fi | 144 | fi |
| 145 | 145 | ||
| 146 | if is_enabled CONFIG_64BIT || is_enabled CONFIG_RELOCATABLE; then | ||
| 147 | kallsymopt="${kallsymopt} --pc-relative" | ||
| 148 | fi | ||
| 149 | |||
| 146 | info KSYMS "${2}.S" | 150 | info KSYMS "${2}.S" |
| 147 | scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" | 151 | scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" |
| 148 | 152 | ||
| @@ -10,10 +10,14 @@ · 9 unmodified lines | |||
| 10 | Usage: | 10 | Usage: |
| 11 | make_fit.py -A arm64 -n 'Linux-6.6' -O linux | 11 | make_fit.py -A arm64 -n 'Linux-6.6' -O linux |
| 12 | -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk | 12 | -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk |
| 13 | @arch/arm64/boot/dts/dtbs-list -E -c gzip | 13 | -r /boot/initrd.img-6.14.0-27-generic @arch/arm64/boot/dts/dtbs-list |
| 14 | -E -c gzip | ||
| 14 | 15 | ||
| 15 | Creates a FIT containing the supplied kernel and a set of devicetree files, | 16 | Creates a FIT containing the supplied kernel, an optional ramdisk, and a set of |
| 16 | either specified individually or listed in a file (with an '@' prefix). | 17 | devicetree files, either specified individually or listed in a file (with an |
| 18 | '@' prefix). | ||
| 19 | |||
| 20 | Use -r to specify an existing ramdisk/initrd file. | ||
| 17 | 21 | ||
| 18 | Use -E to generate an external FIT (where the data is placed after the | 22 | Use -E to generate an external FIT (where the data is placed after the |
| 19 | FIT data structure). This allows parsing of the data without loading | 23 | FIT data structure). This allows parsing of the data without loading |
| @@ -29,12 +33,11 @@ looks at the .cmd files produced by the kernel build. · 9 unmodified lines | |||
| 29 | 33 | ||
| 30 | The resulting FIT can be booted by bootloaders which support FIT, such | 34 | The resulting FIT can be booted by bootloaders which support FIT, such |
| 31 | as U-Boot, Linuxboot, Tianocore, etc. | 35 | as U-Boot, Linuxboot, Tianocore, etc. |
| 32 | |||
| 33 | Note that this tool does not yet support adding a ramdisk / initrd. | ||
| 34 | """ | 36 | """ |
| 35 | 37 | ||
| 36 | import argparse | 38 | import argparse |
| 37 | import collections | 39 | import collections |
| 40 | import multiprocessing | ||
| 38 | import os | 41 | import os |
| 39 | import subprocess | 42 | import subprocess |
| 40 | import sys | 43 | import sys |
| @@ -48,11 +51,12 @@ import libfdt · 7 unmodified lines | |||
| 48 | CompTool = collections.namedtuple('CompTool', 'ext,tools') | 51 | CompTool = collections.namedtuple('CompTool', 'ext,tools') |
| 49 | 52 | ||
| 50 | COMP_TOOLS = { | 53 | COMP_TOOLS = { |
| 51 | 'bzip2': CompTool('.bz2', 'bzip2'), | 54 | 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'), |
| 52 | 'gzip': CompTool('.gz', 'pigz,gzip'), | 55 | 'gzip': CompTool('.gz', 'pigz,gzip'), |
| 53 | 'lz4': CompTool('.lz4', 'lz4'), | 56 | 'lz4': CompTool('.lz4', 'lz4'), |
| 54 | 'lzma': CompTool('.lzma', 'lzma'), | 57 | 'lzma': CompTool('.lzma', 'plzip,lzma'), |
| 55 | 'lzo': CompTool('.lzo', 'lzop'), | 58 | 'lzo': CompTool('.lzo', 'lzop'), |
| 59 | 'xz': CompTool('.xz', 'xz'), | ||
| 56 | 'zstd': CompTool('.zstd', 'zstd'), | 60 | 'zstd': CompTool('.zstd', 'zstd'), |
| 57 | } | 61 | } |
| 58 | 62 | ||
| @@ -81,6 +85,8 @@ def parse_args(): · 22 unmodified lines | |||
| 81 | help='Specifies the operating system') | 85 | help='Specifies the operating system') |
| 82 | parser.add_argument('-k', '--kernel', type=str, required=True, | 86 | parser.add_argument('-k', '--kernel', type=str, required=True, |
| 83 | help='Specifies the (uncompressed) kernel input file (.itk)') | 87 | help='Specifies the (uncompressed) kernel input file (.itk)') |
| 88 | parser.add_argument('-r', '--ramdisk', type=str, | ||
| 89 | help='Specifies the ramdisk/initrd input file') | ||
| 84 | parser.add_argument('-v', '--verbose', action='store_true', | 90 | parser.add_argument('-v', '--verbose', action='store_true', |
| 85 | help='Enable verbose output') | 91 | help='Enable verbose output') |
| 86 | parser.add_argument('dtbs', type=str, nargs='*', | 92 | parser.add_argument('dtbs', type=str, nargs='*', |
| @@ -98,7 +104,7 @@ def setup_fit(fsw, name): · 11 unmodified lines | |||
| 98 | fsw (libfdt.FdtSw): Object to use for writing | 104 | fsw (libfdt.FdtSw): Object to use for writing |
| 99 | name (str): Name of kernel image | 105 | name (str): Name of kernel image |
| 100 | """ | 106 | """ |
| 101 | fsw.INC_SIZE = 65536 | 107 | fsw.INC_SIZE = 16 << 20 |
| 102 | fsw.finish_reservemap() | 108 | fsw.finish_reservemap() |
| 103 | fsw.begin_node('') | 109 | fsw.begin_node('') |
| 104 | fsw.property_string('description', f'{name} with devicetree set') | 110 | fsw.property_string('description', f'{name} with devicetree set') |
| @@ -133,7 +139,28 @@ def write_kernel(fsw, data, args): · 28 unmodified lines | |||
| 133 | fsw.property_u32('entry', 0) | 139 | fsw.property_u32('entry', 0) |
| 134 | 140 | ||
| 135 | 141 | ||
| 136 | def finish_fit(fsw, entries): | 142 | def write_ramdisk(fsw, data, args): |
| 143 | """Write out the ramdisk image | ||
| 144 | |||
| 145 | Writes a ramdisk node along with the required properties | ||
| 146 | |||
| 147 | Args: | ||
| 148 | fsw (libfdt.FdtSw): Object to use for writing | ||
| 149 | data (bytes): Data to write (possibly compressed) | ||
| 150 | args (Namespace): Contains necessary strings: | ||
| 151 | arch: FIT architecture, e.g. 'arm64' | ||
| 152 | fit_os: Operating Systems, e.g. 'linux' | ||
| 153 | """ | ||
| 154 | with fsw.add_node('ramdisk'): | ||
| 155 | fsw.property_string('description', 'Ramdisk') | ||
| 156 | fsw.property_string('type', 'ramdisk') | ||
| 157 | fsw.property_string('arch', args.arch) | ||
| 158 | fsw.property_string('compression', 'none') | ||
| 159 | fsw.property_string('os', args.os) | ||
| 160 | fsw.property('data', data) | ||
| 161 | |||
| 162 | |||
| 163 | def finish_fit(fsw, entries, has_ramdisk=False): | ||
| 137 | """Finish the FIT ready for use | 164 | """Finish the FIT ready for use |
| 138 | 165 | ||
| 139 | Writes the /configurations node and subnodes | 166 | Writes the /configurations node and subnodes |
| @@ -143,6 +170,7 @@ def finish_fit(fsw, entries): · 3 unmodified lines | |||
| 143 | entries (list of tuple): List of configurations: | 170 | entries (list of tuple): List of configurations: |
| 144 | str: Description of model | 171 | str: Description of model |
| 145 | str: Compatible stringlist | 172 | str: Compatible stringlist |
| 173 | has_ramdisk (bool): True if a ramdisk is included in the FIT | ||
| 146 | """ | 174 | """ |
| 147 | fsw.end_node() | 175 | fsw.end_node() |
| 148 | seq = 0 | 176 | seq = 0 |
| @@ -154,6 +182,8 @@ def finish_fit(fsw, entries): · 5 unmodified lines | |||
| 154 | fsw.property_string('description', model) | 182 | fsw.property_string('description', model) |
| 155 | fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) | 183 | fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) |
| 156 | fsw.property_string('kernel', 'kernel') | 184 | fsw.property_string('kernel', 'kernel') |
| 185 | if has_ramdisk: | ||
| 186 | fsw.property_string('ramdisk', 'ramdisk') | ||
| 157 | fsw.end_node() | 187 | fsw.end_node() |
| 158 | 188 | ||
| 159 | 189 | ||
| @@ -179,7 +209,12 @@ def compress_data(inf, compress): · 19 unmodified lines | |||
| 179 | done = False | 209 | done = False |
| 180 | for tool in comp.tools.split(','): | 210 | for tool in comp.tools.split(','): |
| 181 | try: | 211 | try: |
| 182 | subprocess.call([tool, '-c'], stdin=inf, stdout=outf) | 212 | # Add parallel flags for tools that support them |
| 213 | cmd = [tool] | ||
| 214 | if tool in ('zstd', 'xz'): | ||
| 215 | cmd.extend(['-T0']) # Use all available cores | ||
| 216 | cmd.append('-c') | ||
| 217 | subprocess.call(cmd, stdin=inf, stdout=outf) | ||
| 183 | done = True | 218 | done = True |
| 184 | break | 219 | break |
| 185 | except FileNotFoundError: | 220 | except FileNotFoundError: |
| @@ -191,15 +226,31 @@ def compress_data(inf, compress): · 5 unmodified lines | |||
| 191 | return comp_data | 226 | return comp_data |
| 192 | 227 | ||
| 193 | 228 | ||
| 194 | def output_dtb(fsw, seq, fname, arch, compress): | 229 | def compress_dtb(fname, compress): |
| 230 | """Compress a single DTB file | ||
| 231 | |||
| 232 | Args: | ||
| 233 | fname (str): Filename containing the DTB | ||
| 234 | compress (str): Compression algorithm, e.g. 'gzip' | ||
| 235 | |||
| 236 | Returns: | ||
| 237 | tuple: (str: fname, bytes: compressed_data) | ||
| 238 | """ | ||
| 239 | with open(fname, 'rb') as inf: | ||
| 240 | compressed = compress_data(inf, compress) | ||
| 241 | return fname, compressed | ||
| 242 | |||
| 243 | |||
| 244 | def output_dtb(fsw, seq, fname, arch, compress, data=None): | ||
| 195 | """Write out a single devicetree to the FIT | 245 | """Write out a single devicetree to the FIT |
| 196 | 246 | ||
| 197 | Args: | 247 | Args: |
| 198 | fsw (libfdt.FdtSw): Object to use for writing | 248 | fsw (libfdt.FdtSw): Object to use for writing |
| 199 | seq (int): Sequence number (1 for first) | 249 | seq (int): Sequence number (1 for first) |
| 200 | fname (str): Filename containing the DTB | 250 | fname (str): Filename containing the DTB |
| 201 | arch: FIT architecture, e.g. 'arm64' | 251 | arch (str): FIT architecture, e.g. 'arm64' |
| 202 | compress (str): Compressed algorithm, e.g. 'gzip' | 252 | compress (str): Compressed algorithm, e.g. 'gzip' |
| 253 | data (bytes): Pre-compressed data (optional) | ||
| 203 | """ | 254 | """ |
| 204 | with fsw.add_node(f'fdt-{seq}'): | 255 | with fsw.add_node(f'fdt-{seq}'): |
| 205 | fsw.property_string('description', os.path.basename(fname)) | 256 | fsw.property_string('description', os.path.basename(fname)) |
| @@ -207,9 +258,10 @@ def output_dtb(fsw, seq, fname, arch, compress): · 1 unmodified line | |||
| 207 | fsw.property_string('arch', arch) | 258 | fsw.property_string('arch', arch) |
| 208 | fsw.property_string('compression', compress) | 259 | fsw.property_string('compression', compress) |
| 209 | 260 | ||
| 210 | with open(fname, 'rb') as inf: | 261 | if data is None: |
| 211 | compressed = compress_data(inf, compress) | 262 | with open(fname, 'rb') as inf: |
| 212 | fsw.property('data', compressed) | 263 | data = compress_data(inf, compress) |
| 264 | fsw.property('data', data) | ||
| 213 | 265 | ||
| 214 | 266 | ||
| 215 | def process_dtb(fname, args): | 267 | def process_dtb(fname, args): |
| @@ -249,30 +301,27 @@ def process_dtb(fname, args): · 33 unmodified lines | |||
| 249 | 301 | ||
| 250 | return (model, compat, files) | 302 | return (model, compat, files) |
| 251 | 303 | ||
| 252 | def build_fit(args): | 304 | |
| 253 | """Build the FIT from the provided files and arguments | 305 | def _process_dtbs(args, fsw, entries, fdts): |
| 306 | """Process all DTB files and add them to the FIT | ||
| 254 | 307 | ||
| 255 | Args: | 308 | Args: |
| 256 | args (Namespace): Program arguments | 309 | args: Program arguments |
| 310 | fsw: FIT writer object | ||
| 311 | entries: List to append entries to | ||
| 312 | fdts: Dictionary of processed DTBs | ||
| 257 | 313 | ||
| 258 | Returns: | 314 | Returns: |
| 259 | tuple: | 315 | tuple: |
| 260 | bytes: FIT data | 316 | Number of files processed |
| 261 | int: Number of configurations generated | 317 | Total size of files processed |
| 262 | size: Total uncompressed size of data | ||
| 263 | """ | 318 | """ |
| 264 | seq = 0 | 319 | seq = 0 |
| 265 | size = 0 | 320 | size = 0 |
| 266 | fsw = libfdt.FdtSw() | ||
| 267 | setup_fit(fsw, args.name) | ||
| 268 | entries = [] | ||
| 269 | fdts = {} | ||
| 270 | 321 | ||
| 271 | # Handle the kernel | 322 | # First figure out the unique DTB files that need compression |
| 272 | with open(args.kernel, 'rb') as inf: | 323 | todo = [] |
| 273 | comp_data = compress_data(inf, args.compress) | 324 | file_info = [] # List of (fname, model, compat, files) tuples |
| 274 | size += os.path.getsize(args.kernel) | ||
| 275 | write_kernel(fsw, comp_data, args) | ||
| 276 | 325 | ||
| 277 | for fname in args.dtbs: | 326 | for fname in args.dtbs: |
| 278 | # Ignore non-DTB (*.dtb) files | 327 | # Ignore non-DTB (*.dtb) files |
| @@ -282,24 +331,84 @@ def build_fit(args): · 3 unmodified lines | |||
| 282 | try: | 331 | try: |
| 283 | (model, compat, files) = process_dtb(fname, args) | 332 | (model, compat, files) = process_dtb(fname, args) |
| 284 | except Exception as e: | 333 | except Exception as e: |
| 285 | sys.stderr.write(f"Error processing {fname}:\n") | 334 | sys.stderr.write(f'Error processing {fname}:\n') |
| 286 | raise e | 335 | raise e |
| 287 | 336 | ||
| 337 | file_info.append((fname, model, compat, files)) | ||
| 338 | for fn in files: | ||
| 339 | if fn not in fdts and fn not in todo: | ||
| 340 | todo.append(fn) | ||
| 341 | |||
| 342 | # Compress all DTBs in parallel | ||
| 343 | cache = {} | ||
| 344 | if todo and args.compress != 'none': | ||
| 345 | if args.verbose: | ||
| 346 | print(f'Compressing {len(todo)} DTBs...') | ||
| 347 | |||
| 348 | with multiprocessing.Pool() as pool: | ||
| 349 | compress_args = [(fn, args.compress) for fn in todo] | ||
| 350 | # unpacks each tuple, calls compress_dtb(fn, compress) in parallel | ||
| 351 | results = pool.starmap(compress_dtb, compress_args) | ||
| 352 | |||
| 353 | cache = dict(results) | ||
| 354 | |||
| 355 | # Now write all DTBs to the FIT using pre-compressed data | ||
| 356 | for fname, model, compat, files in file_info: | ||
| 288 | for fn in files: | 357 | for fn in files: |
| 289 | if fn not in fdts: | 358 | if fn not in fdts: |
| 290 | seq += 1 | 359 | seq += 1 |
| 291 | size += os.path.getsize(fn) | 360 | size += os.path.getsize(fn) |
| 292 | output_dtb(fsw, seq, fn, args.arch, args.compress) | 361 | output_dtb(fsw, seq, fn, args.arch, args.compress, |
| 362 | cache.get(fn)) | ||
| 293 | fdts[fn] = seq | 363 | fdts[fn] = seq |
| 294 | 364 | ||
| 295 | files_seq = [fdts[fn] for fn in files] | 365 | files_seq = [fdts[fn] for fn in files] |
| 296 | |||
| 297 | entries.append([model, compat, files_seq]) | 366 | entries.append([model, compat, files_seq]) |
| 298 | 367 | ||
| 299 | finish_fit(fsw, entries) | 368 | return seq, size |
| 369 | |||
| 370 | |||
| 371 | def build_fit(args): | ||
| 372 | """Build the FIT from the provided files and arguments | ||
| 373 | |||
| 374 | Args: | ||
| 375 | args (Namespace): Program arguments | ||
| 376 | |||
| 377 | Returns: | ||
| 378 | tuple: | ||
| 379 | bytes: FIT data | ||
| 380 | int: Number of configurations generated | ||
| 381 | size: Total uncompressed size of data | ||
| 382 | """ | ||
| 383 | size = 0 | ||
| 384 | fsw = libfdt.FdtSw() | ||
| 385 | setup_fit(fsw, args.name) | ||
| 386 | entries = [] | ||
| 387 | fdts = {} | ||
| 388 | |||
| 389 | # Handle the kernel | ||
| 390 | with open(args.kernel, 'rb') as inf: | ||
| 391 | comp_data = compress_data(inf, args.compress) | ||
| 392 | size += os.path.getsize(args.kernel) | ||
| 393 | write_kernel(fsw, comp_data, args) | ||
| 394 | |||
| 395 | # Handle the ramdisk if provided. Compression is not supported as it is | ||
| 396 | # already compressed. | ||
| 397 | if args.ramdisk: | ||
| 398 | with open(args.ramdisk, 'rb') as inf: | ||
| 399 | data = inf.read() | ||
| 400 | size += len(data) | ||
| 401 | write_ramdisk(fsw, data, args) | ||
| 402 | |||
| 403 | count, fdt_size = _process_dtbs(args, fsw, entries, fdts) | ||
| 404 | size += fdt_size | ||
| 405 | |||
| 406 | finish_fit(fsw, entries, bool(args.ramdisk)) | ||
| 300 | 407 | ||
| 301 | # Include the kernel itself in the returned file count | 408 | # Include the kernel itself in the returned file count |
| 302 | return fsw.as_fdt().as_bytearray(), seq + 1, size | 409 | fdt = fsw.as_fdt() |
| 410 | fdt.pack() | ||
| 411 | return fdt.as_bytearray(), count + 1 + bool(args.ramdisk), size | ||
| 303 | 412 | ||
| 304 | 413 | ||
| 305 | def run_make_fit(): | 414 | def run_make_fit(): |
| @@ -602,6 +602,10 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) · 601 unmodified lines | |||
| 602 | /* Special register function linked on all modules during final link of .ko */ | 602 | /* Special register function linked on all modules during final link of .ko */ |
| 603 | if (strstarts(symname, "_restgpr0_") || | 603 | if (strstarts(symname, "_restgpr0_") || |
| 604 | strstarts(symname, "_savegpr0_") || | 604 | strstarts(symname, "_savegpr0_") || |
| 605 | strstarts(symname, "_restgpr1_") || | ||
| 606 | strstarts(symname, "_savegpr1_") || | ||
| 607 | strstarts(symname, "_restfpr_") || | ||
| 608 | strstarts(symname, "_savefpr_") || | ||
| 605 | strstarts(symname, "_restvr_") || | 609 | strstarts(symname, "_restvr_") || |
| 606 | strstarts(symname, "_savevr_") || | 610 | strstarts(symname, "_savevr_") || |
| 607 | strcmp(symname, ".TOC.") == 0) | 611 | strcmp(symname, ".TOC.") == 0) |
| @@ -958,7 +962,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, · 350 unmodified lines | |||
| 958 | /* symbols in data sections that may refer to any init/exit sections */ | 962 | /* symbols in data sections that may refer to any init/exit sections */ |
| 959 | if (match(fromsec, PATTERNS(DATA_SECTIONS)) && | 963 | if (match(fromsec, PATTERNS(DATA_SECTIONS)) && |
| 960 | match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && | 964 | match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && |
| 961 | match(fromsym, PATTERNS("*_ops", "*_probe", "*_console"))) | 965 | match(fromsym, PATTERNS("*_ops", "*_console"))) |
| 962 | return 0; | 966 | return 0; |
| 963 | 967 | ||
| 964 | /* Check for pattern 3 */ | 968 | /* Check for pattern 3 */ |