chore(release): 2.7.6 -- separate debug and release build configurations - #65
Merged
Conversation
Development instrumentation and shipping optimization are different jobs
and one set of flags cannot do both. The Makefile had two configurations
selected by `ifdef OPT` and no name for either, so the middle case — an
optimized build you can still attach a debugger to — did not exist, and a
5.6 MB `build/bin/hellish` read as the shipped binary when it never was.
Three named configurations, chosen with MODE=:
debug (default) -O0 -g3 -ggdb, ASan+LSan, libc malloc develop
release -O3 -DNDEBUG, LTO, --gc-sections, no -g ship
relwithdebinfo -O2 -g -DNDEBUG, no sanitizer, no LTO optimized bugs
462 KB / 3.0 MB / 5.6 MB respectively. Nothing is stripped afterwards:
release carries no debug information because release never compiles -g in,
which is why strip recovers ~1 KB from it — 807 bytes of libgcc
crtfastmath.c that -ffast-math pulls in already compiled with -g. None of
it is ours. No sanitizer, assertion, symbol or dependency was removed from
the debug build to get there.
OPT=1 stays working and now resolves to exactly MODE=release, byte for
byte. It used to disagree with itself: SAFE defaulted off `ifdef OPT`, so
the two spellings of one configuration picked different allocators and
produced different binaries. SAFE now keys off MODE.
Fixes a real defect found while writing the test: OBJ_DIR also keyed on
`ifdef OPT`, which covered the OPT benchmark build alone and left
MODE=release and MODE=relwithdebinfo parked in the debug tree. make
rebuilds on a changed prerequisite, never on a changed flag, so a plain
`make MODE=release` after a debug build fed the linker ASan-instrumented
objects under a link line with no -fsanitize:
func_retire.o: undefined reference to `__asan_report_load4'
`make re` hid it. Objects now live in build/obj-<mode>-<allocator>.
tests/build_modes_test.py pins all of it — 20 checks read `make flags`,
which resolves a configuration without compiling, so the test costs
nothing and cannot be fooled by a stale object tree. 3 of its checks fail
against the pre-fix OBJ_DIR. tests/link_closure_test.py now globs
build/obj* and picks the newest tree rather than the first name it
recognised, which is what its docstring always claimed.
Also corrects the update-freshness fix to reference issue #64; 2.7.5 cited
the number GitHub had assigned to the pull request.
make norm clean · golden suite 3790/3790 · pty suite green
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cuts v2.7.6 and separates the build you develop against from the build you ship.
Build configurations
makenow takesMODE=debug|release|relwithdebinfo:debug(default)-O0 -g3 -ggdb, ASan+LSan, libc mallocrelease-O3 -DNDEBUG, LTO,--gc-sections, no-g, no sanitizerrelwithdebinfo-O2 -g -DNDEBUG, no sanitizer, no LTOMeasured on this machine:
Nothing is stripped after the fact — release carries no debug information because release never compiles
-gin. The 807 bytes that remain are a single compilation unit, libgcc'scrtfastmath.c, pulled in by the pre-existing-ffast-mathand shipped by the distro already built with-g. None of our 493 translation units contribute any debug info to release. No sanitizer, assertion, symbol or dependency was removed from the debug build to get there.OPT=1— which the release workflow, the platform matrix, both install targets, the Docker build andmake benchall pass — still means exactlyMODE=release, byte for byte, and a test pins that.Two real defects found while writing the test
OPT=1disagreed with itself.SAFEdefaulted offifdef OPT, so the two spellings of one configuration picked different allocators and produced different binaries.SAFEnow keys offMODE.Build modes shared an object tree.
OBJ_DIRalso keyed onifdef OPT, covering the benchmark build alone and leavingMODE=releaseandMODE=relwithdebinfoparked in the debug tree. make rebuilds on a changed prerequisite, never on a changed flag, so a plainmake MODE=releaseafter a debug build fed the linker ASan-instrumented objects under a link line with no-fsanitize:make rehid it. Objects now live inbuild/obj-<mode>-<allocator>.Tests
tests/build_modes_test.py— 20 checks readingmake flags, which resolves a configuration without compiling, so it costs nothing and cannot be fooled by a stale object tree. 3 of its checks fail against the pre-fixOBJ_DIR, verified red-then-green.tests/link_closure_test.pynow globsbuild/obj*and picks the newest tree rather than the first name it recognised — which is what its docstring always claimed, and what a fixed list could not keep doing once modes were added.Both are picked up automatically by
tests/pty_suite.sh(it globstests/*.py), so no CI wiring was needed.Also in this release
67508ad(already on develop) —make user-installnow leaveshellishon PATH rather than only on disk. Release notes updated to cover it, since it ships under this tag.Verified locally
make norm— cleanbuild_modes_test.py20/20,user_install_path_test.py22/22