de-bespoke build - #519
Conversation
0ec8de8 to
c7bb4f2
Compare
I see the benefits of some simplification, and improved organization. I neither love nor hate the submodule approach. I think a full walk-thru would help and being clear on some key workflows. one nagging problem that is handled to some extent in the current model (not perfect) is pr validation against the dependency profile, including our submodules, that exist in main. the other workflow difficulty is the case where you have changes in moqx that depend some unmerged work in moxygen . oh also note now openmoq/moxygen maintains artifacts for snapshot-latest and full tagged releases only... we may want to reexamine that approach too. |
| # on the next reconfigure of an existing build dir. A cached pin would silently | ||
| # shadow the file's value. | ||
| set(MOXYGEN_REPOSITORY "openmoq/moxygen") | ||
| set(MOXYGEN_REV "a1c42e1a0e0305484eb6cbcfd8c228a4685cade1") |
There was a problem hiding this comment.
I would point to this as one of the motivating fixes.
This is now just a plain text file. Rebase, merging, diffing now works as with any ordinary file.
Conceptually, submodules work as this simple pointer, but them being special makes them more difficult to work with. Because
- Commands don't recurse by default.
- The submodule state lives in multiple-places that can desync (.gitmodules, .git/config, and the actual working tree)
- Different tools shows different diffs.
c7bb4f2 to
dfbba72
Compare
|
I think the PR CI workflow should stay mostly unchanged, except, I always use the oxygen version specified in the source, never fallback on latest. If not prebuilt is found, the fallback is to build from source, not to use latest. In the spirit of CI should be reproducible I think falling back to latest snapshot is just wrong, you are building different code then what's specified in the source code. The main problem is "drift between moxygen merges and moqx's daily moxygen-sync.". But the solution for this is keeping more prebuilts in the moxygen repo, not building with possibly broken version of moxygen. |
c3418da to
551f2b8
Compare
The pin is the one thing every other piece reads: the prebuilt fetcher, the superbuild, and the moqx build all resolve moxygen from it. MOXYGEN_REV starts where deps/moxygen points, not at whatever the branch was cut from.
Inert until CMakeLists.txt includes it. The rev-to-release resolution and its consistency checks are documented in the file header.
- The from-source alternative to the prebuilt, for revs and platforms with no published tarball and for instrumented sanitizer builds. - moqx itself is not built here; only the origin of the moxygen prefix differs between the two modes. - Inert until scripts/configure.sh --moxygen from-source drives it.
- Pins live in cmake/dependencies.cmake. - moxygen is consumed as an installed CMake package: the published prebuilt or a superbuild prefix. - binaryDir is build/<presetName> so profiles coexist. - No .a preference in CMAKE_FIND_LIBRARY_SUFFIXES. folly-targets.cmake hardcodes libglog.so, so an .a-preferring Glog resolution loads both copies and glog's double flag registration crashes under ASan. - GFLAGS_SHARED=ON retires the tests' whole-archive workaround, which only existed to force flag registration out of the static gflags. - The module path and the policy floor are build-level requirements, not per-preset choices: a bare `cmake -S .` needs them too. - compile_commands.json is exported because lint needs it and Ninja does not write it unasked. - A missing system -dev package surfaced deep inside the folly stack rather than as the install-system-deps.sh hint.
Only the build lifecycle scripts, install-system-deps.sh and moqx-run.sh are daily entry points. The rest move next to their audience, and every caller moves with them.
- With CPM the build dir's CMakeCache is the only state, so the setup-deps dispatcher and its marker files go. - --moxygen is explicit: a default would silently pick between an hours-long stack build and an uninstrumented prebuilt. - prebuilt-with-fallback is the entry point. It probes the fetcher directly rather than reading a failed moqx configure as "no prebuilt". - A sanitizer preset refuses any moxygen not instrumented to match. ASan deps under a TSan moqx link two clashing runtimes. - The variables --moxygen and --moxygen-dir own are refused as -D arguments; last-wins would defeat the interlock above. - Job count is -j, then MOQX_BUILD_JOBS, then a RAM-derated default for sanitizer profiles; an explicit value is never clamped (distcc).
- Dependency caches are content-keyed on the pins and restored by prefix: a bump would otherwise cold-download the full set in every concurrent job. - Every build path installs system libraries through install-system-deps.sh. - version-release resolves the release from MOXYGEN_REV, not moxygen's newest tag, which would strand the release as a draft. - The release job stops compiling tests: MOQX_BUILD_TESTS defaults ON, so it built every test executable and never ran ctest. - The releases API is read with a token; anonymous is 60/hour/IP, shared across runner egress.
- The build context no longer carries deps/, so .dockerignore drops the submodule excludes with it. - The moxygen stage is keyed on the pin rather than on src/, so a source-only push reuses the prefix. - It falls back to the superbuild when the pin publishes no prebuilt, the same ladder the build lanes use. - One prefix feeds both targets, so relay and interop-client cannot carry different moxygen builds.
The PR and main lanes build moqx's own TUs under ASan against uninstrumented prebuilt deps. A real ASan/TSan run needs the whole stack instrumented, which only the from-source superbuild produces, so it runs nightly rather than per push.
MOQBIN follows whatever moxygen the build resolved. ctest passes it per test, and scripts outside ctest source the moqx-tools.env the configure writes.
deps/moxygen is going away. The source comes from --moxygen-dir, then CPM_moxygen_SOURCE, then what the build already fetched, then a clone of the pinned rev.
Dead weight once CPM supplies both.
deps/moxygen/LICENSE is gone with the submodule; the fork's copy is the durable target. sync-relay.sh emits the same text it writes into the ported files, so the next sync is a no-op.
- The superbuild and the moqx build share the CPM clones, so a from-source moqx compiles against the exact source its moxygen prefix was built from, and a raw `cmake --preset` build reuses them instead of re-fetching into its own _deps. - The extracted prebuilt installs hang off the same root, so MOQX_DEPS_CACHE moves everything at once on a host with a small home partition.
- CI runs scripts/dev/format.sh; lint.sh is a manual entry point. - The targets' tools/*.cc globs never matched anything.
The static libs are not consumable without installed headers or an install(EXPORT), and they bloat the release tarballs.
- Nothing built or registered changes. - The load test stays unregistered: it needs a live relay. - The shell-test blocks stay explicit: their properties vary.
folly's static_assert on syscall addresses (NetOps.cpp) is not constant under -fsanitize=function, which `,undefined` pulls in. ASan's ABI still matches across the boundary, so moqx keeps both. One SanitizerFlags.cmake now holds the sets the moqx build and the superbuild share.
Only the env spelling was validated. -DBOOST_USE_STATIC_LIBS=auto, which superbuild/README.md advertises as the knob, passed straight through to Boost_USE_STATIC_LIBS where CMake reads it as truthy — forcing static Boost on the distros that package none, the exact failure the probe exists to avoid.
An INTERFACE target linked PRIVATE, so the warning set reaches moqx's own translation units — src/, test/ and benchmark/ — and propagates to no consumer. -Wmissing-field-initializers is off: GCC fires it on C++20 designated initializers that omit members carrying default member initializers, the idiom throughout the tree and correct. Clang does not warn there.
Most of compile_commands.json is CPM-fetched dependency code. Making .clang-tidy load surfaces thousands of warnings in it; that is #518.
Two equal dependency modes, the pin table, and the scripts that drive them.
- README drops the submodule bootstrap and `build.sh setup` for the trilogy. - ci-architecture documents the shared ~/.cache/moqx cache and how it is keyed. - release replaces the `.moxygen-release` tag file with the MOXYGEN_REV pin, so a release/* branch must freeze on a v*-tagged rev. - Repo paths are linked from the root so they resolve wherever they are rendered.
GitHub deprecated the Node 20 runtime: node20 actions still run, but on Node 24, and warn on every job. Each action goes to its lowest major that declares runs.using: node24, not to latest — the jumps are runtime-only, so this stays a version bump rather than a behaviour change. Two majors carry breaking notes that do not apply here: create-github-app-token v3 drops custom proxy handling (no HTTP(S)_PROXY anywhere in .github/), and setup-buildx-action v4 removes deprecated inputs (it is used with none). upload-pages-artifact is composite and has no runtime of its own; v5 is the first to pin a node24 upload-artifact internally. All of these need Actions Runner >= 2.327.1. The self-hosted linode runner reports 2.336.0.
clangd's default database search walks a source file's ancestors and a literal build/ under each; it never descends into a named build/<profile>/. Every translation unit therefore got an empty compilation database, with no error surfaced anywhere — only `clangd --check` showed the cascade of unresolved standard headers. Symlinking from configure.sh and not build.sh makes "last configured profile wins" fall out for free: build.sh runs on every incremental compile and would flap the link for reasons unrelated to which profile you work against.
|
Anecdote: I was doing all new work based of this branch to properly test/dog-feed. I rebased onto remote/main, did A clean build and it immediately failed. Claude's output, no context, clean session just to rebase mh/multi-auth-token from this branch onto main.
|
551f2b8 to
1bf7d0c
Compare
Very much a draft that needs more passes.
Goal
Make the repo easier to understand and work with for newcomers.
and extension points are predictable.
submodule.recurse=true. Still a pain.submodules.
the source along. Optional submodule checkout is worse.
Breaking changes
This change is