dtolnay / cxx

Safe interop between Rust and C++
https://cxx.rs
Apache License 2.0
5.88k stars 332 forks source link

Struggling with error LNK2019: unresolved external symbol cxxbridge on Windows environment #1208

Open raycoe opened 1 year ago

raycoe commented 1 year ago

Hello @dtolnay,

I'm struggling with this linking problem for days.

To explain a bit the context, I have to use a no-access-to-source cross platform dynamic library we are using for years in C++11. In order to achieve this, I created a simple wrapper class in C++ that aims to be the interop (C++ side) between Rust code and this shared lib.

The code is intended to run on MacOS, Linux and Windows. On MacOS and Linux, I have no issue, all the unit-tests are perfectly running; it is only on Windows that I'm facing unresolved external symbol issues for all exposed methods.

On Windows:

$ cargo build
   Compiling cc v1.0.79
   Compiling proc-macro2 v1.0.56
   Compiling quote v1.0.26
   Compiling unicode-ident v1.0.8
   Compiling winapi v0.3.9
   Compiling syn v2.0.15
   Compiling winapi-util v0.1.5
   Compiling link-cplusplus v1.0.8
   Compiling scratch v1.0.5
   Compiling termcolor v1.2.0
   Compiling unicode-width v0.1.10
   Compiling cxxbridge-flags v1.0.94
   Compiling cxx v1.0.94
   Compiling codespan-reporting v0.11.1
   Compiling once_cell v1.17.1
   Compiling cxx-build v1.0.94
   Compiling cxxbridge-macro v1.0.94
   Compiling libzos_cppbinding v1.0.0 (Z:\\AS_Shared\cpp_bindings\LibZos\cpp_bindings\LibZos)
    Finished dev [unoptimized + debuginfo] target(s) in 28.52s

When launching unit-tests:

