Building Rust Code - Using Make Part 2

This series of posts is about building Rust code. In the last post I showed some nice abstractions for using Make with Rust. Today I'll show an improved version of this integration.

New Rust Compiler Flags

After landing the pkgid attribute work there was much community discussion about how that feature could be improved. The net result was:

  • pkgid was renamed to crate_id it's being used to identify a crate and not a package, which is a grouping of crates. Actually, a package is still a pretty fluid concept in Rust right now.
  • The crate_id attribute can now override the inferred name of the crate with new syntax. A crate_id of github.com/foo/rust-bar#bar:1.0 names the crate bar which can be found at github.com/foo/rust-bar. Previously the crate name was inferred to be the last component of the path, rust-bar.
  • The compiler has several new flags to print out this information, saving tooling the bother of parsing it out and computing crate hashes itself. You can use --crate-id, --crate-name, and --crate-file-name so get the value of the crate_id attribute, the crate's name, and output filenames the compiler will produce.

These changes made a good thing even better.

Magical Makefiles Version 2

The Makefile hasn't changed much, but here is a much simpler rust.mk that the new compiler flags enable:

define RUST_CRATE

_rust_crate_dir = $(dir $(1))
_rust_crate_lib = $$(_rust_crate_dir)lib.rs
_rust_crate_test = $$(_rust_crate_dir)test.rs

_rust_crate_name = $$(shell $(RUSTC) --crate-name $$(_rust_crate_lib))
_rust_crate_dylib = $$(shell $(RUSTC) --crate-file-name --lib $$(_rust_crate_lib))

.PHONY : $$(_rust_crate_name)
$$(_rust_crate_name) : $$(_rust_crate_dylib)

$$(_rust_crate_dylib) : $$(_rust_crate_lib)
$$(RUSTC) $$(RUSTFLAGS) --dep-info --lib $$<

-include $$(patsubst %.rs,%.d,$$(_rust_crate_lib))

ifneq ($$(wildcard $$(_rust_crate_test)),"")

.PHONY : check-$$(_rust_crate_name)
check-$$(_rust_crate_name): $$(_rust_crate_name)-test
    ./$$(_rust_crate_name)-test

$$(_rust_crate_name)-test : $$(_rust_crate_test)
    $$(RUSTC) $$(RUSTFLAGS) --dep-info --test $$< -o $$@

-include $$(patsubst %.rs,%.d,$$(_rust_crate_test))

endif

endef

No more nasty sed scripts necessary, but of course, the crate hash is still computable if you want to do it yourself for some reason.

more info