Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ this fixed order:
|------|--------|-------------|
| 1 | `make defconfig` | ARM64 base defconfig from kernel source |
| 2 | `debian/rules` | Disable `CONFIG_LOCALVERSION_AUTO` (prevents git hash in `uname -r`) |
| 3 | Unified fragment pipeline | `arch/arm64/configs/qcom.config` (if present), then `debian/config/*.config` (sorted) |
| 3 | Unified fragment pipeline | `arch/arm64/configs/prune.config`, then `arch/arm64/configs/qcom.config` (both if present), then `debian/config/*.config` (sorted) |
| 4 | `debian/rules` | Re-check `CONFIG_LOCALVERSION_AUTO` (merges may re-enable it) |
| 5 | `arch/arm64/configs/debug.config` | Debug options — only when `DEB_BUILD_PROFILES=debug` |

Expand All @@ -449,12 +449,17 @@ this fixed order:
All config fragments are processed through a single unified pipeline:

1. Collect fragments in order:
- `arch/arm64/configs/qcom.config` first (kernel-source fragment, present in `qcom-next`)
- `arch/arm64/configs/prune.config` first (kernel-source fragment)
- then `arch/arm64/configs/qcom.config` (kernel-source fragment, present in
`qcom-next`), so it wins over anything `prune.config` turned off
- then `debian/config/*.config` in sorted filename order
2. Append all collected fragments to `.config`
2. Merge all collected fragments into `.config` in one
`scripts/kconfig/merge_config.sh -m -r` invocation — later fragments override
earlier ones, and every override is reported
3. Run `make olddefconfig` once to resolve all conflicts and fill in dependencies

`qcom.config` and `debian/config/*.config` use exactly the same mechanism.
`prune.config`, `qcom.config` and `debian/config/*.config` use exactly the same
mechanism.

### `debian/config/` — always-applied fragments

Expand Down Expand Up @@ -499,18 +504,26 @@ verbatim so drift is a plain diff; only the SPDX header is added locally.
| `usb-can.config` | slcan, gs_usb, peak_usb | USB CAN adapter demos/testing |

**In-tree fragments.** `--kernel-config` carries fragments applied *in addition*
to the set above. Today that means fragments shipped by the kernel source under
`arch/arm64/configs/`, referenced with an `intree:` prefix rather than copied
into this repository so they stay versioned with the kernel they target:
to the set above. Today that means fragments shipped by the kernel source,
referenced with an `intree:` prefix rather than copied into this repository so
they stay versioned with the kernel they target:

```
--kernel-config intree:qcom_debug
--kernel-config intree:arch/arm64/configs/qcom_debug.config,intree:kernel/configs/debug.config
```

`intree:<name>` resolves to `arch/arm64/configs/<name>.config`. A bare name is
still accepted for compatibility but is redundant, since that fragment is
already applied. An in-tree fragment sharing a filename with a packaging
fragment is rejected rather than silently overwriting it.
`intree:<path>` names a file relative to the kernel source root, so any
directory in the tree can be used, not just `arch/arm64/configs/`. The path must
end in `.config`, and an absolute path or one containing `..` is rejected. The
fragment is copied into `debian/config/` under its basename, so two entries
resolving to the same filename — whether two in-tree paths
(`arch/arm64/configs/hardening.config` and `kernel/configs/hardening.config`) or
an in-tree path and a packaging fragment — are rejected rather than one silently
overwriting the other.

A bare name (no `intree:` prefix) is still accepted for compatibility but is
redundant, since every fragment in `debian/config-available/` is already
applied.

**Activating via `build-kernel.sh`:**

Expand Down
4 changes: 2 additions & 2 deletions build-kernel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ OPTIONS:
--profiles PROFILES DEB_BUILD_PROFILES (e.g. debug)
--kernel-config LIST Extra config fragments, beyond debian/config-available/
which is always applied in full. An "intree:" prefix
resolves to arch/arm64/configs/<name>.config in the
kernel source (e.g. intree:qcom_debug)
names a path relative to the kernel source root
(e.g. intree:arch/arm64/configs/qcom_debug.config)

