Rust Once, Run Everywhere post from Rust official blog, led me to the author's repository with FFI examples. I was able to run "Rust to C" example, but "C to Rust" gives me a little headache.
Here's what I did:
- I compiled the Rust code to library using:
cargo build
- There's a Makefile in the repository, but since I'm on Windows, and using mscv version of the rustc, I couldn't use it. I tried to make executable, by linking C source with the library:
cl src\main.c target\debug\double_input.lib
- Compiler (or rather linker) started to yell at me:
Microsoft (R) C/C++ Optimizing Compiler Version 19.20.27508.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
Microsoft (R) Incremental Linker Version 14.20.27508.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
target\debug\double_input.lib
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol freeaddrinfo referenced in function _ZN4core3ptr18real_drop_in_place17h8f7164cb4c08a80cE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol closesocket referenced in function _ZN4core3ptr18real_drop_in_place17hd12d400f3f6dc52fE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol WSACleanup referenced in function _ZN50_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$8call_box17hda1367731cbd7b29E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol OpenProcessToken referenced in function _ZN3std3env8home_dir17hcfcc8baa85f07218E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol GetUserProfileDirectoryW referenced in function _ZN3std3env8home_dir17hcfcc8baa85f07218E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol getpeername referenced in function _ZN3std3net3tcp9TcpStream9peer_addr17h4fda3ba35bb8aa36E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol WSAGetLastError referenced in function _ZN3std3net3tcp9TcpStream9peer_addr17h4fda3ba35bb8aa36E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol shutdown referenced in function _ZN3std3net3tcp9TcpStream8shutdown17h85198a6ac8f9970aE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol recv referenced in function _ZN3std3net3tcp9TcpStream4peek17hb15011b3e7917eb7E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol setsockopt referenced in function _ZN3std3net3tcp9TcpStream11set_nodelay17hf7caa446ab5ce1d7E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol WSARecv referenced in function _ZN58_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Read$GT$13read_vectored17hafff0ac29a6c2f3cE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol send referenced in function _ZN59_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$5write17hab6a293bc8927e9aE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol WSASend referenced in function _ZN59_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$14write_vectored17he9669e435a174b0cE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol getsockname referenced in function _ZN3std3net3tcp11TcpListener10local_addr17h2e8ac0f973ead7b7E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol ioctlsocket referenced in function _ZN3std3net3tcp11TcpListener15set_nonblocking17heca205f14b171f87E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol WSAStartup referenced in function _ZN3std4sync4once4Once9call_once28_$u7b$$u7b$closure$u7d$$u7d$17h151cd75414ec4185E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol getsockopt referenced in function _ZN3std10sys_common3net10getsockopt17heed543cec873071bE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol getaddrinfo referenced in function _ZN120_$LT$std..sys_common..net..LookupHost$u20$as$u20$core..convert..TryFrom$LT$$LP$$RF$$u27$a$u20$str$C$$u20$u16$RP$$GT$$GT$8try_from17h86ace16b016ac604E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol connect referenced in function _ZN3std10sys_common3net9TcpStream7connect17h223cef679bf78102E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol bind referenced in function _ZN3std10sys_common3net11TcpListener4bind17he4c8532dd61a943aE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol listen referenced in function _ZN3std10sys_common3net11TcpListener4bind17he4c8532dd61a943aE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol sendto referenced in function _ZN3std10sys_common3net9UdpSocket7send_to17h37852fb24b8a7411E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol WSASocketW referenced in function _ZN3std3sys7windows3net6Socket3new17hbc4ce7cb35631eb9E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol select referenced in function _ZN3std3sys7windows3net6Socket15connect_timeout17h02959efe5714bddfE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol accept referenced in function _ZN3std3sys7windows3net6Socket6accept17h057430023cc7e91cE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol WSADuplicateSocketW referenced in function _ZN3std3sys7windows3net6Socket9duplicate17h5325bb6f6710a926E
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol recvfrom referenced in function _ZN3std3sys7windows3net6Socket20recv_from_with_flags17h8e22e1848c76061dE
double_input.lib(std-c1e537280a7eb2d9.std.3xiyrb3s-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol SystemFunction036 referenced in function _ZN3std3sys7windows4rand19hashmap_random_keys17hd50cf806ba3f66a5E
main.exe : fatal error LNK1120: 28 unresolved externals
- I tried the same with clang compiler, with similar result.
- I changed target library type in Cargo.toml to 'dylib' and repeated all previous steps.This time it worked:
cl src\main.c target\debug\double_input.dll.lib
- I changed library target back to 'staticlib' and build a release version:
cargo build --release
- I repeated step 2, this time using release version of the library:
cl src\main.c target\release\double_input.lib
- It worked. OK, now I'm confused.
Is this a standard behavior, or is there a way to also link the 'debug' variant of a Rust library? Maybe I'm missing something really obvious and my approach may seem naive, but I'm used to build things 'by hand' and I would love to know, how cargo is running the show behind the scenes.
If I'm doing something stupid, please let me know. I'm here to learn.
My environment:
rustc 1.34.0 (91856ed52 2019-04-10),
Windows 10 Pro,
Visual Studio Community 2019,
LLVM 8.0