Skip to content

make clean / make distclean leave generated files behind (measured on Linux + macOS)Β #3878

Description

@mcfnord

πŸ€– AI

Follow-up to this thread on #3785, where @pljones noticed builds leave the working directory messy and @ann0see suggested an issue. Below are the results of the exact protocol proposed there: fresh clone β†’ save a full file listing β†’ build β†’ make clean β†’ listing β†’ make distclean β†’ listing, then diff.

Setup: commit a24e09c. Linux: Ubuntu 22.04, Qt 5.15.3, three configs (default, headless serveronly, nosound). macOS: 12.7.6, Qt 5.15.2, -spec macx-clang, default config. Android: cross-built with .github/autobuild/android.sh's exact pins (Qt 5.15.2 android, NDK r21d, JDK 8, android-30), qmake -spec android-clang, default 4-ABI multi-arch, including the CI flow's make install INSTALL_ROOT=build and androiddeployqt --gradle stages.

After make clean (Linux, default config) 9 files remain:

.qmake.stash
Jamulus
Makefile
Makefile.Debug
Makefile.Release
debug/qmake_qmake_qm_files.qrc
release/qmake_qmake_qm_files.qrc
linux/jamulus.desktop
linux/jamulus-server.desktop

The binary and Makefiles are standard qmake semantics (distclean's job, not clean's), but the generated .desktop files and the .qrc stubs are already outside the clean scope. headless serveronly and nosound behave the same modulo the .desktop files.

After make distclean, in every Linux config, two files survive:

debug/qmake_qmake_qm_files.qrc
release/qmake_qmake_qm_files.qrc

qmake generates these for the lrelease + embed_translations setup (Jamulus.pro lines 31–32) but its generated distclean rule never removes them. They're worse than inert cruft: each one embeds absolute local paths to .qm files that distclean just deleted, so the leftover refers to a machine-specific, no-longer-existing state. Empty debug/, release/ and .qm/ directories also remain.

macOS behaves identically: after make distclean the same two .qrc files survive (after make clean, the Jamulus.app bundle skeleton also remains β€” standard target semantics, as on Linux).

Notably, none of this shows up in git status: .gitignore names qmake_qmake_qm_files.qrc explicitly β€” the cruft has historically been hidden from git rather than removed by the clean rules.

Android is the messiest, matching the original observation. After make clean, 564 files remain (.qmake.stash, 9 Makefiles, four libJamulus_<abi>.so targets, plus everything below). After make distclean, 550 files remain:

android-Jamulus-deployment-settings.json    ← generated by qmake, survives distclean, and
                                              visible in plain `git status` β€” the one leftover
                                              .gitignore doesn't even hide
debug-<abi>/qmake_qmake_qm_files.qrc        ← the same lrelease escape Γ— 8: one stub per
release-<abi>/qmake_qmake_qm_files.qrc        ABI/config pair, same absolute-path contents
build/                                      ← 541 files (the installed libs + the generated
                                              gradle project) β€” outside make's knowledge
                                              entirely; listed because the CI recipe places
                                              it inside the source tree

The fix line above is a no-op on Android β€” measured: all 8 stubs survive distclean with it applied β€” because the multi-ABI build writes the stubs to debug-<abi>//release-<abi>/, not debug//release/ (resources_functions.prf:45). The working replacement, verified to leave zero qmake-generated files behind (only empty directories) on Linux, Android, and macOS:

android {
    for (abi, ANDROID_ABIS) {
        QMAKE_DISTCLEAN += $$shell_path(debug-$${abi}/qmake_qmake_qm_files.qrc) $$shell_path(release-$${abi}/qmake_qmake_qm_files.qrc)
    }
    QMAKE_DISTCLEAN += $$shell_path(android-$${TARGET}-deployment-settings.json)
} else {
    QMAKE_DISTCLEAN += $$shell_path(debug/qmake_qmake_qm_files.qrc) $$shell_path(release/qmake_qmake_qm_files.qrc)
}

($$RCC_DIR/qmake_qmake_qm_files.qrc would be the principled spelling, but RCC_DIR is still empty when the .pro is parsed β€” measured: it removes nothing on either platform.)

I can turn that into a PR if the approach is agreed.

Not measured yet: Windows β€” the CI path builds qmake Makefiles via jom (windows/deploy_windows.ps1), so the same protocol applies there; hardware for it becomes available within the next week. iOS has no make distclean to test (ios/deploy_ios.sh generates an Xcode project and builds with xcodebuild), so only the analogous "what does a build leave in the tree" question exists; a Mac able to answer it is available in the same window.


πŸ€– This message was written by AI and reviewed by @mcfnord.

Metadata

Metadata

Assignees

No one assigned

    Labels

    AIAI generated or potentially AI generated

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions