microsoft / microsoft/azure-linux-dev-tools

`spec-remove-subpackage` drops `%define` macros inside the removed subpackage that are referenced elsewhere

Open
#203 0 comments 0 reactions 1 assignee View on GitHub

@trungams is already working on this.

Since Sep 1, 2026.

area: overlays enhancement
Dominant language
Go
Stars
18
Forks
27
Avg merge
4d 33m
Merged PRs (30d)
24

Description

Summary

spec-remove-subpackage deletes the entire %package / %description / %files block of the targeted subpackage but does not preserve %define (or %global) macros that live inside that block when they are referenced from sections that survive removal (%install, %build, %check, etc.). The macro is silently dropped, the referencing section keeps the now-undefined %{macro} references, and the build fails far away -- for instance with Installed (but unpackaged) files found: on the payload that the surviving section was supposed to clean up.

Repro

Component: qemu on the 4.0 branch of microsoft/azurelinux.

Upstream qemu.spec (Fedora rawhide, commit f2cb21ff470d94a6dfd2a2e6ef9effeaa3aead1f) defines %{testsdir} inside the %package tests block:

%package tests
Summary: tests for the %{name} package
Requires: %{name} = %{evr}

%define testsdir %{_libdir}/%{name}/tests-src

%description tests
The %{name}-tests rpm contains tests ...

%{testsdir} is then referenced from %install, which is not guarded by any "tests enabled" conditional — the upstream %install unconditionally creates %{buildroot}%{testsdir}/... and copies the test fixtures there:

%install
...
mkdir -p %{buildroot}%{testsdir}/python
mkdir -p %{buildroot}%{testsdir}/tests
mkdir -p %{buildroot}%{testsdir}/tests/qemu-iotests
mkdir -p %{buildroot}%{testsdir}/scripts/qmp

cp -R %{qemu_kvm_build}/python/qemu %{buildroot}%{testsdir}/python
cp -R %{qemu_kvm_build}/scripts/qmp/* %{buildroot}%{testsdir}/scripts/qmp
install -p -m 0755 tests/Makefile.include %{buildroot}%{testsdir}/tests/
...

Apply this overlay:

[[components.qemu.overlays]]
description = "Remove qemu-tests subpackage"
type = "spec-remove-subpackage"
package = "tests"

Render with azldev comp render -p qemu and inspect specs/q/qemu/qemu.spec.

azldev version reproduced against:

azldev version v0.1.1-0.20260521162032-fc8fadad257d
Expected

spec-remove-subpackage detects that %define / %global statements inside the removed subpackage are referenced from sections that survive removal, and preserves them (for example, by hoisting them to just before the removed section).

(The same logic should apply symmetrically to spec-remove-section when targeting a %package section that contains macro definitions referenced elsewhere.)

Actual

%package tests, %description tests, and %files tests are correctly removed — but the %define testsdir line vanishes along with the block. Every %install reference to %{testsdir} survives unchanged. RPM expansion then produces commands like mkdir -p /.../buildroot%{testsdir}/python literally (the unexpanded %{testsdir} token is appended to the buildroot path), so the real /usr/lib/qemu/tests-src/... payload is written under one nonsensical path and any follow-up cleanup overlay trying to rm -rf %{buildroot}%{testsdir} cannot find it. The build trips Installed (but unpackaged) files found: on the leftover payload.

Today this has to be worked around with an explicit spec-search-replace overlay that hoists the %define near the top of the spec, e.g.:

{ description = "Hoist %define testsdir to top of spec",
  type      = "spec-search-replace",
  regex     = '^%global enable_werror 0$',
  replacement = "%global enable_werror 0\n%define testsdir %{_libdir}/%{name}/tests-src" },

Side note (not part of this bug)

While reproducing the above, spec-remove-section (used for the surrounding audio backends in the same component) was observed to leave empty %if … %endif wrappers around subpackages whose entire body was removed — e.g. %if %{have_dbus_display} followed immediately by %endif after audio-dbus is gone. This is functionally inert (rpmspec -P parses the spec fine and the build succeeds), so it is not a separate bug — just flagging in case the cleanup pass that addresses the %define case can also collapse fully-empty conditional wrappers.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.