DEV Community

TheoForger
TheoForger

Posted on

My First Publish to crates.io (and cross compilation)

Finally, the time has come! This week we were tasked to release our code on GitHub and publish to a registry. For years, downloading software from the Releases page was my only use for GitHub. Now it's coming full circle. Time to release Mastermind!

🚀 Releasing on GitHub

To make sure the commit is clearly marked, I added a new tag:

$ git tag -a v1.0.0 -m "mastermind release v1.0.0"
Enter fullscreen mode Exit fullscreen mode

and pushed it to GitHub (I had to use --follow-tags since tags aren't pushed by default):

$ git push --follow-tags
Enter fullscreen mode Exit fullscreen mode

Then I simply went on GitHub and drafted the release. That was it! quick and easy! Although I did a few more attempts due to an issue with crates.io, which I'll discuss later.

🎉 Publishing to crates.io

crates.io is the central repository/registry for Rust crates. It's a crucial part of the Rust ecosystem.

Publishing to crates.io was surprisingly easy. Following the documentation, I made an account and logged in using cargo login, and then added some more information in the Cargo.toml manifest file.

First concern I had was regarding included files. Luckily, there's a handy command for that!

$ cargo package --list
Enter fullscreen mode Exit fullscreen mode

Looking at the output, it seemed like everything in .gitignore was already excluded, so no additional configuration was needed. Neat!

After a dry run with cargo publish --dry-run, I went ahead and attempted my first publish. Here I ran into a couple of issues

The first problem concerned the license field in the metadata. I initially assumed that any input was acceptable, but after reading the doc once again, I realized there's a syntax to follow.

The second problem was with my crate name - My publish was rejected because the crate mastermind already existed in the registry. I followed it up by a search on crates.io. Turned out even mastermind-rs was taken too! I eventually learned that crates.io allocates names on a first-come-first-serve basis, so I went with mastermind-cli

Later, I did some more research into this since many other registries support namespaces or scopes. Turned out it's not a feature available yet on crates.io. There have been discussions about it, but it's not happening right now.

But hey, it surely felt nice to see my own project finally published!

mastermind-cli published

📦 Caching in GitHub Actions

It's been a few days since I published my project. I shared my experience during the class and learned a few things from other people as well! One of the things I decided to try was set up caching in GitHub Actions for my CI workflow to speed things up.

Luckily, there's already something for that on GitHub Marketplace. I simply added one line in each of the CI jobs:

- uses: Swatinem/rust-cache@v2
Enter fullscreen mode Exit fullscreen mode

And everything just worked. The improvement was truly night and day!

Before After
before after

🤞 Cross Compilation Shenanigans

After discussing my work during class, the professor suggested me looking into cross compilation and release binaries for different platforms.

Some quick research led to cross, which automatically sets up container environments for cross compilation.

🪟 Target: Windows

I followed the instructions on a get-started guide, which gave me some errors:

$ cross run --target x86_64-pc-windows-msvc
[cross] warning: `cross` does not provide a Docker image for target x86_64-pc-windows-msvc, specify a custom image in `Cross.toml`.
[cross] note: Falling back to `cargo` on the host.

# ... Some actions later

error: linker `link.exe` not found
  |
  = note: No such file or directory (os error 2)

note: the msvc targets depend on the msvc linker but `link.exe` was not found

note: please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.

note: VS Code is a different product, and is not sufficient.

error: could not compile `mastermind-cli` (bin "mastermind-cli") due to 1 previous error
Enter fullscreen mode Exit fullscreen mode

Again, one quick research later, I realized that cross doesn't actually support target x86_64-pc-windows-msvc, which requires some libraries that are only available on Windows.

Although there are ways to work around it, I decided to go with x86_64-pc-windows-gnu instead. This target will produce larger binaries since it's not using the Microsoft VC++ libraries. But it's a lot easier to work with on Linux.

Anyway, I ran the command with a different target. Right away, I saw docker running:

cross utilizing docker

After confirming it worked on my Windows VM, I uploaded it to my GitHub Release.

🍎 Target: macOS

I rarely work with Apple hardware/software and I gotta admit, it's a nightmare... if you don't use a Mac, which was exactly the case for me.

Due to licensing issue, cross does not host any container image for macOS, so I had to build it from scratch with macOS's SDK.

The only problem is: I searched across Apple's developer website, and couldn't for the sake of god find a way to download it. Then I learned that it's bundled with Xcode, which was only available to Mac users...

I then went on a tangent to find workarounds to obtain Xcode and extract the SDK. After hours of struggle, I stumbled upon a random GitHub hero who's brave enough to upload these SDKs in their repo (I'm not going to link it here for obvious reason 😆). Usually I wouldn't trust something like this, but this time I decided to go with it.

Good news is that things weren't too bad from then on. cross only supports an older version of the SDK, so I went with 12.3:

cargo build-docker-image aarch64-apple-darwin-cross \
  --build-arg 'MACOS_SDK_FILE=MacOSX12.3.sdk.tar.xz'
Enter fullscreen mode Exit fullscreen mode

building docker image

After the image was built, I verified it with:

$ docker image ls
REPOSITORY                                    TAG       IMAGE ID       CREATED         SIZE
ghcr.io/cross-rs/aarch64-apple-darwin-cross   local     6dd44db89a86   8 minutes ago   1.74GB

Enter fullscreen mode Exit fullscreen mode

Then it was finally the time to build:

$ cross run --target aarch64-apple-darwin
Enter fullscreen mode Exit fullscreen mode

🎉 Et Voilà! I have all the binaries ready!

GitHub Release

Top comments (0)