How to build both 32- and 64-bit app on Windows

I want to build both 32- and 64-bit binaries of an application on Windows 7-64. I have installed the stable-i686 and stable-x86_64 toolchains and have built the application as 64-bit with no problems. But the 32-bit one ends up with some 64-bit code and won't run.

I use two .bat files to build:

rustup default stable-i686-pc-windows-msvc
SET CARGO_TARGET_DIR=C:\tmp\targets\myapp32
SET RELEASE_DIR=%CARGO_TARGET_DIR%\release
mkdir %RELEASE_DIR%
cargo build --release
copy %RELEASE_DIR%\myapp.exe ..\files32

and

rustup default stable-x86_64-pc-windows-msvc
SET CARGO_TARGET_DIR=C:\tmp\targets\myapp64
SET RELEASE_DIR=%CARGO_TARGET_DIR%\release
mkdir %RELEASE_DIR%
cargo build --release
copy %RELEASE_DIR%\myapp.exe ..\files64

Is there something I'm missing or doing wrong --- or is there a better approach?

1 Like

I've now tried using a different approach:

SET CARGO_TARGET_DIR=C:\tmp\targets\myapp64
SET RELEASE_DIR=%CARGO_TARGET_DIR%\release
mkdir %RELEASE_DIR%
cargo build --target=x86_64-pc-windows-msvc --release
copy %RELEASE_DIR%\myapp.exe ..\files64

This works fine (as the previous version did).
But building for 32-bits doesn't work.
I believe I have the correct toolchains installed:

C:\>rustup toolchain list
stable-i686-pc-windows-msvc
stable-x86_64-pc-windows-msvc (default)

But when I try:

SET CARGO_TARGET_DIR=C:\tmp\targets\myapp32
SET RELEASE_DIR=%CARGO_TARGET_DIR%\release
mkdir %RELEASE_DIR%
cargo build --target=i686-pc-windows-msvc --release
copy %RELEASE_DIR%\myapp.exe ..\files32

It won't build. (I know the copy won't work either, but I don't get that far.)
It reports:

V:\myapp>cargo build --target=i686-pc-windows-msvc --release
   Compiling rand_core v0.4.0
   Compiling unicode-width v0.1.5
   Compiling lazy_static v1.3.0
   Compiling ucd-util v0.1.3
error[E0463]: can't find crate for `core`
error[E0463]: can't find crate for `core`
  |
  |
  = note: the `i686-pc-windows-msvc` target may not be installed

So I'm stuck!

1 Like

What you want is rustup target add i686-pc-windows-msvc.

1 Like

Thank you. That gets me further.

Now my 64-bit .bat file is:

SET ARCH=x86_64-pc-windows-msvc
SET CARGO_TARGET_DIR=C:\tmp\targets\myapp64
SET RELEASE_DIR=%CARGO_TARGET_DIR%\%ARCH%\release
cargo build --target=%ARCH% --release
copy %RELEASE_DIR%\myapp.exe c:\bin\myapp64.exe

with the 32-bit only different by having the different ARCH and target dir & exe name.

However, although the 32-bit exe now builds, it crashes when run due to a "BEX" error even after I did a cargo clean and rebuilt it.

The depends program reports a problem with the 32-bit exe: "Error: Modules with different CPU types were found." Which sounds to me like I have some 64-bit artifacts even though I build the 32- and 64-bit versions in different target dirs.

Are you using any C dependencies? Maybe the sys crates find 64-bit libraries.

I'm not aware that I have any C dependencies: the app is pure rust + some access to DLLs (for which I have a cfg to choose 32- or 64 bits). But I use lots of crates so maybe one of those is 64 bit only. I'll try again with a small example app.

BTW, cargo tree can show you all the deps.

I had a look through Cargo.lock and there are lots of -sys crates I'm using.

I also tried building a really tiny example both 32- and 64-bit and both built and ran fine.
And I also tried building my qtrac-retest crate both 32- and 64-bit, and again both built and ran fine.

So for the larger app I'm working on I think you're right that I have a crate dependency that's 64-bit only. But even if I found out which one (or ones) it is, knowing that won't give me a 32-bit build.

I thought that crates.io did some automated build tests? Maybe it could say which triples (of those tested) work and which don't?

Knowing which dependency it is could help you file a bug and get it fixed. Sys crates usually also have a way to force them to build a static library from source instead of searching the system for it.

crates.io doesn't build packages. Indirectly docs.rs and "crater runs" do it, but not on Windows, and not cross-compiled.

Try building with --verbose flag. Maybe you'll notice wrong library paths.

Unfortunately, I've now removed all the 32-bit support. It was only a "nice to have" for me and had the disadvantage of doubling the number of packages and tests. I know that people use virtual machines, but I don't really know why people still use 32 bits (although I do have two ancient laptops that are 32 bits, so maybe other people hang on to old machines too).

I finally built my application on a Win7-32 bit system. So now I suspect that the winapi module was maybe using kernel-sys when I build in both 32- and 64-bit mode on Win7-64, but correctly uses kernel32-sys on Win7-32. (I can't be certain though because I now only have a 64-bit toolchain on the 64-bit system and a 32-bit toolchain on the 32-bit system).

@mark is it possible to share the command which used to compile to 32 bit?
or even can you share the executable that you have produced?

i'm getting about the same errors with no luck.

thx

I'm very sorry but it is so long ago I no longer remember and since then I abandoned 32-bit rust and only build 64-bit applications or libraries with it.

This topic was automatically closed 30 days after the last reply. We invite you to open a new topic if you have further questions or comments.