Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,48 @@ jobs:
shell: bash
run: |
mine='${{ fromJSON(needs.select.outputs.plan)[matrix.platform][format('{0}', matrix.shard)] }}'

# ── A member its toolchain cannot build, and why that lives HERE ──
#
# Members self-gate with `[target.'cfg(...)']` (see the workspace
# comment above), and that has a platform axis and no STANDARD
# LIBRARY axis -- a cfg selector is not a platform. So a member that
# cannot be built under libc++ has nowhere of its own to say so, and
# the leg is the only layer that knows which standard library is in
# play. That is the whole reason this list is in CI and not in a
# descriptor; it is not a convenience.
#
# `mysql-connector-cpp`: the package builds STATIC libraries with
# CMake and the system compiler, so `std::__cxx11::` crosses the
# boundary and a libc++ consumer fails at link:
#
# ld.lld: error: undefined symbol:
# std::__cxx11::basic_string<...>::_M_create(...)
#
# Its install hook cannot adapt, because nothing tells it what the
# consumer chose: MCPP_CXX_STDLIB is exported only when mcpp runs a
# BUILD PROGRAM (`src/build/build_program.cppm`), `make_xlings_env`
# carries `{binary, home, projectDir}` and no toolchain, and a probe
# in the hook measured `MCPP_CXX_STDLIB=nil` on this very leg (#392).
# mcpp-community/mcpp#613; when the hook can see the consumer's stdlib,
# this entry comes out and the descriptor does the work instead.
#
# SKIPPED, NOT MARKED GREEN: the incompatibility is real for users on
# a libc++ toolchain. This stops CI from re-measuring a known answer
# every run; it does not claim the combination works.
if [ "${{ matrix.toolchain }}" = "llvm" ]; then
kept=""
for m in $mine; do
case "$m" in
mysql-connector-cpp)
echo "skipping '$m' on the llvm leg: static libs are built" \
"against the system stdlib; see the comment above" ;;
*) kept="$kept $m" ;;
esac
done
mine="${kept# }"
fi

echo "MEMBERS=$mine" >> "$GITHUB_ENV"
echo "shard ${{ matrix.shard }}/${{ matrix.shards }}: ${mine:-<none>}"

Expand Down Expand Up @@ -1256,7 +1298,9 @@ jobs:
# optimise, and a local harness that differs from CI measures
# something else.
if [ -z "$MEMBERS" ]; then
echo "No workspace member affected by this change — nothing to test."
echo "No workspace member to test here: none affected by this" \
"change, or every member of this shard was skipped on this" \
"leg (the shard step above says which, and why)."
else
MCPP_TIMINGS="$PWD/timings.tsv" bash tests/run_members.sh $MEMBERS
fi
Expand Down
47 changes: 47 additions & 0 deletions pkgs/c/compat.mysql-connector-cpp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,53 @@ function install()
local jobs = (os.default_njob and os.default_njob()) or 4
local clean_env = "env -u CPPFLAGS -u CFLAGS -u CXXFLAGS -u LDFLAGS "
local compiler = ""

-- THE STANDARD LIBRARY THIS IS BUILT AGAINST HAS TO MATCH THE CONSUMER'S.
--
-- CMake picks the system compiler below, so the static libs come out
-- against libstdc++ whatever the consumer uses. On the llvm leg, which
-- links libc++, the member then fails at link with the libstdc++ half of
-- its own dependency undefined:
--
-- ld.lld: error: undefined symbol: std::_Rb_tree_increment(...)
-- ld.lld: error: undefined symbol:
-- std::__cxx11::basic_string<...>::_M_create(...)
--
-- AND THIS HOOK CANNOT KNOW WHAT THE CONSUMER'S IS. That was asked as a
-- question and has now been answered; the answer is no, at three levels:
--
-- 1. MEASURED. The probe below logged `MCPP_CXX_STDLIB=nil` on the llvm
-- leg (mcpplibs/mcpp-index#392, `workspace (linux llvm 0/4)`), and
-- the link failed exactly as before.
-- 2. THE ONLY SETTER is `src/build/build_program.cppm` (`e.emplace_back
-- ("MCPP_CXX_STDLIB", env.cxxStdlib)`) -- mcpp exports it when it runs
-- a BUILD PROGRAM. An xlings install hook is not that.
-- 3. THE CALL CARRIES NOTHING ELSE either: `make_xlings_env` builds an
-- `xlings::Env` of `{binary, home, projectDir}`, and
-- `install_packages` is invoked with `XLINGS_HOME` and PATH. No
-- toolchain, no compiler, no stdlib crosses that boundary.
--
-- So neither route is reachable from HERE. `llamacpp` refuses a libc++
-- toolchain by name with `mcpp::cxx_stdlib()`, but that lives in its
-- build program, in its own repo; an inline descriptor has no such place,
-- and `[target.'cfg(...)']` self-gating has a platform axis and no
-- standard-library axis (a cfg selector is not a platform).
--
-- WHAT IS TRUE ABOUT THIS PACKAGE, stated plainly so a user reads it
-- before the linker says it: these are STATIC libraries built by CMake
-- with the system compiler, so `std::__cxx11::` and friends cross the
-- boundary into the consumer. Consuming them from a libc++ toolchain does
-- not work and cannot be made to work from inside this hook. Tracked as
-- mcpp-community/mcpp#613 (install hooks need the consumer's stdlib);
-- until then
-- `validate.yml` keeps this member off the llvm leg, with the same reason
-- written there.
--
-- The probe stays. It costs one log line, it is the evidence for point 1,
-- and the day mcpp does pass the variable through, this line reports it
-- and the fix becomes a three-line change directly below.
hook_log("MCPP_CXX_STDLIB=" .. tostring(os.getenv("MCPP_CXX_STDLIB"))
.. " (expected nil; see the comment above)")
if os.host() == "macosx" then
-- Connector 在 project() 前启动 bootstrap CMake;必须通过环境变量
-- 将最低系统版本同步给 bootstrap 及其后续的内置依赖构建。
Expand Down
Loading