Build and Run Windows and Linux Binaries of Rust Programs from Bash with WSL

This blog post explains one way to build and run both Windows and Linux binaries of a rust program from a single process running under Windows Subsystem for Linux (WSL).

Update 21.June.2021: Current code at wink/wince at main · deliverystack/wink (github.com)

From a bash process under WSL, you can use a shell script to build and run both Linux and Windows binaries of a rust program.

One trick is to be in the directory that contains the project (C:\temp\wink in my example), which should be a Windows file system rather than something hosted under WSL (not under \\wsl.localhost\Ubuntu-20.04 or equivalent). I store my significant rust files in a directory on OneDrive, which can be available for sharing code, scripts, and any other files between Windows and WSL on any number of machines.

Another trick is to install rust for both Windows and Linux and call cargo build for each.

Yet another trick is to use cmd.exe /c to invoke Windows cargo.exe from bash to build the Windows executable, and then call cmd.exe /c again to invoke the built executable.

In my case, the wink executable that I am building calls cmd.exe /c if I pass raw as the first parameter, so I build the wink Linux executable and use that wink executable to build and run the Windows executable.

This script includes some other things that slow it down a bit, such as updating rust as well as an unnecessary cargo check and possibly cargo update. In this script, the list of files to rustfmt is hard-coded, as are the paths to output files determined by whether the builds are debug or release.

The script tries to prevent building if cargo-clippy generates any warnings. Otherwise, if the build succeeds, it overwrites the installed copy of the wink executable with the new build, and then uses that to build and run the Windows executable. This basically adds one level of process hierarchy around a call to cmd.exe /c, but processes are relatively inexpensive to spawn nowadays and this tests the new Linux binary.

After invoking the Windows wink binary with the help parameter, the script invokes the Linux binary with the parameters supplied on the command line used to invoke this script, the absence of which would lead to the Linux binary showing help information for the wink command just as the Windows invocation did with the help command. Finally, it attempts to revert to the working directory that was in place before the script ran, without indicating the path indicating that it has done so.

#!/bin/sh

clear
rustup update
rustfmt /mnt/c/temp/wink/src/main.rs

if [ $? -ne 0 ]; then
    echo rustfmt failed
    exit 2
else
    cd /mnt/c/temp/wink
    cargo check
    cargo update 
    cargo-clippy 2>&1 | egrep -iq warning

    if [ $? -eq 0 ]; then
        echo cargo-clippy failed
        exit 3
    else
        cargo doc
        cargo build --release # affects binary path below 

        if [ $? -ne 0 ]; then
            echo cargo build failed
            exit 4
        else
            rm ~/bin/wink
            ls -l target/release/wink
            cp target/release/wink ~/bin
            # use newly built Linux wink to build Windows wink binary
            ~/bin/wink raw cargo.exe build --release # affects binary path below 
            ls -l target/release/wink.exe
            target/release/wink.exe help
            ~/bin/wink $@
        fi
    fi
fi

cd - > /dev/null
exit 0

One thought on “Build and Run Windows and Linux Binaries of Rust Programs from Bash with WSL

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: