My First Publish to crates.io (and cross compilation)
TheoForger
Posted on November 28, 2024
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"
and pushed it to GitHub (I had to use --follow-tags
since tags aren't pushed by default):
$ git push --follow-tags
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
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!
📦 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
And everything just worked. The improvement was truly night and day!
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
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:
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'
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
Then it was finally the time to build:
$ cross run --target aarch64-apple-darwin
🎉 Et Voilà! I have all the binaries ready!
Posted on November 28, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.