When I started using Rust, one of the major selling points I tried to drive home to people was that there would no longer have to be a bunch of
.in files that the build system would use to build itself - differently - on different platforms.
Well, it didn't take long until I realized that this wasn't the entirely true. The point is still somewhat valid, because it's far less of an issue (we only need one currently). Anyway, this has caused some friction internally among people who aren't used to complicated build systems, so I thought I'd see if there are any good solutions to it.
Basically the problem can be summarized as:
- we use rusqlite (and like it, thus want to keep using it)
- on unixy platforms we want to use the shared library as installed by the platform's native package managing system (this is the default behavior, so everything is good)
- on windows we want to dynamically link to the CRT, but statically link everything else (basically we want to avoid non-system DLL's).
features = ["bundled"]allows rusqlite to build sqlite from source and use that version. This is not perfect, but acceptable, for Windows builds -- but not for non-Windows platforms.
This is where I first noticed that the features in
Cargo.toml have some slightly surprising semantics; they don't respect the platform-specific sections. (It was a while back that I did this, but I believe the feature being used is actually the union of all feature sections).
Anyway, it was at that point that I simply went with a
Cargo.toml.in, and preprocess those files before builds so each platform got their appropriate features. For me, this is still a major win since its orders of magnitude less complicated that most build systems that need to work on both Unixy platforms and Windows, but others aren't as happy with it, and there's a wish to "just use plain Cargo.toml" files, which I obviously agree with would be optimal.
From time to time I have tried to use vcpkg. It seems promising, but I always end up spending way too long trying to bend it to my will, so I just go with custom build scripts for the libraries we need. (Again, this is acceptable to me, but not to those who aren't accustomed something more complicated than pressing F5 in Visual Studio).
So what I'm basically wondering is if there's some way to eliminate my
Cargo.toml.in hack, but get static builds of sqlite for rusqlite on Windows (but with dynamic CRT, obviously), but regular dynamic builds on all other platforms?
The reason I mention vcpkg is because I read the vcpkg crate docs, which states:
The default 64-bit configuration is
x64-windows-static-mdwhich is a community supported configuration that is a good match for Rust - dynamically linking to the C runtime, and statically linking to the packages in vcpkg.
This sounds perfect -- but how do I use it? I know I build using
.\vcpkg.exe install sqlite:x64-windows-static-md, but how do I make sure that the rusqlite picks this build?
Any other suggestions to get to the desired end goal?
Also, how do people handle this
features quirk? When I started to think about it, I realized that there's bound to be plenty of situations where one want to build with different default features on different platforms. Is this something one can accomplish with