You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
12 KiB
305 lines
12 KiB
# Version 0.2
|
|
# Copyright 2017-2019, Stephan Sokolow
|
|
|
|
# --== Variables to be customized/overridden by the user ==--
|
|
|
|
# The target for `cargo` commands to use and `install-rustup-deps` to install
|
|
export CARGO_BUILD_TARGET := "x86_64-unknown-linux-gnu"
|
|
|
|
# An easy way to override the `cargo` channel for just this project
|
|
channel := "nightly"
|
|
|
|
# Extra cargo features to enable
|
|
features := ""
|
|
|
|
# An easy place to modify the build flags used
|
|
build_flags := ""
|
|
|
|
# Example for OpenPandora cross-compilation
|
|
# export CARGO_BUILD_TARGET = "arm-unknown-linux-gnueabi"
|
|
|
|
# -- `build-dist` --
|
|
|
|
# Set this to the cross-compiler's `strip` when cross-compiling
|
|
strip_bin := "strip"
|
|
|
|
# Flags passed to `strip_bin`
|
|
strip_flags := "--strip-unneeded"
|
|
|
|
# Set this if you need to override it for a cross-compiling `sstrip`
|
|
sstrip_bin := "sstrip"
|
|
|
|
# Example for OpenPandora cross-compilation
|
|
# strip_bin = `echo $HOME/opt/pandora-dev/arm-2011.09/bin/pandora-strip`
|
|
|
|
# -- `kcachegrind` --
|
|
|
|
# Extra arguments to pass to [callgrind](http://valgrind.org/docs/manual/cl-manual.html).
|
|
callgrind_args := ""
|
|
|
|
# Temporary file used by `just kcachegrind`
|
|
callgrind_out_file := "callgrind.out.justfile"
|
|
|
|
# Set this to override how `kcachegrind` is called
|
|
kcachegrind := "kcachegrind"
|
|
|
|
# -- `install` and `uninstall` --
|
|
|
|
# Where to `install` bash completions.
|
|
# **You'll need to manually add some lines to source these files in `.bashrc.`**
|
|
bash_completion_dir := "~/.bash_completion.d"
|
|
|
|
# Where to `install` fish completions. You'll probably never need to change this.
|
|
fish_completion_dir := "~/.config/fish/completions"
|
|
|
|
# Where to `install` zsh completions.
|
|
# **You'll need to add this to your `fpath` manually**
|
|
zsh_completion_dir := "~/.zsh/functions"
|
|
|
|
# Where to `install` manpages. As long as `~/.cargo/bin` is in your `PATH`, `man` should
|
|
# automatically pick up this location.
|
|
manpage_dir := "~/.cargo/share/man/man1"
|
|
|
|
# --== Code Begins ==--
|
|
|
|
# Internal variables
|
|
# TODO: Look up that GitHub issues post on whitespace handling
|
|
_cargo_cmd := "cargo" # Used for --dry-run simulation
|
|
_cargo := _cargo_cmd + " \"+" + channel + "\""
|
|
_build_flags := "--features=\"" + features + "\" " + build_flags
|
|
_doc_flags := "--document-private-items --features=\"" + features + "\""
|
|
|
|
# Parse the value of the "name" key in the [package] section of Cargo.toml
|
|
# using only the commands any POSIX-compliant platform should have
|
|
# Source: http://stackoverflow.com/a/40778047/435253
|
|
export _pkgname:=`sed -nr "/^\[package\]/ { :l /^name[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" Cargo.toml | sed 's@^"\(.*\)"$@\1@'`
|
|
export _rls_bin_path:="target/" + CARGO_BUILD_TARGET + "/release/" + _pkgname
|
|
export _dbg_bin_path:="target/" + CARGO_BUILD_TARGET + "/debug/" + _pkgname
|
|
|
|
# Shorthand for `just test`
|
|
DEFAULT: test
|
|
|
|
# -- Development --
|
|
|
|
# Alias for cargo-edit's `cargo add` which regenerates local API docs afterwards
|
|
add +args="":
|
|
{{_cargo}} add {{args}}
|
|
just doc
|
|
|
|
# Alias for `cargo bloat`
|
|
bloat +args="":
|
|
{{_cargo}} bloat {{_build_flags}} {{args}}
|
|
|
|
# Alias for `cargo check`
|
|
check +args="":
|
|
{{_cargo}} check {{_build_flags}} {{args}}
|
|
|
|
# Superset of `cargo clean -v` which deletes other stuff this justfile builds
|
|
clean +args="":
|
|
{{_cargo}} clean -v {{args}}
|
|
export CARGO_TARGET_DIR:="target/kcov" && {{_cargo}} clean -v
|
|
rm -rf dist
|
|
|
|
# Run rustdoc with `--document-private-items` and then run cargo-deadlinks
|
|
doc +args="":
|
|
{{_cargo}} doc {{_doc_flags}} {{args}} && \
|
|
{{_cargo}} deadlinks --dir target/$CARGO_BUILD_TARGET/doc/{{_pkgname}}
|
|
|
|
# Alias for `cargo +nightly fmt -- {{args}}`
|
|
fmt +args="":
|
|
{{_cargo_cmd}} +nightly fmt -- {{args}}
|
|
|
|
# Alias for `cargo +nightly fmt -- --check {{args}}` which un-bloats TODO/FIXME warnings
|
|
fmt-check +args="":
|
|
cargo +nightly fmt -- --check --color always {{args}} 2>&1 | egrep -v '[0-9]*[ ]*\|'
|
|
|
|
# Run a debug build under [callgrind](http://valgrind.org/docs/manual/cl-manual.html), then open the
|
|
# profile in [KCachegrind](https://kcachegrind.github.io/)
|
|
kcachegrind +args="":
|
|
{{_cargo}} build
|
|
rm -rf '{{ callgrind_out_file }}'
|
|
valgrind --tool=callgrind --callgrind-out-file='{{ callgrind_out_file }}' \
|
|
{{ callgrind_args }} 'target/{{ CARGO_BUILD_TARGET }}/debug/{{ _pkgname }}' \
|
|
'{{ args }}' || true
|
|
test -e '{{ callgrind_out_file }}'
|
|
{{kcachegrind}} '{{ callgrind_out_file }}'
|
|
|
|
# Generate a statement coverage report in `target/cov/`
|
|
kcov:
|
|
#!/bin/sh
|
|
# Adapted from:
|
|
# - http://sunjay.ca/2016/07/25/rust-code-coverage
|
|
# - https://users.rust-lang.org/t/tutorial-how-to-collect-test-coverages-for-rust-project/650
|
|
#
|
|
# As of July 2, 2016, there is no option to make rustdoc generate a runnable
|
|
# test executable. That means that documentation tests will not show in your
|
|
# coverage data. If you discover a way to run the doctest executable with kcov,
|
|
# please open an Issue and we will add that to these instructions.
|
|
# -- https://github.com/codecov/example-rust
|
|
|
|
# Ensure that kcov can see totally unused functions without clobbering regular builds
|
|
# Adapted from:
|
|
# - http://stackoverflow.com/a/38371687/435253
|
|
# - https://gist.github.com/dikaiosune/07177baf5cea76c27783efa55e99da89
|
|
export CARGO_TARGET_DIR:="target/kcov"
|
|
export RUSTFLAGS:='-C link-dead-code'
|
|
kcov_path="$CARGO_TARGET_DIR/html"
|
|
|
|
if [ "$#" -gt 0 ]; then shift; fi # workaround for "can't shift that many" being fatal in dash
|
|
cargo test --no-run || exit $?
|
|
rm -rf "$kcov_path"
|
|
|
|
for file in "$CARGO_TARGET_DIR"/"$CARGO_BUILD_TARGET"/debug/$_pkgname-*; do
|
|
if [ -x "$file" ]; then
|
|
outpath="$kcov_path/$(basename "$file")"
|
|
mkdir -p "$outpath"
|
|
kcov --exclude-pattern=/.cargo,/usr/lib --verify "$outpath" "$file" "$@"
|
|
elif echo "$file" | grep -F -e '-*'; then
|
|
echo "No build files found for coverage!"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Alias for cargo-edit's `cargo rm` which regenerates local API docs afterwards
|
|
rm +args="":
|
|
{{_cargo}} rm {{args}}
|
|
just doc
|
|
|
|
# Convenience alias for opening a crate search on lib.rs in the browser
|
|
search +args="":
|
|
xdg-open "https://lib.rs/search?q={{args}}"
|
|
|
|
# Run all installed static analysis, plus `cargo test`
|
|
test:
|
|
@echo "============================= Outdated Packages ============================="
|
|
@{{_cargo}} outdated
|
|
@echo "\n============================= Insecure Packages ============================="
|
|
@{{_cargo}} audit -q
|
|
@echo "\n=============================== Clippy Lints ================================"
|
|
@{{_cargo}} clippy -q {{_build_flags}}
|
|
@echo "\n===================== Dead Internal Documentation Links ====================="
|
|
@{{_cargo}} doc -q --document-private-items {{_build_flags}} && \
|
|
{{_cargo}} deadlinks --dir target/$CARGO_BUILD_TARGET/doc/{{_pkgname}}
|
|
@echo "\n================================ Test Suite ================================="
|
|
@{{_cargo}} test -q {{_build_flags}}
|
|
@echo "============================================================================="
|
|
|
|
# Alias for cargo-edit's `cargo update` which regenerates local API docs afterwards
|
|
update +args="":
|
|
{{_cargo}} update {{args}}
|
|
just doc
|
|
|
|
# TODO: https://users.rust-lang.org/t/howto-sanitize-your-rust-code/9378
|
|
|
|
# -- Local Builds --
|
|
|
|
# Alias for `cargo build`
|
|
build:
|
|
@echo "\n--== Building with {{channel}} for {{CARGO_BUILD_TARGET}} (features: {{features}}) ==--\n"
|
|
{{_cargo}} build {{_build_flags}}
|
|
|
|
# Install the un-packed binary, shell completions, and a manpage
|
|
install: dist-supplemental
|
|
@# Install completions
|
|
@# NOTE: bash and zsh completion requires additional setup to source a non-root dir
|
|
mkdir -p {{bash_completion_dir}} {{zsh_completion_dir}} {{ fish_completion_dir }} {{ manpage_dir }}
|
|
cp dist/{{ _pkgname }}.bash {{ bash_completion_dir }}/{{ _pkgname }}
|
|
cp dist/{{ _pkgname }}.zsh {{ zsh_completion_dir }}/_{{ _pkgname }}
|
|
cp dist/{{ _pkgname }}.fish {{ fish_completion_dir }}/{{ _pkgname }}.fish
|
|
@# Install the manpage
|
|
cp dist/{{ _pkgname }}.1.gz {{ manpage_dir }}/{{ _pkgname }}.1.gz || true
|
|
@# Install the command to ~/.cargo/bin
|
|
{{_cargo}} install --path . --force --features="{{features}}"
|
|
|
|
# Alias for `cargo run -- {{args}}`
|
|
run +args="":
|
|
{{_cargo}} run {{_build_flags}} -- {{args}}
|
|
|
|
# Remove any files installed by the `install` task (but leave any parent directories created)
|
|
uninstall:
|
|
@# TODO: Implement the proper fallback chain from `cargo install`
|
|
rm ~/.cargo/bin/{{ _pkgname }} || true
|
|
rm {{ manpage_dir }}/{{ _pkgname }}.1.gz || true
|
|
rm {{ bash_completion_dir }}/{{ _pkgname }} || true
|
|
rm {{ fish_completion_dir }}/{{ _pkgname }}.fish || true
|
|
rm {{ zsh_completion_dir }}/_{{ _pkgname }} || true
|
|
|
|
# -- Release Builds --
|
|
|
|
# Make a release build and then strip and compress the resulting binary
|
|
build-dist:
|
|
@echo "\n--== Building with {{channel}} for {{CARGO_BUILD_TARGET}} (features: {{features}}) ==--\n"
|
|
{{_cargo}} build --release {{_build_flags}}
|
|
|
|
@# Don't modify the original "cargo" output. That confuses cargo somehow.
|
|
cp "{{_rls_bin_path}}" "{{_rls_bin_path}}.stripped"
|
|
@printf "\n--== Stripping, SStripping, and Compressing With UPX ==--\n"
|
|
{{strip_bin}} {{strip_flags}} "{{_rls_bin_path}}.stripped"
|
|
@# Allow sstrip to fail because it can't be installed via "just install-deps"
|
|
{{sstrip_bin}} "{{_rls_bin_path}}.stripped" || true
|
|
@# Display the resulting file sizes so we can keep an eye on them
|
|
@# (Separate `ls` invocations are used to force the display ordering)
|
|
@printf "\n--== Final Result ==--\n"
|
|
@ls -1sh "{{_rls_bin_path}}"
|
|
@ls -1sh "{{_rls_bin_path}}.stripped"
|
|
@printf "\n"
|
|
|
|
|
|
# Build the shell completions and a manpage, and put them in `dist/`
|
|
dist-supplemental:
|
|
mkdir -p dist
|
|
@# Generate completions and store them in dist/
|
|
{{_cargo}} run --release {{_build_flags}} -- dump-completions bash > dist/{{ _pkgname }}.bash
|
|
{{_cargo}} run --release {{_build_flags}} -- dump-completions zsh > dist/{{ _pkgname }}.zsh
|
|
{{_cargo}} run --release {{_build_flags}} -- dump-completions fish > dist/{{ _pkgname }}.fish
|
|
{{_cargo}} run --release {{_build_flags}} -- dump-completions elvish > dist/{{ _pkgname }}.elvish
|
|
{{_cargo}} run --release {{_build_flags}} -- dump-completions powershell > dist/{{ _pkgname }}.powershell
|
|
@# Generate manpage and store it gzipped in dist/
|
|
@# (This comes last so the earlier calls to `cargo run` will get the compiler warnings out)
|
|
help2man -N '{{_cargo}} run {{_build_flags}} --' \
|
|
| gzip -9 > dist/{{ _pkgname }}.1.gz || true
|
|
|
|
# Call `dist-supplemental` and `build-dist` and copy the packed binary to `dist/`
|
|
dist: build-dist dist-supplemental
|
|
@# Copy the packed command to dist/
|
|
cp "{{ _rls_bin_path }}.stripped" dist/{{ _pkgname }}
|
|
|
|
# -- Dependencies --
|
|
|
|
# Use `apt-get` to install dependencies `cargo` can't (except `kcov` and `sstrip`)
|
|
install-apt-deps:
|
|
sudo apt-get install binutils help2man kcachegrind upx valgrind
|
|
|
|
# `install-rustup-deps` and then `cargo install` tools
|
|
install-cargo-deps: install-rustup-deps
|
|
@# Prevent "already installed" from causing a failure
|
|
{{_cargo}} install cargo-audit || true
|
|
{{_cargo}} install cargo-bloat || true
|
|
{{_cargo}} install cargo-deadlinks || true
|
|
{{_cargo}} install cargo-edit || true
|
|
{{_cargo}} install cargo-outdated || true
|
|
cargo +nightly install cargo-cov || true
|
|
|
|
# Install (don't update) nightly and `channel` toolchains, plus `CARGO_BUILD_TARGET`, clippy, and rustfmt
|
|
install-rustup-deps:
|
|
@# Prevent this from gleefully doing an unwanted "rustup update"
|
|
rustup toolchain list | grep -q '{{channel}}' || rustup toolchain install '{{channel}}'
|
|
rustup toolchain list | grep -q nightly || rustup toolchain install nightly
|
|
rustup target list | grep -q '{{CARGO_BUILD_TARGET}} (' || rustup target add '{{CARGO_BUILD_TARGET}}'
|
|
rustup component list | grep -q 'clippy-\S* (' || rustup component add clippy
|
|
rustup component list --toolchain nightly | grep 'rustfmt-\S* (' || rustup component add rustfmt --toolchain nightly
|
|
|
|
# Run `install-apt-deps` and `install-cargo-deps`. List what remains.
|
|
@install-deps: install-apt-deps install-cargo-deps
|
|
echo
|
|
echo "-----------------------------------------------------------"
|
|
echo "IMPORTANT: You will need to install the following manually:"
|
|
echo "-----------------------------------------------------------"
|
|
echo " * Rust-compatible kcov (http://sunjay.ca/2016/07/25/rust-code-coverage)"
|
|
echo " * sstrip (http://www.muppetlabs.com/%7Ebreadbox/software/elfkickers.html)"
|
|
|
|
# Local Variables:
|
|
# mode: makefile
|
|
# End:
|
|
|
|
# vim: set ft=make textwidth=100 colorcolumn=101 noexpandtab sw=8 sts=8 ts=8 :
|