Undefined C++ references during link step when statically linking

I'm using bindgen to generate bindings to a statically-linked library (PROJ) that I'm building myself as part of build.rs. This works fine on macOS (Clang 11.0.1 on Travis), but the link step fails on Linux (Xenial, using clang 7.0 on Travis); I use cmake to configure the libproj build:

// Build PROJ from the included tar
let path = "PROJSRC/proj-7.0.1.tar.gz";
let tar_gz = File::open(path).expect("Couldn't open PROJ source tar");
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);
archive.unpack("PROJSRC/proj").expect("Couldn't unpack tar");
let target = env::var("TARGET").unwrap();
let mut config = cmake::Config::new("PROJSRC/proj/proj-7.0.1");

config.pic(true);
config.define("BUILD_SHARED_LIBS", "OFF");
config.define("BUILD_TESTING", "OFF");
config.define("CMAKE_BUILD_TYPE", "Release");

// Find and configure required dependencies
println!("cargo:rustc-link-lib=dylib=sqlite3");
println!("cargo:rustc-link-lib=dylib=curl");
println!("cargo:rustc-link-lib=dylib=tiff");
if target.contains("apple") {
    println!("cargo:rustc-link-lib=dylib=c++");
} else if target.contains("linux") {
    println!("cargo:rustc-link-lib=dylib=stdc++");
}
let proj = config.build();

Then configure bindgen:

println!(
    "cargo:rustc-link-search=native={}",
    proj.join("lib").display()
);
// Tell cargo to tell rustc to link PROJ
println!("cargo:rustc-link-lib=static=proj");

let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindgen::builder()
    .header(proj.join("include").join("proj.h").to_str().unwrap())
    .clang_arg("-x")
    .clang_arg("c++")
    .clang_arg("-std=c++11")
    .trust_clang_mangling(false)
    .blacklist_type("max_align_t")
    .generate()
    .expect("Unable to generate bindings")
    .write_to_file(out_path.join("bindings.rs"))
    .expect("Couldn't write bindings!");

The error occurs here:

Running rustc --crate-name proj_sys --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C debuginfo=2 --cfg 'feature="bundled_proj"' -C metadata=fa366d7f794cc977 -C extra-filename=-fa366d7f794cc977 --out-dir /home/travis/build/georust/proj-sys/target/debug/deps -C incremental=/home/travis/build/georust/proj-sys/target/debug/incremental -L dependency=/home/travis/build/georust/proj-sys/target/debug/deps -L native=/home/travis/build/georust/proj-sys/target/debug/build/proj-sys-7a5c19f0a85b0f5f/out/lib -l dylib=stdc++ -l dylib=sqlite3 -l dylib=curl -l dylib=tiff -l static=proj

Full cc invocation

"cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.177t2rap6u4od0iv.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.1g2eqh50x9u2ncg.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.1qqu12ejfhhntd85.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.2c58aij4xyps0lnj.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.2npi0qq2az2k1md2.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.36zb3w2n69jpowtu.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.4ji07alb1q4d8t6b.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.4u4ie7n56b1if9w4.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.7ojf8pzaav9f0rh.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.pj3jh26qoxnhzzk.rcgu.o" "-o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-265aaa79a6b13f2a.h1ciig43xzml1c9.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "/home/travis/build/georust/proj-sys/target/debug/deps" "-L" "/home/travis/build/georust/proj-sys/target/debug/build/proj-sys-7a5c19f0a85b0f5f/out/lib" "-L" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-lstdc++" "-lsqlite3" "-lcurl" "-ltiff" "-Wl,-Bstatic" "-Wl,--whole-archive" "-lproj" "-Wl,--no-whole-archive" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-c4aa6514e6be1a7c.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libterm-6255fdc1b09c0456.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgetopts-d446f4782431d67a.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode_width-ac169ce18f53c620.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_std-a3711a5e6b85a778.rlib" "-Wl,--start-group" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-3859b7e52a41a8fd.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-b6f63fdced5391b3.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-f1162cb368d8a940.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-3a410b3342175ea9.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-8465780e2e7f26a2.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-dc606003556dfe9c.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-9b57db8474cf9a25.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-eb5c673507e106bb.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-6bfbf42e528a9aa0.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-bd6281bbe193935c.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-1ca9bb8ed5fdbc90.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-d0d38ef150f70011.rlib" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-0d0018c00d4fd6be.rlib" "-Wl,--end-group" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-2541f1e09df1c67d.rlib" "-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"

And gives me 1000s of errors, beginning with

= note: /home/travis/build/georust/proj-sys/target/debug/build/proj-sys-7a5c19f0a85b0f5f/out/lib/libproj.a(networkfilemanager.cpp.o): In function osgeo::proj::DiskChunkCache::open(projCtx_t*)': networkfilemanager.cpp:(.text._ZN5osgeo4proj14DiskChunkCache4openEP9projCtx_t+0x42): undefined reference to operator new(unsigned long).

I don't do much work with C++ or cross-library linking, so I'm not sure why it's failing – it looks as if there's a library invocation to stdc++ missing, or it's to an incorrect version? PROJ is built with C++11 features, but I don't understand why the existing configuration would then work on macOS, but fail on Linux.

The solution is to set CXXFLAGS=-std=c++11 either globally, or using your build system (e.g. CMake). If you fail to do this, your compiler may default to an earlier C++ standard library.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.