build_config: give each host build config a name of its own - #7195
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Included review availability: Your plan includes up to 8 reviews per rolling hour; 6 remain after this review. 📝 WalkthroughWalkthroughThe build configurations now use dedicated names and directories for specialized host builds. The no-float build includes ChangesDedicated MRuby build targets
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change gives each host build configuration its own build directory, preventing build artifacts and binaries from being mixed across configurations. The supplied verification shows the default build remains intact and the named configurations produce their expected outputs, so no actionable merge-blocking risk remains beyond normal checks. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
build_config/host-f32.rb, host-gprof.rb, host-m32.rb and host-m32-f32.rb
each opened an anonymous `MRuby::Build`, and an unnamed build is called
'host' (lib/mruby/build.rb:94). The build tree is keyed by that name
(:107), so each of them wrote its objects straight into build/host, on
top of whatever a default build had left there. None of the four ever
created a build directory of its own.
host-f32 shows the shape, and it exits 0 while doing it. Starting from
a good default build:
$ md5sum build/host/bin/mruby build/host/lib/libmruby.a
c5ab48eae68084c5cbf07fccaa5cf0db build/host/bin/mruby
7156ead7b09d5deb56a44776fa23dc7a build/host/lib/libmruby.a
$ build/host/bin/mruby -e 'p 0.1+0.2'
0.30000000000000004
$ MRUBY_CONFIG=host-f32 rake -j8 # exit 0
...
Config Name: host
Output Directory: build/host
$ ls build/
host
$ md5sum build/host/bin/mruby build/host/lib/libmruby.a
9ed6eedb366400055b1ffb780c81c842 build/host/bin/mruby
d4112da25dfdadf33ad214793396ceef build/host/lib/libmruby.a
$ build/host/bin/mruby -e 'p 0.1+0.2'
0.30000001192092896
What is left in build/host is an `MRB_USE_FLOAT32` mruby, and the repo
bin/ symlinks point into it, because `host?` builds install them (:452).
The damage outlives the run. libmruby.a is archived with `ar rs`
(lib/mruby/build/command.rb:258), and r replaces but never removes, so
members accumulate across config switches: 99 unique members before the
host-f32 run, 107 after, since full-core.gembox carries gems that
default.gembox does not. Building the default config again does not
recover the tree. It exits 0 and leaves one that cannot boot at all:
$ rake -j8 # exit 0
$ build/host/bin/mruby -e 'p 1'
(unknown):0: uninitialized constant digits::other_excl (NameError)
The presym tables are regenerated for the smaller gem set while the
extra members stay in the archive, so the objects and the tables
disagree about which symbol id is which. Recovery is rm -rf build/host
plus a full rebuild.
Name each build after its config. full-core.gembox supplies
mruby-bin-mrbc through its glob, so the rename is all the four need.
Each now builds into its own directory and leaves an existing host build
byte-identical:
$ MRUBY_CONFIG=host-f32 rake -j8
Config Name: host-f32
Output Directory: build/host-f32
$ MRUBY_CONFIG=host-gprof rake -j8
Config Name: host-gprof
Output Directory: build/host-gprof
$ md5sum build/host/bin/mruby build/host/lib/libmruby.a
c5ab48eae68084c5cbf07fccaa5cf0db build/host/bin/mruby
7156ead7b09d5deb56a44776fa23dc7a build/host/lib/libmruby.a
$ ar t build/host/lib/libmruby.a | sort -u | wc -l
99
build_config/asan.rb already does this, and its own comment says why.
host-m32 and host-m32-f32 need a 32-bit toolchain that the machine's own
gcc cannot supply: it carries no multilib libc, so `-m32` stops at the
first compile, on bits/libc-header-start.h. Pointing the gcc toolchain
at i686-linux-gnu-gcc through the environment builds both, and they land
in directories of their own as well:
$ export CC=i686-linux-gnu-gcc CXX=i686-linux-gnu-g++ \
LD=i686-linux-gnu-gcc AR=i686-linux-gnu-gcc-ar
$ MRUBY_CONFIG=host-m32 rake -j8 # exit 0
$ MRUBY_CONFIG=host-m32-f32 rake -j8 # exit 0
$ file build/host-m32/bin/mruby
ELF 32-bit LSB pie executable, Intel 80386, ..., interpreter
/lib/ld-linux.so.2, ...
$ build/host-m32/bin/mruby -e 'p 1.class'
Integer
$ build/host-m32/bin/mruby -e 'p 0.1+0.2'
0.30000000000000004
$ build/host-m32-f32/bin/mruby -e 'p 0.1+0.2'
0.30000001192092896
$ md5sum build/host/bin/mruby build/host/lib/libmruby.a
c5ab48eae68084c5cbf07fccaa5cf0db build/host/bin/mruby
7156ead7b09d5deb56a44776fa23dc7a build/host/lib/libmruby.a
build_config/host-nofloat.rb opened an anonymous `MRuby::Build`, and an
unnamed build is called 'host' (lib/mruby/build.rb:94). The build tree
is keyed by that name (:107), so MRUBY_CONFIG=host-nofloat wrote
`MRB_NO_FLOAT` objects straight into build/host, on top of whatever a
default build had left there. No build/host-nofloat was ever created.
Starting from a good default build:
$ ls build/
host
$ md5sum build/host/bin/mruby build/host/bin/mrbc
c5ab48eae68084c5cbf07fccaa5cf0db build/host/bin/mruby
2138e925f0e738d9240e0e71d82a3a73 build/host/bin/mrbc
$ MRUBY_CONFIG=host-nofloat rake -j8 # exit 0
...
Config Name: host
Output Directory: build/host
$ ls build/
host
$ md5sum build/host/bin/mruby build/host/bin/mrbc
f69af2ed9fd24b7ddcfb013114b8db8e build/host/bin/mruby
2138e925f0e738d9240e0e71d82a3a73 build/host/bin/mrbc
$ build/host/bin/mruby -e 'p 1'
trace (most recent call last):
[1] mrblib/kernel.rb:27
mrblib/kernel.rb:27:in module_function: wrong argument type Symbol
(expected Symbol) (TypeError)
That last failure is a boot failure and not a float one, this config
fails on any input both before and after this commit (see the end of
this message). What it shows here is only that build/host/bin/mruby
has stopped being the default build's mruby.
build/host/bin/mrbc was left untouched while build/host/bin/mruby was
relinked, so the tree is not even a consistent `MRB_NO_FLOAT` build.
That mrbc still compiles a float literal afterwards:
$ echo 'p 1.5' > /tmp/f.rb
$ build/host/bin/mrbc -o /tmp/f.mrb /tmp/f.rb # exit 0
The repo bin/ symlinks point into this tree as well, since `host?`
builds install them (:452), so bin/mruby is that binary too. bin/mrbc
need not be the one beside it: tasks/bin.rake:2 installs the internal
build/host/mrbc/bin/mrbc over it for a `host?` build carrying no
mruby-bin-mrbc gem of its own, and that one is compiled with
`MRB_NO_FLOAT`. Which of the two the symlink ends up at is decided by
which of them rake found out of date.
So what the tree hands back afterwards depends on what happened to get
relinked. Any measurement taken through this config silently measures
a mixed tree, and recovery is rm -rf build/host plus a full rebuild.
Naming the build is not enough on its own. The internal mrbc build is
created only for a `host?` build or one that carries mruby-bin-mrbc
(:153), and none of the gemboxes this config loads supplies it. Only
default.gembox does:
$ grep -n mruby-bin-mrbc mrbgems/stdlib.gembox mrbgems/stdlib-ext.gembox \
mrbgems/stdlib-io.gembox mrbgems/metaprog.gembox mrbgems/default.gembox
mrbgems/default.gembox:9: conf.gem :core => "mruby-bin-mrbc"
so the rename alone aborts before it compiles anything:
$ MRUBY_CONFIG=host-nofloat rake -j8
rake aborted!
external mrbc or mruby-bin-mrbc gem in current('host-nofloat') or
'host' build is required
lib/mruby/build.rb:364:in `mrbcfile'
Name the build 'host-nofloat' and add mruby-bin-mrbc so it can supply
its own compiler. build_config/gctest.rb is the same pair for the same
reason, a named build with an explicit mruby-bin-mrbc line; asan.rb is
named too and picks mrbc up implicitly, through full-core.gembox. The
config now builds into its own directory and leaves an existing host
build byte-identical:
$ MRUBY_CONFIG=host-nofloat rake -j8
...
Config Name: host-nofloat
Output Directory: build/host-nofloat
$ md5sum build/host/bin/mruby build/host/bin/mrbc
c5ab48eae68084c5cbf07fccaa5cf0db build/host/bin/mruby
2138e925f0e738d9240e0e71d82a3a73 build/host/bin/mrbc
$ build/host/bin/mruby -e 'p 0.1+0.2'
0.30000000000000004
Whether the resulting `MRB_NO_FLOAT` binary runs is a separate matter
and is unchanged here. It fails to boot the same way when built into a
directory of its own:
$ build/host-nofloat/bin/mruby -e 'p 1'
mrblib/kernel.rb:27:in module_function: wrong argument type Symbol
(expected Symbol) (TypeError)
build_config/host-shared.rb opened an anonymous `MRuby::Build`, and an
unnamed build is called 'host' (lib/mruby/build.rb:94). The build tree
is keyed by that name (:107), so MRUBY_CONFIG=host-shared aimed its
`-fPIC`, `enable_debug` objects at build/host and its libmruby.so at
build/host/lib. No build/host-shared was ever created.
What that costs is decided by the timestamps in build/host, and both
answers are wrong. Starting from a good default build, rake compares
timestamps rather than compiler flags, finds every object up to date,
recompiles nothing, and links the shared library out of the archive the
default build left, which is not `-fPIC`:
$ ls build/host/lib/
libmruby.a libmruby.flags.mak
$ MRUBY_CONFIG=host-shared rake -j8
LD build/host/lib/libmruby.so
ld: build/host/lib/libmruby.a(codegen.o): relocation R_X86_64_PC32
against symbol `stderr@@GLIBC_2.2.5' can not be used when making a
shared object; recompile with -fPIC
ld: final link failed: bad value
rake aborted!
When the objects are out of date instead, the tree is rebuilt with
`-fPIC` and `MRB_DEBUG` into build/host and the .so is produced there,
and this one never announces itself afterwards. Both configs load the
same gembox, so the object set matches, and the default build after it
finds the tree up to date, exits 0, changes nothing and hands that
foreign tree back. The libmruby.so and libmruby.so.4.0 left in
build/host/lib outlive every later default build, because nothing in
the default pipeline knows about them. Recovery is rm -rf build/host
plus a full rebuild.
Name the build 'host-shared'. default.gembox supplies mruby-bin-mrbc,
so the rename is all the build itself needs, but the post-build pass
that adds the shared-library targets picks its target by name and has to
follow it, or the config would build and produce no .so at all. The
header comment's build/host paths are updated to match. The config now
builds into its own directory and leaves an existing host build
byte-identical:
$ MRUBY_CONFIG=host-shared rake -j8
...
Config Name: host-shared
Output Directory: build/host-shared
$ ls build/host-shared/lib/
libmruby.a libmruby.flags.mak libmruby.so libmruby.so.4.0
$ objdump -p build/host-shared/lib/libmruby.so | grep SONAME
SONAME libmruby.so.4.0
$ md5sum build/host/bin/mruby build/host/lib/libmruby.a
c5ab48eae68084c5cbf07fccaa5cf0db build/host/bin/mruby
7156ead7b09d5deb56a44776fa23dc7a build/host/lib/libmruby.a
$ ls build/host/lib/
libmruby.a libmruby.flags.mak
build_config/asan.rb already does this, and its own comment says why.
755aa4c to
1344171
Compare
build_config/ci/msvc.rb opened an anonymous `MRuby::Build`, and an unnamed build is called 'host' (lib/mruby/build.rb:114). The build tree is keyed by that name (:127), so MRUBY_CONFIG=ci/msvc aimed a full-core build with `MRB_GC_FIXED_ARENA` at build/host, the directory a default build on the same machine uses. The Windows-VC job never sees that, since it builds a fresh checkout, but a developer who points MRUBY_CONFIG at this config on a tree the default config has built shares one directory between two gem sets, which is the shape mruby#7195, mruby#7197, mruby#7199 and mruby#7200 took out of the other configs that had it. 14d6e42 named the bintest build in ci/gcc-clang and left this one alone, on the ground that a single build has no sibling for a name to tell it apart from. That was a reason about telling builds apart; the build directory is decided by the name whether or not there is a sibling, and that is the reason here. Name it after its config, as build_config/mrbc.rb, clang-asan.rb and gctest.rb are. Nothing in the file needs the build to be called 'host'. It is an `MRuby::Build`, and it pulls `mruby-bin-mrbc` in through full-core, so it lends no mrbc to any cross target and creates its own internal one either way (:174). The name reaches three other places: `install_prefix` (:625), the `bin/*.bat` wrappers that `define_installer_if_needed` writes only when `host?` answers true (:461 and :482), and the mrbtest that `rake clean` removes from MRUBY_ROOT/bin (tasks/test.rake:82). The job runs `rake -m test:run:serial` (.github/workflows/build.yml:89), which installs nothing and cleans nothing, so none of the three fires. `enable_bintest` has not required the name 'host' since fd113da, and test/bintest.rb resolves every binary it runs from BUILD_DIR rather than from bin/; the `bintest` build in ci/gcc-clang is this same shape under a name, in the same workflow. There is no MSVC here to run the job with. What can be checked on Linux is that the config still loads and that the tree it names is its own; the job on this change is the run: $ MRUBY_CONFIG=ci/msvc rake -T | grep amalgam rake amalgam # Generate amalgamated mruby.h and mruby.c in .../build/msvc/amalgam
Six configs open an anonymous
MRuby::Build, and an unnamed build is calledhost(lib/mruby/build.rb:94). The build tree is keyed by that name (:107), so each of them aims its objects atbuild/host, on top of whatever a default build has left there, and none of them ever creates a directory of its own:The repo
bin/symlinks point into the result as well, becausehost?builds install them (:452). All of the transcripts below are from today's master, gcc 13.3.0, each starting from one clean default build.The four full-core configs
host-f32shows the shape, and it exits 0 while doing it:The damage outlives the run.
libmruby.ais archived withar rs(lib/mruby/build/command.rb:258), andrreplaces but never removes, so members accumulate across config switches: 99 unique members before thehost-f32run, 107 after, sincefull-core.gemboxcarries gems thatdefault.gemboxdoes not. Building the default config again does not recover the tree. It exits 0 and leaves one that cannot boot at all:The presym tables are regenerated for the smaller gem set while the extra members stay in the archive, so the objects and the tables disagree about which symbol id is which. Recovery is
rm -rf build/hostplus a full rebuild.host-nofloatThis one relinks part of the tree and leaves the rest:
build/host/bin/mrubyis anMRB_NO_FLOATbinary andbin/mrubyis that binary too, while themrbcbeside it is the default build's and goes on compiling a float literal, so the tree is not even a consistentMRB_NO_FLOATbuild.bin/mrbcneed not stay put either:tasks/bin.rake:2installs the internalbuild/host/mrbc/bin/mrbcover it for ahost?build carrying nomruby-bin-mrbcgem of its own, and that one is compiled withMRB_NO_FLOAT. Which of the two the symlink ends up at is decided by which of them rake found out of date, so any measurement taken through this config silently measures a mixed tree.host-sharedWhat this one costs is decided by the timestamps in
build/host, and both answers are wrong. Starting from a good default build, rake compares timestamps rather than compiler flags, finds every object up to date, recompiles nothing, and links the shared library out of the archive the default build left, which is not-fPIC:When the objects are out of date instead, the tree is rebuilt with
-fPICandMRB_DEBUGintobuild/hostand the.sois produced there, and this one never announces itself afterwards. Both configs load the same gembox, so the object set matches, and the default build after it finds the tree up to date, exits 0, changes nothing and hands that foreign tree back. Thelibmruby.soandlibmruby.so.4.0left inbuild/host/liboutlive every later default build, because nothing in the default pipeline knows about them.Naming them
Each build is named after its config file, which is what
build_config/asan.rbandbuild_config/gctest.rbalready do, and what 8b44a52 did forhost-cxx. Nothing outside the configs refers to the directories these produce.Two of the six need more than the rename:
host-nofloatgainsconf.gem :core => 'mruby-bin-mrbc'. The internal mrbc build is created only for ahost?build or one that carries that gem (:153), and none of the gemboxes this config loads supplies it, so the rename on its own aborts inmrbcfile(:364) before compiling anything.build_config/gctest.rbis the same pair for the same reason.host-sharedcarries a post-build pass that adds the shared-library targets, and it picks its target by name. That has to follow the rename, or the config would build and produce no.soat all.The other four need the rename alone:
full-core.gemboxsuppliesmruby-bin-mrbcthrough its glob.Verified
One clean default build, then each config in turn,
rake -j8throughout:host,build/hosthost-f32host-f32,build/host-f32host-gprofhost-gprof,build/host-gprofhost-nofloathost-nofloat,build/host-nofloathost-sharedhost-shared,build/host-sharedhost-m32host-m32,build/host-m32CC=i686-linux-gnu-gcchost-m32-f32host-m32-f32,build/host-m32-f32Afterwards each config has a directory of its own,
build/hostis byte-identical to what the default build left, and its archive holds the same 99 members it did:Each build also holds what it is supposed to:
The two 32-bit configs need a toolchain the machine's own gcc cannot supply, since it carries no multilib libc and
-m32stops at the first compile, onbits/libc-header-start.h. Pointing the gcc toolchain ati686-linux-gnu-gccthrough the environment builds both:Whether the
MRB_NO_FLOATbinary runs is a separate matter and is unchanged here. It fails to boot the same way it did when it was building intobuild/host:Environment
Details
The line each build gives
src/string.c, read offrake --verbosewith-MMD -c, the-Ilist and-odropped. The four configs built here all callenable_debug, which appends-g3 -O0after the gcc toolchain's own-g -O3: