…and why every build must be verbose.
I thought this little story is not only funny but also educational, so here we go. It is not a secret that updates tend to break stuff, and untested updates more so. A typical scenario on legacy systems is that a port starts requiring a newer SDK, and the build fails. Often that gets reflected on “details” page of a given port, where red marks show failing build jobs.
So few days ago MacPorts updates `librime` port. Details now show that it fails on all systems < 10.15:
I try to build ports which get updated to ensure they still build and pick ports which I did not try building earlier in PPCPorts. For this one I know all dependencies built fine and none one them were recently updated. So I try to build `librime` – and the build fails already at configure. First issue is straightforward – Boost is not accepted, and configure explicitly requires 1.77 minimum, while MacPorts (and PPCPorts) default to 1.76 is not specified otherwise.
Nothing about legacy macOS, the same error is on every macOS on buildbots (example). However, turns out, Boost is an optional dependency, so it just gets disabled by configure.
What breaks configure is that it cannot find `Marisa`, which is a required dependency. I start trying to figure out why CMake cannot find it, when here it is, installed in the same version which MacPorts uses. Sometimes such errors are misleading, because CMake may run some test command, which passes a wrong flag or uses incompatible C++ standard, etc., and “dependency is not found” because that compile command fails, not because there is anything wrong with that dependency. I check CMake logs, CMakeLists and included Find* modules, nothing suspicious.
So I look if there is anything weird about my installation of `marisa-trie` (I used PPCPorts’ port, since MacPorts did not set correct C++ standard and build failed) and I broken it earlier with my fix. `port contents` shows there is no library installed, only headers, configs and binaries. That is not necessarily wrong on its own, since that’s how header-only libraries install, for example, and I did not know if `Marisa` is header-only at that point. But since CMake configure failed when looking for the library, I thought that library did not get built for some reason on PowerPC, and I failed to notice that. Fine, but then MacPorts also does not install any library:
So I look into the log of `librime` configure from buildbot on one of modern systems where the build succeeds. Turns out, it completely ignores `marisa-trie` port (which it should use), but instead picks marisa library from macOS SDK (which apparently was added in Catalina for god knows what reason):
Now it is clear how `librime` update could pass CI, despite the whole port being essentially broken. What is not clear is why MacPorts’ marisa is not used. I build `marisa-trie` from source to see what’s going on – lo and behold, the library is built, but for some reason is not being installed (same pattern on all modern macOS, example).
Since I rebuilt marisa-trie, the base ran a check for broken ports, and now my `opencc` is shown as broken, because it cannot find `libmarisa`. Sure enough, it can’t, since it is not installed.
Checking pre-built `opencc` from packages.macports.org shows it is also linked to `libmarisa.dylib`:
`libmarisa.dylib` does not exist anymore, so `opencc` port is broken for all systems now. The update of `marisa-trie` which was made in MacPorts without checking anything whatsoever took place a month ago.
Now it is needed to a) fix `marisa-trie` installation, so that the library is actually installed, b) rebuild `opencc` against fixed marisa, c) once these dependencies are fixed, build `librime`, which was what I started with.
Second step fails with a C++ standard-related error: turns out, new `marisa-trie` headers require at least C++17. Passing `-std=c++17` to opencc build still fails. Turned out, that is “broken by design”, since [original] CMakeLists of opencc hardcode C++14. Patching that out fixes the build of opencc.
`librime` itself configures and installs normally once dependencies are sorted out. Notice, that Port health creates a totally misleading impression that `librime` update fails on older systems, and an attempt to `port install librime` (without -v flag) will probably just confirm that impression. In reality the port is broken on all systems, and the build incidentally succeeds on 10.15+ due to opportunistic usage of a wrong dependency, but there no issue with it actually specific for legacy macOS.
I thought this little story is not only funny but also educational, so here we go. It is not a secret that updates tend to break stuff, and untested updates more so. A typical scenario on legacy systems is that a port starts requiring a newer SDK, and the build fails. Often that gets reflected on “details” page of a given port, where red marks show failing build jobs.
So few days ago MacPorts updates `librime` port. Details now show that it fails on all systems < 10.15:
I try to build ports which get updated to ensure they still build and pick ports which I did not try building earlier in PPCPorts. For this one I know all dependencies built fine and none one them were recently updated. So I try to build `librime` – and the build fails already at configure. First issue is straightforward – Boost is not accepted, and configure explicitly requires 1.77 minimum, while MacPorts (and PPCPorts) default to 1.76 is not specified otherwise.
Code:
-- Could NOT find Boost: Found unsuitable version "1.76.0", but required is at least "1.77.0" (found /opt/local/libexec/boost/1.76/include, )
What breaks configure is that it cannot find `Marisa`, which is a required dependency. I start trying to figure out why CMake cannot find it, when here it is, installed in the same version which MacPorts uses. Sometimes such errors are misleading, because CMake may run some test command, which passes a wrong flag or uses incompatible C++ standard, etc., and “dependency is not found” because that compile command fails, not because there is anything wrong with that dependency. I check CMake logs, CMakeLists and included Find* modules, nothing suspicious.
So I look if there is anything weird about my installation of `marisa-trie` (I used PPCPorts’ port, since MacPorts did not set correct C++ standard and build failed) and I broken it earlier with my fix. `port contents` shows there is no library installed, only headers, configs and binaries. That is not necessarily wrong on its own, since that’s how header-only libraries install, for example, and I did not know if `Marisa` is header-only at that point. But since CMake configure failed when looking for the library, I thought that library did not get built for some reason on PowerPC, and I failed to notice that. Fine, but then MacPorts also does not install any library:
So I look into the log of `librime` configure from buildbot on one of modern systems where the build succeeds. Turns out, it completely ignores `marisa-trie` port (which it should use), but instead picks marisa library from macOS SDK (which apparently was added in Catalina for god knows what reason):
Code:
-- Found marisa: /Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk/usr/lib/libmarisa.tbd
Since I rebuilt marisa-trie, the base ran a check for broken ports, and now my `opencc` is shown as broken, because it cannot find `libmarisa`. Sure enough, it can’t, since it is not installed.
Checking pre-built `opencc` from packages.macports.org shows it is also linked to `libmarisa.dylib`:
Code:
% otool -L /Users/svacchanda/Downloads/opencc-1.1.9_0.darwin_24.x86_64/opt/local/lib/libopencc.1.1.9.dylib
/Users/svacchanda/Downloads/opencc-1.1.9_0.darwin_24.x86_64/opt/local/lib/libopencc.1.1.9.dylib:
/opt/local/lib/libopencc.1.1.dylib (compatibility version 1.1.0, current version 1.1.9)
/opt/local/lib/libmarisa.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1800.101.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)
Now it is needed to a) fix `marisa-trie` installation, so that the library is actually installed, b) rebuild `opencc` against fixed marisa, c) once these dependencies are fixed, build `librime`, which was what I started with.
Second step fails with a C++ standard-related error: turns out, new `marisa-trie` headers require at least C++17. Passing `-std=c++17` to opencc build still fails. Turned out, that is “broken by design”, since [original] CMakeLists of opencc hardcode C++14. Patching that out fixes the build of opencc.
`librime` itself configures and installs normally once dependencies are sorted out. Notice, that Port health creates a totally misleading impression that `librime` update fails on older systems, and an attempt to `port install librime` (without -v flag) will probably just confirm that impression. In reality the port is broken on all systems, and the build incidentally succeeds on 10.15+ due to opportunistic usage of a wrong dependency, but there no issue with it actually specific for legacy macOS.