Environment
- nanobrew: v0.1.205
- macOS: 26.5.1
- arch: arm64
- Nanobrew prefix:
/opt/nanobrew/prefix
- Homebrew prefix:
/opt/homebrew
- upgraded installation originally initialized before v0.1.204
Summary
On an existing macOS installation upgraded to v0.1.205, /opt/nb is not created automatically. When a bottle needs whole-file Mach-O relocation, nb install prints a warning but continues successfully using the load-command-only fallback. Compile-time paths in .rodata remain under /opt/homebrew.
If the same formula is installed with Homebrew, the Nanobrew process can then silently load Homebrew modules and libraries. This is a remaining upgrade/coexistence failure after #347.
Reproduction with Perl
Start with Nanobrew v0.1.205 and an existing prefix, but no short-prefix link:
test -e /opt/nb
# exit 1: /opt/nb is absent
brew install perl
nb install perl
Nanobrew warns but reports the package installed:
nb: note: /opt/nb short-prefix symlink unavailable — Mach-O .rodata not relocated; run `sudo nb init` and reinstall affected packages
...
✓ perl
==> Done
The Nanobrew executable and direct libperl dependency are correctly isolated:
/opt/nanobrew/prefix/Cellar/perl/5.42.2/bin/perl
/opt/nanobrew/prefix/Cellar/perl/5.42.2/lib/perl5/5.42/darwin-thread-multi-2level/CORE/libperl.dylib
But its compiled Perl configuration remains Homebrew-prefixed:
env -i HOME="$HOME" PATH=/usr/bin:/bin LC_ALL=C \
/opt/nanobrew/prefix/Cellar/perl/5.42.2/bin/perl \
-MConfig -e 'print "$Config{prefix}\n$INC{\"Config.pm\"}\n", join("\n", @INC), "\n"'
/opt/homebrew/opt/perl
/opt/homebrew/opt/perl/lib/perl5/5.42/darwin-thread-multi-2level/Config.pm
...
/opt/homebrew/opt/perl/lib/perl5/5.42
With DYLD_PRINT_LIBRARIES=1, Nanobrew Perl loaded Brew's XS bundles and dependency library:
/opt/homebrew/Cellar/perl/5.42.2/.../auto/Encode/Encode.bundle
/opt/homebrew/Cellar/perl/5.42.2/.../auto/GDBM_File/GDBM_File.bundle
/opt/homebrew/Cellar/gdbm/1.26/lib/libgdbm.6.dylib
Temporarily hiding Brew's /opt/homebrew/opt/perl and public Perl links made the Nanobrew copy fail:
Can't locate strict.pm in @INC
Can't locate Config.pm in @INC
Restoring the Brew links made it pass again. Brew was therefore masking a broken Nanobrew installation.
Impact
- A same-version Homebrew formula silently supplies Nanobrew runtime components.
- Independent upgrades can create module/ABI mismatches rather than an immediate, diagnosable failure.
- A user without the corresponding Homebrew formula gets a broken Nanobrew package despite
nb install reporting success.
- This affects more than Perl: the current installation contained
/opt/homebrew in 139 Mach-O files across the selected Nanobrew kegs.
Relevant implementation
src/macho/relocate.zig explicitly leaves .rodata untouched when /opt/nb is unavailable and falls back to install_name_tool for load commands only. src/main.zig creates /opt/nb during nb init, but an ordinary upgrade does not rerun privileged initialization.
Expected
An upgraded installation should not successfully install a keg with known-incomplete runtime relocation. Possible acceptable outcomes include:
- bootstrap or explicitly require
/opt/nb as part of the v0.1.204+ upgrade path; or
- fail the affected package installation instead of warning and continuing.
The installed record should not be reported as successful while loadable files retain foreign-prefix runtime paths.
Refs #347.
Environment
/opt/nanobrew/prefix/opt/homebrewSummary
On an existing macOS installation upgraded to v0.1.205,
/opt/nbis not created automatically. When a bottle needs whole-file Mach-O relocation,nb installprints a warning but continues successfully using the load-command-only fallback. Compile-time paths in.rodataremain under/opt/homebrew.If the same formula is installed with Homebrew, the Nanobrew process can then silently load Homebrew modules and libraries. This is a remaining upgrade/coexistence failure after #347.
Reproduction with Perl
Start with Nanobrew v0.1.205 and an existing prefix, but no short-prefix link:
Nanobrew warns but reports the package installed:
The Nanobrew executable and direct
libperldependency are correctly isolated:But its compiled Perl configuration remains Homebrew-prefixed:
With
DYLD_PRINT_LIBRARIES=1, Nanobrew Perl loaded Brew's XS bundles and dependency library:Temporarily hiding Brew's
/opt/homebrew/opt/perland public Perl links made the Nanobrew copy fail:Restoring the Brew links made it pass again. Brew was therefore masking a broken Nanobrew installation.
Impact
nb installreporting success./opt/homebrewin 139 Mach-O files across the selected Nanobrew kegs.Relevant implementation
src/macho/relocate.zigexplicitly leaves.rodatauntouched when/opt/nbis unavailable and falls back toinstall_name_toolfor load commands only.src/main.zigcreates/opt/nbduringnb init, but an ordinary upgrade does not rerun privileged initialization.Expected
An upgraded installation should not successfully install a keg with known-incomplete runtime relocation. Possible acceptable outcomes include:
/opt/nbas part of the v0.1.204+ upgrade path; orThe installed record should not be reported as successful while loadable files retain foreign-prefix runtime paths.
Refs #347.