Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
207 lines (166 loc) ยท 8.19 KB
/
Copy pathMakefile
File metadata and controls
207 lines (166 loc) ยท 8.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
SHELL = /bin/bash
# Reuse the same shell for all commands in all recipes
.ONESHELL:
# Always error out early on any non zero result and echo all commands
.SHELLFLAGS = -cex
# Do not echo recipes
.SILENT:
# By default, we don't set a target and use the current default toolchain.
ifneq ($(CARGO_TARGET),)
export CARGO_BUILD_TARGET := $(CARGO_TARGET)
# CAUTION: Do not use tabs to indent here, because it changes the scoping to the local recipe
# and doesn't make the variable globally available
TARGET_FLAG := --target=$(CARGO_TARGET)
endif
# Defines VERSION from the git history. Used by the binaries to build their own version string.
# To satisfy semver we fall back to `0.0.0` if there is no matching tag
VERSION ?= $(shell (git describe --tags --match "v*.*.*" 2>/dev/null || echo "v0.0.0") | sed 's/\-/~/g')
# Strip the first character, which is usually "v" to allow usage in semver contexts
VERSION_TRIMMED := $(shell V="$(VERSION)" && echo $${V:1})
ifneq ($(CARGO_LOCKED),)
# CAUTION: Do not use tabs to indent here, because it changes the scoping to the local recipe
# and doesn't make the variable globally available
LOCKED_FLAG := --locked
endif
### Simple cargo wrappers ###
all: build
# By setting TARGET (or CARGO_BUILD_TARGET directly) to a Rust target triple, the following commands
# can cross compile.
# Run quick sanity checks
.PHONY: check
check:
cargo +nightly fmt --check
cargo clippy $(LOCKED_FLAG) --all-features -- -D warnings
# Run cargo deny
.PHONY: deny
deny:
cargo deny $(LOCKED_FLAG) --all-features check
# Run tests
.PHONY: test
test:
cargo test $(LOCKED_FLAG) --all-features
# Build the normal dev/debug profile
.PHONY: build
build:
VERSION="$(VERSION)" cargo build $(LOCKED_FLAG)
.PHONY: clean
clean:
cargo clean $(LOCKED_FLAG)
### Release build and packaging ###
# Where to put the packages
PACKAGE_DIR := target/package
# Output dir of all artifacts, including the manually generated
TARGET_DIR := target/$(CARGO_TARGET)/release
# Define the command to build the release binaries based on configuration
RELEASE_BUILD_CMD := cargo build $(TARGET_FLAG)
# If glibc version is given, use zigbuild to link against specific libc
ifneq ($(GLIBC_VERSION),)
# Zigbuild requires a specified target
ifeq ($(CARGO_TARGET),)
$(error GLIBC_VERSION requires CARGO_TARGET which was not provided)
endif
RELEASE_BUILD_CMD := cargo zigbuild --target=$(CARGO_TARGET).$(GLIBC_VERSION)
endif
# We want to include the full debug info so it can be split off.
# We also force a build ID as zigs linker does not emit one by default.
RELEASE_BUILD_CMD := VERSION="$(VERSION)" $(RELEASE_BUILD_CMD) \
--release --locked --config='profile.release.debug = "full"' \
--config='build.rustflags = ["-Clink-arg=-Wl,--build-id=sha1"]'
# Build release binaries and package them.
# In addition to all environment variables accepted by cargo, this target reads the following:
# * TARGET: Define a build target for cross compiling by giving a Rust target triple. Requires
# all the necessary tools (compilers, linkers, ...) to be installed
# * BIN_UTIL_PREFIX: The prefix to put before binutil commands when cross compiling (like strip) to
# call the correct one.
# * GLIBC_VERSION: The glibc version to link against when applicable. This requires `cargo-zigbuild`
# and the zig compiler to be installed and available.
.PHONY: package
package:
# Patch mgmtds Cargo.toml to depend on linked libc version if specified
if [ "$(GLIBC_VERSION)" != "" ]; then
# We don't want to auto modify files in a devs repo, so restore the original file on exit
# (even works on erroring out).
function clean_up() {
mv mgmtd/Cargo.toml.orig mgmtd/Cargo.toml 2> /dev/null
}
trap clean_up EXIT
cp mgmtd/Cargo.toml mgmtd/Cargo.toml.orig
# Patch deb specs
sed -i 's/depends = "libbeegfs-license/depends = "libc6 (>= $(GLIBC_VERSION)), libbeegfs-license/' mgmtd/Cargo.toml
grep -q 'libc6 (>=' mgmtd/Cargo.toml || { echo "ERROR: DEB libc6 patch failed"; exit 1; }
# Patch rpm specs
sed -i 's/libbeegfs-license = ">=/glibc = ">= $(GLIBC_VERSION)"\nlibbeegfs-license = ">=/' mgmtd/Cargo.toml
grep -q 'glibc = ">=' mgmtd/Cargo.toml || { echo "ERROR: RPM glibc patch failed"; exit 1; }
fi
# Build thirdparty license summary
mkdir -p $(TARGET_DIR)
cargo about generate about.hbs --all-features -o $(TARGET_DIR)/thirdparty-licenses.html
# Build after cleaning the binary generating crates to prevent accidental reuse of already
# stripped binaries.
cargo clean --locked $(TARGET_FLAG) --release -p mgmtd
$(RELEASE_BUILD_CMD)
# Split the debug info off into its own file, which the debuginfo package ships.
$(BIN_UTIL_PREFIX)objcopy --only-keep-debug \
$(TARGET_DIR)/beegfs-mgmtd $(TARGET_DIR)/beegfs-mgmtd.debug
$(BIN_UTIL_PREFIX)strip -s $(TARGET_DIR)/beegfs-mgmtd
# Point the stripped binary at the debug file, required for gdb and Rust backtrace to find it.
# objcopy stores only the base name in the link, so $(TARGET_DIR) does not leak into the binary.
$(BIN_UTIL_PREFIX)objcopy --add-gnu-debuglink=$(TARGET_DIR)/beegfs-mgmtd.debug \
$(TARGET_DIR)/beegfs-mgmtd
# Build packages
# These don't respect CARGO_BUILD_TARGET, so we need to add --target manually using $(TARGET_FLAG)
cargo deb --locked $(TARGET_FLAG) --no-build -p mgmtd -o $(PACKAGE_DIR)/ \
--deb-version="20:$(VERSION_TRIMMED)"
cargo deb --locked $(TARGET_FLAG) --no-build -p mgmtd -o $(PACKAGE_DIR)/ --variant=debug \
--deb-version="20:$(VERSION_TRIMMED)"
# We don't want the epoch in the file names
find $(PACKAGE_DIR) -name "*_20:*.deb" -exec bash -c 'mv "$$1" $$(echo "$$1" | sed "s/_20:/_/g")' bash {} \;
cargo generate-rpm $(TARGET_FLAG) -p mgmtd -o $(PACKAGE_DIR)/ \
--set-metadata='version="$(VERSION_TRIMMED)"' \
--set-metadata='epoch=20' \
--set-metadata='provides={"beegfs-mgmtd" = "= $(VERSION_TRIMMED)"}'
cargo generate-rpm $(TARGET_FLAG) -p mgmtd -o $(PACKAGE_DIR)/ --variant=debug \
--set-metadata='version="$(VERSION_TRIMMED)"' \
--set-metadata='epoch=20' \
--set-metadata='provides={"beegfs-mgmtd" = "= $(VERSION_TRIMMED)"}'
# Replace tilde in package filename with hypens.
# Github release action and api substitutes tilde (~) with dot (.) in file names when uploaded to Github packages.
find $(PACKAGE_DIR)/ -type f \( -name "*~*.deb" -o -name "*~*.rpm" \) -exec bash -c 'mv "$$1" "$${1//\~/-}"' _ {} \;
.PHONY: clean-package
clean-package:
rm -rf $(PACKAGE_DIR)
### Utilities ###
COVERAGE_DIR=$(shell echo $$(pwd)/target/coverage)
# Generates test coverage of the code excluding doctests and prints a report
.PHONY: coverage
coverage:
# Ensure the required llvm-tools are installed - these must be exactly the ones required.
# See https://doc.rust-lang.org/rustc/instrument-coverage.html
rustup component add llvm-tools
# Figure out the path to the installed llvm binaries for the local machine
LLVM=$$(rustc --print sysroot)/lib/rustlib/$$(rustc -Vv | grep host | awk '{print $$2}')/bin
rm -f $(COVERAGE_DIR)/*
export RUSTFLAGS="-C instrument-coverage"
export LLVM_PROFILE_FILE="$(COVERAGE_DIR)/%m_%p.profraw"
# Run tests with instrumentation. Then print a summary of the runs to extract the test binaries.
cargo test $(LOCKED_FLAG) --all-features --tests
TEST_BINARIES="$$( \
for f in $$(cargo test $(LOCKED_FLAG) --all-features --tests --no-run 2>&1 | grep -E -o "target\/.*[^)]"); \
do \
printf "%s %s " -object $$f; \
done \
)"
$$LLVM/llvm-profdata merge -sparse $(COVERAGE_DIR)/*.profraw -o $(COVERAGE_DIR)/merged.profdata
git ls-files "*.rs" | xargs $$LLVM/llvm-cov report $$TEST_BINARIES -instr-profile=$(COVERAGE_DIR)/merged.profdata -sources
# Quickly installs the newest versions most of the tools and components used by this repo. Requires
# `rustup` to be installed. You can install that by either going to `https://rustup.rs` and use the
# script there or install the version from your distros package manager if available.
#
# IMPORTANT: Only installs the tools needed for a local, native build. Not sufficient for cross
# compiling or using special C compilers like `musl`.
.PHONY: install-tools
install-tools:
rustup update
rustup toolchain install nightly
rustup component add --toolchain nightly rustfmt
cargo install --locked cargo-deny@0.18.9 cargo-about@0.7.1 cargo-generate-rpm@0.18.1 cargo-deb@3.6.0