$ cargo test
"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "/NOLOGO" 
 "c:\\Temp\\rustcHdmQXx\\symbols.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.13o4b0qxbnzos09g.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.13twwxo88tqxibaa.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.1gu9dnrrnv0gk443.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.1pmzl8rgj6stk5in.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.1wtaehwu27fjz5ol.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.1yc9qijxqxz8ja8o.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.25xxxxbegkxlpjzi.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.2jers72ak0jpgikn.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.2lrxbvaiww2te4z4.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.2ofm7clriclagpbu.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.2r0q647sftpuk8bp.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.2tnz8hipkxmf13wb.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.2z58jqwukjg4c6h4.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.3264nyes3qiym086.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.37ff0hrhe42aerhh.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.3hbh5ksb1qssbjva.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.3l8gobvn97l39yf9.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.40yd688gse8o66k9.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.4c5blketfcpsb7e0.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.4f9clwp3n4twmcuz.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.4j58ikzqow6d43w8.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.4licrtfdqd2unfig.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.4x1xh4tpqlpnkavs.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.51tof5torfeth7ok.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.5cqjrfi1lrlp7gvh.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.5gtqx6t1ipx30mf9.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.5hahzpqh625oen2.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.6zwnbifmtnxznx2.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.cv2f6cfqtcocfgm.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.odr5hrxg6l4rlrc.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.tko1amf1xrmt14u.rcgu.o"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.ib2h1pkm1qw1g49.rcgu.o"
 "/LIBPATH:Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps"
 "/LIBPATH:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\atlmfc\\lib\\amd64"
 "/LIBPATH:Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\build\\libzos_cppbinding-13704696392cb4db\\out"
 "/LIBPATH:Z:\\AS_Shared\\cpp_bindings\\LibZos\\cpp\\LibZos_cppWrapper\\LibZos\\lib\\Win64"
 "/LIBPATH:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\atlmfc\\lib\\amd64"
 "/LIBPATH:Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\build\\cxx-6f5dcf278ce17e88\\out"
 "/LIBPATH:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\atlmfc\\lib\\amd64"
 "/LIBPATH:Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\build\\link-cplusplus-83643f81420c133b\\out"
 "/LIBPATH:C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib"
 "/WHOLEARCHIVE:LibZos_Handler.lib"
 "libzos.lib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libtest-6c2a016a62f03e3c.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libgetopts-48bb9938631f3ce1.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunicode_width-1a77658c715c0e3a.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_std-a01563643cc25a04.rlib"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libcxx-b6c7b9a05a173074.rlib"
 "Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\liblink_cplusplus-2815780cc5593eb4.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-9f65829977a28b3f.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-0e317596d7fb62b4.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-ab973503635148e8.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_detect-60b7aa0a2358b614.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-cd6aa41f43f53ce3.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libminiz_oxide-88a4232a8779d8ac.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libadler-a9f9f52ac1a95cb8.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-29f32b95b7504de2.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-9830e462dc6b4b78.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-44ab97457d9c0d23.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-71dfac72fe747b71.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-c459514f814b56b6.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-77d9806000248920.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-9380feaa1ae51240.rlib"
 "C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-a0d563049c58a24e.rlib"
 "kernel32.lib" "kernel32.lib" "advapi32.lib" "userenv.lib" "kernel32.lib" "ws2_32.lib" "bcrypt.lib" "msvcrt.lib" "legacy_stdio_definitions.lib"
 "/NXCOMPAT"
 "/LIBPATH:C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib"
 "/OUT:Z:\\AS_Shared\\cpp_bindings\\LibZos\\target\\debug\\deps\\libzos_cppbinding-0ce0ce7e106f0a6d.exe"
 "/OPT:REF,NOICF"
 "/DEBUG"
 "/NATVIS:C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis"
 "/NATVIS:C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis"
 "/NATVIS:C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis"
 "/NATVIS:C:\\Rust\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libstd.natvis"
  = note: LINK : warning LNK4044: unrecognized option '/WHOLEARCHIVE:LibZos_Handler.lib'; ignored
          libzos_cppbinding-0ce0ce7e106f0a6d.4f9clwp3n4twmcuz.rcgu.o : error LNK2019: unresolved external symbol cxxbridge1$new_LibZos_Handler referenced in function _ZN16libzos_cppbinding9libzos_ffi17new_LibZos_Handler17h146adabcdc2da60cE
          libzos_cppbinding-0ce0ce7e106f0a6d.4f9clwp3n4twmcuz.rcgu.o : error LNK2019: unresolved external symbol cxxbridge1$LibZosHandler$get_lasterrormsg referenced in function _ZN16libzos_cppbinding9libzos_ffi12LibZosHandler16get_lasterrormsg17h2ff8b3fb20eea595E
          libzos_cppbinding-0ce0ce7e106f0a6d.4f9clwp3n4twmcuz.rcgu.o : error LNK2019: unresolved external symbol cxxbridge1$LibZosHandler$is_initialized referenced in function _ZN16libzos_cppbinding9libzos_ffi12LibZosHandler14is_initialized17ha27f87793527ebf4E
          ...
          libzos_cppbinding-0ce0ce7e106f0a6d.4f9clwp3n4twmcuz.rcgu.o : error LNK2019: unresolved external symbol cxxbridge1$unique_ptr$LibZosHandler$raw referenced in function _ZN94_$LT$libzos_cppbinding..libzos_ffi..LibZosHandler$u20$as$u20$cxx..unique_ptr..UniquePtrTarget$GT$5__raw17h4aab0d84de6d97a4E
          libzos_cppbinding-0ce0ce7e106f0a6d.4f9clwp3n4twmcuz.rcgu.o : error LNK2019: unresolved external symbol cxxbridge1$unique_ptr$LibZosHandler$get referenced in function _ZN94_$LT$libzos_cppbinding..libzos_ffi..LibZosHandler$u20$as$u20$cxx..unique_ptr..UniquePtrTarget$GT$5__get17ha46db16b10c2fcceE
          libzos_cppbinding-0ce0ce7e106f0a6d.4f9clwp3n4twmcuz.rcgu.o : error LNK2019: unresolved external symbol cxxbridge1$unique_ptr$LibZosHandler$drop referenced in function _ZN94_$LT$libzos_cppbinding..libzos_ffi..LibZosHandler$u20$as$u20$cxx..unique_ptr..UniquePtrTarget$GT$6__drop17hcad8fd1c330ee65aE
          Z:\AS_Shared\cpp_bindings\LibZos\target\debug\deps\libzos_cppbinding-0ce0ce7e106f0a6d.exe : fatal error LNK1120: 23 unresolved externals`**

An this is the build.rs content:

fn main() {
    #[cfg(target_os = "windows")]
    cxx_build::bridge("src/lib.rs")
        .include("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\include")
        .include("C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.19041.0\\ucrt")
        .include("cpp_bindings")
        .file("cpp/LibZos_cppWrapper/LibZos_Handler.cpp")
        .flag_if_supported("-std=c++11")
        .flag_if_supported("-D_UNICODE")
        .compile("LibZos_Handler");

    #[cfg(target_family = "unix")]
    cxx_build::bridge("src/lib.rs")
        .file("cpp/LibZos_cppWrapper/LibZos_Handler.cpp")
        .flag_if_supported("-std=c++11")
        .flag_if_supported("-D_UNICODE")
        .compile("LibZos_Handler");

    println!("cargo:rerun-if-changed=src/lib.rs");
    println!("cargo:rerun-if-changed=cpp/LibZos_cppWrapper/LibZos_Handler.hpp");
    println!("cargo:rerun-if-changed=cpp/LibZos_cppWrapper/LibZos_Handler.cpp");
    #[cfg(target_os = "macos")]
    println!("cargo:rustc-link-search=cpp/LibZos_cppWrapper/LibZos/lib/OSX/");
    #[cfg(target_os = "linux")]
    println!("cargo:rustc-link-search=cpp/LibZos_cppWrapper/LibZos/lib/Lnx64/");
    #[cfg(target_os = "windows")]
    println!("cargo:rustc-link-search=Z:\\AS_Shared\\cpp_bindings\\LibZos\\cpp\\LibZos_cppWrapper\\LibZos\\lib\\Win64");
    #[cfg(target_family = "unix")]
    println!("cargo:rustc-link-lib=zos");
    #[cfg(target_os = "windows")]
    println!("cargo:rustc-link-lib=libzos");
}

I'm looking for help, so many thanks in advance if someone could tell me what I'm missing.

raycoe commented 1 year ago

I attempted to rebuild the cxx project within MSVC and get the same errors.

With this project, it looks like that at some stage, cxx-build is building a cxxbridge1.lib that calls functions that cannot be resolved and then produce LNK2019 errors.

Something looks to be missing in the libraries that are generated by cxx-build, it can be in the LIBPATH or some libraries themselves, at least in the Windows environment but can't figure out which ones.

raycoe commented 1 year ago

The most amazing when looking for symbol refs on the cxx-generated lib file after having tried many options with cargo-test:

00000000 T cxxbridge1$new_libzos_handler`
00000730 T cxxbridge1$unique_ptr$LibZosHandler$drop`
000006f0 T cxxbridge1$unique_ptr$LibZosHandler$get`
00000640 T cxxbridge1$unique_ptr$LibZosHandler$null`
00000690 T cxxbridge1$unique_ptr$LibZosHandler$raw`
00000710 T cxxbridge1$unique_ptr$LibZosHandler$release`
...

Which is indicating that symbols are defined...

mvo4777 commented 1 year ago

Hi @raycoe,

Did you get a chance to solve the issue on Windows?

I'm facing exactly the same problem with a cross-platform c++ static library, I think cxx is not really meant to work with Windows but nix platforms only...

schreter commented 1 year ago

I don't have Windows, but the problem may be in the whole-archive handling. The compilation warns you that the option is unsupported/unknown. Simply put, the symbols are optimized out if not directly used, unless you force compiling in the whole archive (i.e., the whole static lib). But I may be mistaken.

raycoe commented 1 year ago

I'm doubting that LNK1120 fatal errors are due to the warn LNK4044 since the last is simply ignored anyway by CL. But I could give it a try if there is any possibility to manipulate /WHOLEARCHIVE option that is apparently forced by cxx.

whynothackme commented 1 year ago

Could you perhaps try deleting or renaming the lib.rs file? That might help!

ctemple commented 1 year ago

Could you perhaps try deleting or renaming the lib.rs file? That might help!

it's worked!

eminence commented 1 year ago

I'm also on Windows, and trying to get a basic "hello-world" working, and I ran into this issue too. Removing my empty lib.rs solved the problem (thank you @whynothackme )

But it's not clear to me if using lib.rs is a limitation, or if some additional care/configuration is needed when using cxx with a rust library.

raycoe commented 11 months ago

I don't know how above suggested solution could work since, except if I missed something, rust requires either a main.rs if app or a lib.rs if lib.

Now that I upgraded to 1.74 cargo environment, it no longer working on MacOS (13.6) either!