build: separate build dirs for sanitizer and coverage builds#23
Conversation
All sanitizer flavors shared one platform build dir (eg 'linux'), so
switching asan<->tsan<->none forced a full CMake reconfigure (and the
occasional stale-mix build failure). Suffix the build dir per sanitizer
('linux-asan', 'linux-tsan', 'linux-ubsan', 'linux-lsan') in the two
funnels that pick it. No sanitizer keeps the old name, so existing
caches stay valid; first build of each flavor after upgrade configures
once into its new dir.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Coverage builds shared a build dir with plain (and sanitizer) builds, forcing a full reconfigure whenever you switched flavors. Extend build_dir_suffix() to prepend a '-coverage' marker, composing with the existing sanitizer suffix: plain -> linux, coverage -> linux-coverage, asan -> linux-asan (unchanged), coverage+asan -> linux-coverage-asan. Both consumers (platform_build_dir_name and dependency_chain's MAMA_BUILD define) flow through the same helper, so dep include paths stay consistent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| Coverage builds add '-coverage' and sanitizer builds add a further | ||
| suffix, eg 'linux-coverage', 'linux-asan' or 'linux-coverage-asan'. | ||
| """ | ||
| # WARNING: This needs to be in sync with dependency_chain.py: _save_mama_cmake !!! |
There was a problem hiding this comment.
fixed, a clanker got spliced for that mistake
The comment about sync with dependency_chain.py was accidentally left on the public wrapper after the implementation was split into the private helper. Move it to the method whose body actually needs to stay in sync. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| # gets the defines for a single platform and architecture | ||
| # must match platform_build_dir_name(): same sanitizer suffix as the actual build dir | ||
| def get_build_dir_defines(build_dir): | ||
| build_dir += c.build_dir_suffix() |
There was a problem hiding this comment.
This is fishy and doesn't seem to belong here, the whole suffix definition should be done inside BuildConfig (single source of truth). This would also remove the unnecessary comment must match platform_build_dir_name() -- because in reality even Claude will not often read this properly.
build_dir = c.build_dir_with_suffix(build_dir)
This would delegate the single source of truth into BuildConfig class, and BuildConfig.platform_build_dir_name() can also use it
|
Concrete motivation to land this: it would've caught KrattWorks/rtpvideo#4 — an unaligned |
…ith_suffix() Replace the split build_dir_suffix() + manual += in dependency_chain.py with a build_dir_with_suffix(build_dir) method on BuildConfig. Both platform_build_dir_name() and get_build_dir_defines() now call the same method, removing the "must match" guard comment and the WARNING. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Problem
All sanitizer flavors write to the same platform build dir (
packages/<pkg>/linux,windows, …).self.sanitizeisn't part of the build path, so switching betweenasan/tsan/ubsan/ none reuses one dir with a different sanitizer than it was configured for.run_config()then sees the sanitizer marker changed and forces a full CMake reconfigure every switch — slow, and occasionally a stale-mix build failure. Coverage (mama coverage) had the exact same problem: it landed in plainlinuxand collided with both plain and sanitizer builds.Fix
Suffix the build dir per flavor via one
build_dir_suffix()helper, reusing the existing CLI short tokens for sanitizers and adding a-coveragemarker that composes cleanly in front of any sanitizer suffix:linux(unchanged)coveragelinux-coverageaddresslinux-asanthreadlinux-tsanundefinedlinux-ubsanleaklinux-lsancoverage+addresslinux-coverage-asan(and the same for every platform:
windows-asan,android-tsan,linux-coverage, …)The helper is applied in the two places that pick the per-platform name:
platform_build_dir_name()anddependency_chain._save_mama_cmake'sget_build_dir_defines(kept in sync per the existing WARNING comment, so dependencymama.cmakeinclude paths match the suffixed dep dirs). No coverage and no sanitizer ⇒ no suffix ⇒ existing caches stay valid. Each flavor now keeps its own dir +CMakeCache.txt, so switching between already-built flavors no longer reconfigures.Coverage
mama coverage buildnow lands inlinux-coverageinstead of sharinglinux. The marker is prepended to the sanitizer suffix, somama coverage asan build→linux-coverage-asan, keeping the previously-reviewed sanitizer dir names byte-identical (linux-asan, etc.). Plainmama buildis unchanged (linux), so existing non-coverage caches stay valid.Verification
tests/test_build_dir/asserts the per-sanitizer names, the new coverage-only (linux-coverage) and coverage+sanitizer (linux-coverage-asan) names, and that no-coverage/no-sanitizer is unchanged. Full existing suite is green — 87 tests (prior 85 + 2 new coverage cases).Ran the patched mama against a throwaway CMake project:
mama coverage build,mama asan build, andmama coverage asan buildcreate separatelinux-coverage/linux-asan/linux-coverage-asandirs; theMAMA_BUILDdefine in the generatedmama.cmakematches the on-disk dir for each; re-running each already-built flavor skips CMake configure (no churn); plainbuildstill useslinux.Back-compat note
First build of each flavor after upgrading mama configures once into its new suffixed dir (the old shared
linuxdir keeps the plain no-coverage/no-sanitizer build). Expected, one-time.Supersedes #22 (moved off fork to a branch on this repo).
LOC breakdown