Paths:
-k, --kernel-dir DIR Kernel source directory (default: $KERNEL_DIR)
Expand Down
34 changes: 20 additions & 14 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,16 @@ override_dh_auto_configure:
# 1. ARM64 base defconfig
# 2. Disable CONFIG_LOCALVERSION_AUTO (must happen before any merges)
# 3. Config fragments applied in a single unified pipeline:
# a. arch/arm64/configs/qcom.config (kernel-source, always applied if present)
# b. arch/arm64/configs/prune.config (kernel-source, always applied if present)
# a. arch/arm64/configs/prune.config (kernel-source, always applied if present)
# b. arch/arm64/configs/qcom.config (kernel-source, always applied if present)
# c. debian/config/*.config (packaging fragments)
# Populated by prepare-source.sh: every fragment in
# debian/config-available/, plus any intree: fragments named in
# --kernel-config. Applied in LC_ALL=C filename order so the
# result does not depend on the builder's locale.
# All fragments: append to .config + make olddefconfig.
# All fragments are merged in one scripts/kconfig/merge_config.sh -m -r
# invocation (later fragments win, overrides are reported), followed by
# make olddefconfig to resolve the resulting dependencies.
# 4. Re-check CONFIG_LOCALVERSION_AUTO (merges may re-enable it)
# 5. arch/arm64/configs/debug.config — only when DEB_BUILD_PROFILES=debug
# ---------------------------------------------------------------------------
Expand All @@ -198,18 +200,18 @@ override_dh_auto_configure:
# Step 3: Unified config fragment pipeline.
@CONFIG_FILE="$(if $(BUILD_OBJ),$(BUILD_OBJ)/).config"; \
FRAGMENTS=""; \
if [ -f arch/arm64/configs/qcom.config ]; then \
echo "Found kernel-source fragment: arch/arm64/configs/qcom.config"; \
FRAGMENTS="arch/arm64/configs/qcom.config"; \
else \
echo "Note: arch/arm64/configs/qcom.config not found (not a qcom-next tree?)"; \
fi; \
if [ -f arch/arm64/configs/prune.config ]; then \
echo "Found kernel-source fragment: arch/arm64/configs/prune.config"; \
FRAGMENTS="$$FRAGMENTS arch/arm64/configs/prune.config"; \
FRAGMENTS="arch/arm64/configs/prune.config"; \
else \
echo "Note: arch/arm64/configs/prune.config not found (skipping)"; \
fi; \
if [ -f arch/arm64/configs/qcom.config ]; then \
echo "Found kernel-source fragment: arch/arm64/configs/qcom.config"; \
FRAGMENTS="$$FRAGMENTS arch/arm64/configs/qcom.config"; \
else \
echo "Note: arch/arm64/configs/qcom.config not found (not a qcom-next tree?)"; \
fi; \
if [ -d debian/config ] && ls debian/config/*.config >/dev/null 2>&1; then \
for f in $$(ls debian/config/*.config | LC_ALL=C sort); do \
echo "Found packaging fragment: $$f"; \
Expand All @@ -219,10 +221,14 @@ override_dh_auto_configure:
echo "Note: no packaging fragments in debian/config/ (none activated via --kernel-config)"; \
fi; \
if [ -n "$$FRAGMENTS" ]; then \
for frag in $$FRAGMENTS; do \
echo "Applying config fragment: $$frag"; \
cat "$$frag" >> "$$CONFIG_FILE"; \
done; \
[ -x scripts/kconfig/merge_config.sh ] || { \
echo "ERROR: scripts/kconfig/merge_config.sh not found or not executable"; \
exit 1; \
}; \
echo "Merging config fragments into $$CONFIG_FILE:$$FRAGMENTS"; \
ARCH=$(ARCH) scripts/kconfig/merge_config.sh -m -r \
$(if $(BUILD_OBJ),-O $(BUILD_OBJ)) \
"$$CONFIG_FILE" $$FRAGMENTS; \
echo "Running olddefconfig to resolve all fragment conflicts..."; \
$(MAKE) $(KBUILD_O_ARG) ARCH=$(ARCH) olddefconfig; \
else \
Expand Down
52 changes: 38 additions & 14 deletions prepare-source.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ OPTIONS:
--kernel-config LIST Comma-separated fragments to apply in addition to
debian/config-available/, every entry of which is
applied to every build regardless of this option.
An "intree:" prefix resolves to
arch/arm64/configs/<name>.config in the kernel
source, for fragments that ship with the kernel
and are versioned with it
(e.g. intree:qcom_debug).
An "intree:" prefix names a path relative to the
kernel source root, for fragments that ship with
the kernel and are versioned with it
(e.g. intree:arch/arm64/configs/qcom_debug.config
or intree:kernel/configs/debug.config). The path
must end in .config; absolute paths and ".." are
rejected.
A bare name is accepted for compatibility but is
redundant, since that fragment is already applied.
Entries are processed in LC_ALL=C sorted order.
Expand Down Expand Up @@ -208,7 +210,6 @@ log_info "Copied $ACTUAL_DEBIAN_DIR -> $SOURCE_DIR/debian"
# has already been applied.
ACTIVE_DIR="$SOURCE_DIR/debian/config"
AVAIL_DIR="$SOURCE_DIR/debian/config-available"
INTREE_DIR="$SOURCE_DIR/arch/arm64/configs"
mkdir -p "$ACTIVE_DIR"

log_step "Applying all packaging fragments from debian/config-available/"
Expand All @@ -233,22 +234,45 @@ if [[ -n "$KERNEL_CONFIG" ]]; then
if [[ "$cfg" == intree:* ]]; then
# In-tree fragment, shipped by the kernel source rather than by this
# repository. Referenced instead of vendored so it stays versioned
# with the kernel it targets.
frag="${cfg#intree:}"
frag="${frag%.config}.config"
src="$INTREE_DIR/$frag"
# with the kernel it targets. The entry spells the whole path
# relative to the kernel source root, so fragments outside
# arch/arm64/configs/ are reachable too (kernel/configs/debug.config).
path="${cfg#intree:}"
case "$path" in
"" | /* | ".." | "../"* | *"/../"* | *"/..")
log_error "Invalid in-tree fragment: ${cfg}"
log_error "Expected a path relative to the kernel source root, e.g. intree:arch/arm64/configs/qcom_debug.config"
exit 1
;;
esac
# debian/rules globs debian/config/*.config, so a fragment named
# anything else would be copied in and then silently ignored.
[[ "$path" == *.config ]] || {
log_error "In-tree fragment must name a .config file: $cfg"
log_error "Spell the whole path, e.g. intree:arch/arm64/configs/qcom_debug.config"
exit 1
}
src="$SOURCE_DIR/$path"
frag="$(basename "$path")"
dir="$(dirname "$path")"
[[ -f "$src" ]] || {
log_error "In-tree fragment not found: arch/arm64/configs/$frag"
log_error "Available: $(ls "$INTREE_DIR"/*.config 2>/dev/null | xargs -n1 basename | tr '\n' ' ')"
log_error "In-tree fragment not found: $path"
log_error "Paths are relative to the kernel source root ($SOURCE_DIR)."
avail="$(ls "$SOURCE_DIR/$dir"/*.config 2>/dev/null | xargs -n1 basename | tr '\n' ' ')"
[[ -n "$avail" ]] && log_error "Available in $dir/: $avail"
exit 1
}
# The fragment keeps only its basename in debian/config/, so two
# in-tree paths can collide with each other as well as with a
# packaging fragment (kernel/configs/hardening.config and
# arch/arm64/configs/hardening.config both exist).
[[ -e "$ACTIVE_DIR/$frag" ]] && {
log_error "Fragment name collision in debian/config/: $frag"
log_error "An in-tree fragment must not share a filename with a packaging fragment."
log_error "An in-tree fragment must not share a filename with an already applied fragment."
exit 1
}
cp "$src" "$ACTIVE_DIR/$frag"
log_info " Applied: $frag (from arch/arm64/configs)"
log_info " Applied: $frag (from $dir)"
else
frag="${cfg%.config}.config"
[[ -f "$AVAIL_DIR/$frag" ]] || {
Expand Down
Loading