I am currently working on a Rust project that requires me to connect to a MariaDB server. I have decided to create Rust bindings for the officially provided C connector, which works just fine in linux, but not on Windows.
Since only the MSVC-binaries are provided as a download, which don't work due to linker issues between the Microsft linker and the MinGW linker used for Rust that cause the program to crash when the first function is called, I tried to compile the mariadb sources myself, but even though compilation under MinGW should work as of the 2.0 release of mariadb, it fails with
error: conflicting types for ssize_t
typedef SSIZE_T ssize_t
since it has already been defined in another file, and when I tried to simply remove the redefinition, other errors occured.
I tried to cross-compile it from Arch using the mingw-w64-mariadb-connector-c package, which did not show any compilation errors for the connector, but when I tested the binaries on windows, it threw an undefined reference linking error for every of my C-Function declarations, which look like this:
extern crate libc;
use self::libc::{c_int, /*...*/};
#[link(name="mariadb", kind="dylib")]
extern {
pub fn mysql_init(mysql: *const MYSQL) -> c_int;
// ...
}
I also tried this suggestion for the mysql-c-connector, but the same linker errors appeared.
I am using the newest rust nightlies and MinGW-w64 v4.9.1 (the same version as in the nightlies), both 32 bit.
Related
I'm experimenting with Rust on Windows. My code declares and calls a function in an external library.
The declaration is like this:
#[link(name = "Rvea0326nc-64")]
extern "C" {
fn WeibullSpeedProbability(wa: &f32, wk: &f32, qu: &f32, prob: &f32, theerr: &i32) -> ();
}
(It's all ByRef because the DLL is Fortran. It's built with the Intel compiler.)
Note that the file name has no extension. The DLL is in the \target\debug\deps folder of the Rust project.
According to the documentation here
https://doc.rust-lang.org/std/keyword.extern.html, this should import a DLL on Windows, but I get an error, thus:
error: linking with `link.exe` failed: exit code: 1181
<SNIP>
= note: LINK : fatal error LNK1181: cannot open input file 'Rvea0326nc-64.lib'
Sure enough, if I find and copy in the *.lib file from which the DLL was generated, everything works fine. The DLL is apparently irrelevant.
I have tried explicitly adding ".dll" to the link name, but Rust just complains that it cannot find Rvea0326nc-64.dll.lib.
Is the documentation wrong? Have I missed something? Is there a way to get Rust to work with the DLL?
Update: I found that when running the Rust-compiled executable directly, the DLL is required and the LIB is not.
Without having too much experience with FFI in Rust, I can imagine to compile your program, you will need the .lib installed on your machine, so that rustc can correctly check that the FFI function is correct. Then when the produced binary is run, it loads the .dll at runtime and uses it.
Try to see if after producing a binary with the .lib installed, that you can run that binary without the .lib installed.
I'm trying to compile Rust code on Windows that calls vsnprintf. My C code looks like this:
#include <stdarg.h>
#include <stdio.h>
// A static buffer for storing any formatted messages.
static char buffer[4096];
void rust_logger(const char *fmt, ...) {
// Reconstruct the variable arguments as a va_list. This is necessary so we
// can chain together a call to vsnprintf.
va_list varargs;
va_start(varargs, fmt);
// Write the formatted string to our target (static) buffer.
vsnprintf(buffer, sizeof(buffer)-1, fmt, varargs);
// Call Rust back with final string
...
// Clean up processing of variable arguments
va_end(varargs);
}
This works fine on macOS (and I would guess under Linux, although I have not tried it). But on Windows, I'm having problems. The error I get is:
"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "/LIBPATH:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.10240.0\\ucrt\\x64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\8.1\\lib\\winv6.3\\um\\x64" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\deps\\rust_fmu-dd167e2c1e3583f1.0.o" "/OUT:C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\deps\\rust_fmu-dd167e2c1e3583f1.exe" "/OPT:REF,NOICF" "/DEBUG" "/LIBPATH:C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\deps" "/LIBPATH:C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\build\\rust-fmu-e434516f4288772d\\out" "/LIBPATH:C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "logger.lib" "C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\deps\\liblibloading-c41a2f71457b39f3.rlib" "C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\deps\\liblibc-5dc7b85e748840b4.rlib" "C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\deps\\libkernel32-835ed4d4f4dc2d3e.rlib" "C:\\Users\\mtiller\\Source\\rust-fmu\\target\\debug\\deps\\libwinapi-a5898d7aceb63fac.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-90fbcc8c07b4a644.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-d2e7baf2c0a36eaf.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-112baa0117a60076.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-ad15457034b2bf37.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librand-fa1852079e0fefd1.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcollections-27e4c8cc19e6faac.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-588bb0bd8c9dd8ca.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc_system-dbfe715efb71d408.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_unicode-a2e15800b52a7a60.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-b2880fdfb9b2b596.rlib" "C:\\Users\\mtiller\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-9d27746f5ba8488f.rlib" "kernel32.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "shell32.lib" "msvcrt.lib"
note: logger.lib(logger.o) : error LNK2019: unresolved external symbol __ms_vsnprintf referenced in function vsnprintf
C:\Users\mtiller\Source\rust-fmu\target\debug\deps\rust_fmu-dd167e2c1e3583f1.exe : fatal error LNK1120: 1 unresolved externals
From my research, it seems like this has something to do with some mismatch between MinGW and MinGW64, but when I look at the output of the Rust build, it seems to be using Visual Studio 14.0.
I'm totally confused. I don't quite know how Rust determines which toolchain to use. I used the rustup-init.exe installer which I assumed would "do the right thing", but it seems confused here (or is it just me).
Any suggestions on how to get my toolchain aligned? One other constraint is that I'm using the libloading crate because my program is loading DLLs. I want that part to work as well, but haven't gotten to test that under Windows yet because of build issues.
P.S. - I need the v version of vsnprintf because I'm getting passed varargs and I need a way to actually process them.
My machine had MSVC, MinGW64 and MinGW installed on it. Given the error messages, I fell into the trap of thinking that it was related to rustc invoking the wrong compiler/linker because of issues in my path or its own assumptions about the tools on my machine.
It turns out the build script I was using was calling gcc and ar directly, which invoked the MinGW commands. I thought Rust had "wrappers" for these commands so they behaved the same on all platforms (hence my lack of concern about these).
When I read the documentation on build scripts more closely, I see that they repeat the same (non-portable) approach, but then talk about the lack of cross-platform support for that approach and then show a much simpler and more portable way to do this.
Bottom line, use:
[build-dependencies]
gcc = "0.3"
...and read the build script documentation carefully. Now everything compiles fine on both macOS and Windows.
I'm trying to integrate CUDA to an existing aplication wich uses boost::spirit.
Isolating the problem, I've found out that the following code does not copile with nvcc:
main.cu:
#include <boost/spirit/include/qi.hpp>
int main(){
exit(0);
}
Compiling with nvcc -o cudaTest main.cu I get a lot of errors that can be seen here.
But if I change the filename to main.cpp, and compile again using nvcc, it works. What is happening here and how can I fix it?
nvcc sometimes has trouble compiling complex template code such as is found in Boost, even if the code is only used in __host__ functions.
When a file's extension is .cpp, nvcc performs no parsing itself and instead forwards the code to the host compiler, which is why you observe different behavior depending on the file extension.
If possible, try to quarantine code which depends on Boost into .cpp files which needn't be parsed by nvcc.
I'd also make sure to try the nvcc which ships with the recent CUDA 4.1. nvcc's template support improves with each release.
I'm trying to compile a library on windows with mingw, that uses boost.
I compiled boost with:
bootstrap mingw
b2 toolset=gcc
After that I build the library with cmake and mingw.
Building the dll itself works fine, but when I try to build the tests, I get:
C:/boost/boost_1_55_0/boost/test/utils/runtime/config.hpp:95:51: error: 'putenv'
was not declared in this scope
putenv( const_cast<char*>( fs.str().c_str() ) );
So the error comes from a boost header and I have no idea how to fix that.
The repo of what I'm trying to build: https://github.com/linges/daestruct
It uses c99 and c++11.
This seems to be a bug in boost. It has been happened to others, too:
https://github.com/BoostGSoC/boost.afio/commit/1b06855b6e20a01a3c4461c6d2d54e16eb3c8e21
The solution (or better: workaround) is to add the following lines before the inclusion of boost::test:
#ifdef __MINGW32__
// Mingw doesn't define putenv() needed by Boost.Test
extern int putenv(char*);
#endif
so, I'm trying to compile Gwen in Windows, for use with a project I have coming up. I downloaded the source from Garry's GitHub, and followed his instructions on building the compilation before importing it to Code::Blocks to compile. I import the .cbp file, start compiling, and after a few minutes I get:
Error: '_asm' was not declared in this scope.
The error comes from some code after a line containing #ifdef _WIN32.
Exact file: gwen.cpp, line 49.
More information:
OS: Windows 7 64bit.
Compiler: Latest gcc from the MinGW, 4.7.2 (MinGW32)
I think it is because MinGW doesn't understand the assembler, it should be asm for that compiler. I think this is cause by using _WIN32 instead of WIN32. The former is the platform and the latter is API.
Try changing it to:
void AssertCheck(bool b, const char* strMsg)
{
if (!b)
{
Msg("Assert: %s\n", strMsg);
#ifdef WIN32
MessageBoxA(NULL, strMsg, "Assert", MB_ICONEXCLAMATION|MB_OK);
_asm { int 3 }
#endif
}
}
EDIT: Alternatively you could try Gwork, which is a tidied up version of GWEN.