Skip to content

Commit d66db33

Browse files
committed
fix(mysql-connector-cpp): match the consumer's standard library, or say why not
CMake picks the system compiler here, so the static libs come out against libstdc++ whatever the consumer uses. On the llvm leg, which links libc++, the member 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(...) `llamacpp` refuses a libc++ toolchain by name with `mcpp::cxx_stdlib()`, and I said twice that the same lever was out of reach here because that is a build-program API and this is an inline descriptor. That was half right. The API is out of reach; the VARIABLE it reads is not necessarily — MCPP_CXX_STDLIB is exported when mcpp runs a build program (src/build/build_program.cppm), and whether it also reaches an xlings install hook is documented nowhere. So this asks instead of assuming, and records the answer either way: * visible and `libc++` — build with `-stdlib=libc++`, on the compile and both link flag sets. Compiling against libc++ headers while linking libstdc++ produces the same undefined symbols one layer later, so the flag has to reach all three. * absent — nothing changes. The build is what it was, and the hook log carries `MCPP_CXX_STDLIB=nil`, which is the missing half of the diagnosis the next time that leg fails. The failure has been read wrong once already in this area: `install() result=nil` was taken for a cause when it was a successful install with no return statement. A hook that reports what it saw is cheaper than a third round of inference.
1 parent 9ea3271 commit d66db33

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

pkgs/c/compat.mysql-connector-cpp.lua

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,41 @@ function install()
264264
local jobs = (os.default_njob and os.default_njob()) or 4
265265
local clean_env = "env -u CPPFLAGS -u CFLAGS -u CXXFLAGS -u LDFLAGS "
266266
local compiler = ""
267+
268+
-- THE STANDARD LIBRARY THIS IS BUILT AGAINST HAS TO MATCH THE CONSUMER'S.
269+
--
270+
-- CMake picks the system compiler below, so the static libs come out
271+
-- against libstdc++ whatever the consumer uses. On the llvm leg, which
272+
-- links libc++, the member then fails at link with the libstdc++ half of
273+
-- its own dependency undefined:
274+
--
275+
-- ld.lld: error: undefined symbol: std::_Rb_tree_increment(...)
276+
-- ld.lld: error: undefined symbol:
277+
-- std::__cxx11::basic_string<...>::_M_create(...)
278+
--
279+
-- `llamacpp` refuses a libc++ toolchain by name with
280+
-- `mcpp::cxx_stdlib()`, but that is a build-program API and this is an
281+
-- inline descriptor with no build program. What an install hook CAN do is
282+
-- read the variable that API reads. mcpp exports MCPP_CXX_STDLIB when it
283+
-- runs a build program (src/build/build_program.cppm); whether it reaches
284+
-- an xlings install hook is not documented either way, so this asks
285+
-- rather than assumes, and RECORDS the answer either way.
286+
--
287+
-- Absent, nothing changes: the build is what it was, and the hook log says
288+
-- the variable was not visible -- which is the missing half of the
289+
-- diagnosis if the llvm leg fails again.
290+
local want_stdlib = os.getenv("MCPP_CXX_STDLIB")
291+
hook_log("MCPP_CXX_STDLIB=" .. tostring(want_stdlib))
292+
if want_stdlib == "libc++" and os.host() == "linux" then
293+
-- -stdlib reaches the compile AND the link, which is what a mixed
294+
-- build gets wrong: compiling against libc++ headers and linking
295+
-- libstdc++ produces the same undefined symbols one layer later.
296+
compiler = compiler
297+
.. "-DCMAKE_CXX_FLAGS=-stdlib=libc++ "
298+
.. "-DCMAKE_EXE_LINKER_FLAGS=-stdlib=libc++ "
299+
.. "-DCMAKE_SHARED_LINKER_FLAGS=-stdlib=libc++ "
300+
hook_log("building against libc++ to match the consumer")
301+
end
267302
if os.host() == "macosx" then
268303
-- Connector 在 project() 前启动 bootstrap CMake;必须通过环境变量
269304
-- 将最低系统版本同步给 bootstrap 及其后续的内置依赖构建。

0 commit comments

Comments
 (0)