"multiple definition of" linker error (Regression since 1.0.188)
I have a project where we expose some Rust code to C++ code via a staticlib, using cxx.
Today I tested out updating to the newest version, 1.0.189 and I get the following error. (On 1.0.188 it works fine.)
We have a backend_server_staticlib project that depends on a backend_server project, and exposes a staticlib crate-type, and a few extern "C" functions that are invoked from our C++ code base.
[package]
name = "backend_server_staticlib"
version = "0.1.0"
edition = "2024"
[dependencies.backend_server]
path = "../../backend-server"
[lib]
crate-type = ["staticlib"]
I understand it may be hard to go just based on this error, but since it is a error that happens only since the last release, maybe someone has an idea how to fix it. Otherwise I must try to make a standalone reproducer, but that will require some time.
[build] /usr/bin/ld: backend_cpp_bridge/libbackend_server_staticlib.a(a8ac3b080008f8da-cpp_bridge.rs.o): in function `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$null':
[build] cpp_bridge.rs.cc:(.text.cxxbridge1$shared_ptr$backend_cpp_bridge$Location$null+0x0): multiple definition of `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$null'; backend_cpp_bridge/libbackend_cpp_bridge_generated.a(generated_from_rust.cpp.o):generated_from_rust.cpp:(.text+0x2538): first defined here
[build] /usr/bin/ld: backend_cpp_bridge/libbackend_server_staticlib.a(a8ac3b080008f8da-cpp_bridge.rs.o): in function `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$uninit':
[build] cpp_bridge.rs.cc:(.text.cxxbridge1$shared_ptr$backend_cpp_bridge$Location$uninit+0x0): multiple definition of `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$uninit'; backend_cpp_bridge/libbackend_cpp_bridge_generated.a(generated_from_rust.cpp.o):generated_from_rust.cpp:(.text+0x2578): first defined here
[build] /usr/bin/ld: backend_cpp_bridge/libbackend_server_staticlib.a(a8ac3b080008f8da-cpp_bridge.rs.o): in function `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$raw':
[build] cpp_bridge.rs.cc:(.text.cxxbridge1$shared_ptr$backend_cpp_bridge$Location$raw+0x0): multiple definition of `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$raw'; backend_cpp_bridge/libbackend_cpp_bridge_generated.a(generated_from_rust.cpp.o):generated_from_rust.cpp:(.text+0x2618): first defined here
[build] /usr/bin/ld: backend_cpp_bridge/libbackend_server_staticlib.a(a8ac3b080008f8da-cpp_bridge.rs.o): in function `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$clone':
[build] cpp_bridge.rs.cc:(.text.cxxbridge1$shared_ptr$backend_cpp_bridge$Location$clone+0x0): multiple definition of `cxxbridge1$shared_ptr$backend_cpp_bridge$Location$clone'; backend_cpp_bridge/libbackend_cpp_bridge_generated.a(generated_from_rust.cpp.o):generated_from_rust.cpp:(.text+0x2678): first defined here
.... cut off
Looking at https://github.com/dtolnay/cxx/compare/1.0.188...1.0.189, it seems to me that the error above may be somehow related to https://github.com/dtolnay/cxx/commit/e197216329dd49930eff8c24b509885307f07b48
FWIW cxx assumes that it only generates a particular impl/generic-monomorphization/template-instantiation once (e.g. an impl of std::shared_ptr<backend_cpp_bridge::Location>), because of:
- The
is_localcheck (from the commit linked above, but also present before that commit, just in a slightly different but I think equivalent form) which ensures that impls are only generated for types (e.g.Locationfrom the repro) that are defined in the givencxx::bridge(and not e.g. aliased and defined elsewhere - defininig an impl for every alias could result in conflicting impls and linking errors). - But a defense in-depth is also an orphan rule which enforces that
impl SharedPtrTarget for SomeTypeLikeLocationonly references crate-local types. See also https://docs.rs/cxx/latest/cxx/memory/trait.SharedPtrTarget.html and https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
So I am not really sure what happened. And because https://github.com/dtolnay/cxx/pull/1658 was quite big, I would prefer to fix this forward (rather than reverting some of the changes from 1.0.189).
try to make a standalone reproducer, but that will require some time
Could you try that please? That would help to diagnose and fix this issue (and may also potentially help with adding regression tests).