cxx icon indicating copy to clipboard operation
cxx copied to clipboard

"multiple definition of" linker error (Regression since 1.0.188)

Open apartridge opened this issue 1 month ago • 1 comments

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

apartridge avatar Nov 27 '25 14:11 apartridge

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:

  1. The is_local check (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. Location from the repro) that are defined in the given cxx::bridge (and not e.g. aliased and defined elsewhere - defininig an impl for every alias could result in conflicting impls and linking errors).
  2. But a defense in-depth is also an orphan rule which enforces that impl SharedPtrTarget for SomeTypeLikeLocation only 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).

anforowicz avatar Dec 02 '25 17:12 anforowicz