cross-cleaner
LOW
maintainer nekiplay
1 votes
scanned 2026-10-17 07:17:15.137327
Why flagged
Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.
Triggered rules
Low
Few votes, recently uploaded
zero_votes_recent
Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.
PKGBUILD
1
# Maintainer: Roman <roman at users.noreply.github.com>
2
# Based on upstream packaging by the Cross-Cleaner authors.
3
#
4
# NOTE: the license in this repository (the packaging files) is 0BSD, per the
5
# AUR submission guidelines. The packaged software itself is GPL-3.0-or-later,
6
# which is what the license= field below refers to.
7
8
# Built from source with the distribution package's own flags, mirroring the
9
# reasoning in packaging/linux/nfpm.yaml: the package manager owns the installed
10
# version, so every binary is compiled with --no-default-features and the
11
# self-update path is not part of the build at all. `crates/desktop`,
12
# `crates/tui` and `crates/cli` each document this in their own Cargo.toml.
13
14
pkgname=cross-cleaner
15
# The tag archive, not a `git+` source: a VCS source always tracks the default
16
# branch, so every user would build whatever main happened to contain at that
17
# moment instead of the release that was actually published. With an archive,
18
# the version below names exactly one commit.
19
#
20
# The four lines between the markers are the whole of what
21
# .github/workflows/aur.yml rewrites, and the block deliberately contains
22
# nothing else -- regenerating it must not delete the explanation around it.
23
# ---AUR-VERSION-BEGIN---
24
pkgver=2.0.4.4
25
pkgrel=1.1
26
source=("cross-cleaner-v${pkgver}.tar.gz::https://github.com/Cross-Cleaner/Cross-Cleaner/archive/refs/tags/v${pkgver}.tar.gz")
27
sha256sums=('86e98f694c97f518e573c267add2873fc91a751b7905a4a374d326b35b745af5')
28
# ---AUR-VERSION-END---
29
pkgdesc='Addon-style system cleanup tool that removes temporary files, cache and other system junk'
30
arch=('x86_64' 'aarch64')
31
url='https://github.com/Cross-Cleaner/Cross-Cleaner'
32
license=('GPL-3.0-or-later')
33
# ~636 crates in the lock file, all of them needed by the window app. Without a
34
# lower bound the resolver picks a version the sources have never been built
35
# against; with one, an Arch update that breaks the build is a visible bisect
36
# rather than a silent surprise.
37
depends=('gcc-libs'
38
'alsa-lib'
39
'mesa'
40
'libdrm'
41
'wayland'
42
'wayland-protocols'
43
'libx11'
44
'libxcursor'
45
'libxrandr'
46
'libxi'
47
'libxinerama'
48
'libxrender'
49
'libxext'
50
'libxkbcommon'
51
'libxkbcommon-x11'
52
'fontconfig')
53
# rust, cargo, git, pkgconf and make are base-devel members and so are not
54
# listed here; they are named above only to record why the build needs them.
55
makedepends=('icoutils'
56
'desktop-file-utils'
57
'appstream'
58
# alsa-sys, khronos-egl and wayland-sys all resolve their native
59
# libraries through pkg-config at compile time, so the -dev side of
60
# each has to be present while building, not only afterwards.
61
'alsa-lib'
62
'mesa'
63
'wayland')
64
optdepends=('gtk-update-icon-cache: update the icon cache without restarting the session')
65
66
# No pkgver() function. The version is pinned to one git tag by the source line
67
# above, so there is nothing left to compute at build time -- and a pkgver()
68
# function is exactly what made this package unusable as an AUR package before:
69
# it resolved against whatever the clone happened to contain, which drifted
70
# from the pkgver= line the AUR web interface displays.
71
72
# GitHub's tag archives extract into a directory named after the tag without
73
# its leading `v`. Set once here so prepare(), build() and package() all agree.
74
_srcdir_tag="Cross-Cleaner-${pkgver}"
75
76
prepare() {
77
cd "$srcdir/$_srcdir_tag"
78
79
# crates/winicon/assets/icon.ico holds a single 96px frame, so this is a
80
# straight extraction rather than a resize. Unlike the AppImage build, which
81
# upscales to 128 and 256 with ImageMagick, nothing is invented here: the
82
# one real size is installed as-is. Dropping a >=512px master PNG into
83
# crates/winicon/assets is what makes the larger hicolor slots worth filling.
84
#
85
# Extraction goes to a throwaway directory rather than straight to
86
# $srcdir/icons: prepare() has to be idempotent, because makepkg reuses an
87
# existing $srcdir whenever only the PKGBUILD changed. Writing the frame
88
# next to its destination and then `mv`-ing it onto itself fails the second
89
# time round, with "mv: ... and ... are the same file".
90
local extract
91
extract=$(mktemp -d)
92
icotool -x -o "$extract" crates/winicon/assets/icon.ico
93
# icotool names its output after the source and the frame's geometry, so
94
# glob rather than hardcode the name.
95
local frame
96
frame=$(find "$extract" -name '*.png' -print -quit)
97
if [[ -z "$frame" ]]; then
98
rm -rf "$extract"
99
printf 'icotool extracted no frame from icon.ico\n' >&2
100
return 1
101
fi
102
install -Dm644 "$frame" "$srcdir/icons/cross-cleaner.png"
103
rm -rf "$extract"
104
105
# Make the binaries report this package's version.
106
#
107
# `--version` comes from CARGO_PKG_VERSION, and cargo takes that from the
108
# `version` field of each crate's [package] table. It is not overridable
109
# from the environment -- exporting CARGO_PKG_VERSION before the build
110
# changes nothing, verified on cargo 1.98.
111
#
112
# The values in the tree are whatever the release happened to leave there,
113
# and they disagree with the tag: crates/*/Cargo.toml says 2.0.1 while the
114
# tag this package is built from is 2.0.4.2.5. The cause is upstream --
115
# dev_build.yml rewrote every Cargo.toml back to a hardcoded 2.0.1 on each
116
# push while release.yml wrote the real version, so the two ping-ponged and
117
# each tag inherited whichever it landed on (v2.0.4.2.4 reports 2.0.1,
118
# v2.0.4.2.5 reports 2.0.4).
119
#
120
# Rewriting only the [package] table, not every `version = ` line: a
121
# dependency declared as
122
# [dependencies.foo]
123
# version = "1"
124
# is legal TOML and a plain /^version = / would rewrite that too, silently
125
# changing which version of a dependency is required.
126
# The release version has four components (2.0.4.2.5) but a cargo package
127
# version is semver: exactly three numeric components, optionally followed
128
# by -pre or +build. Passing four in is a hard parse error, which is why
129
# release.yml does the same `cut -d. -f1-3`. So the application reports
130
# 2.0.4 for a 2.0.4.2.5 package: the fourth component has no representation
131
# inside the binary and cannot be recovered from one.
132
local crate_version
133
crate_version=$(printf '%s' "$pkgver" | cut -d. -f1-3)
134
if ! printf '%s' "$crate_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
135
printf 'pkgver %s does not reduce to a semver version (%s)\n' "$pkgver" "$crate_version" >&2
136
return 1
137
fi
138
139
find "$srcdir/$_srcdir_tag" -name Cargo.toml -print0 |
140
while IFS= read -r -d '' manifest; do
141
awk -v v="$crate_version" '
142
/^\[package\]/ { inpkg = 1 }
143
/^\[/ && !/^\[package\]/ { inpkg = 0 }
144
inpkg && /^version[[:space:]]*=/ && !seen {
145
print "version = \"" v "\""
146
seen = 1
147
next
148
}
149
{ print }
150
' "$manifest" > "$manifest.tmp" && mv "$manifest.tmp" "$manifest"
151
done
152
153
# The three components alone are not the release version, so the string the
154
# binaries print is set outright. clap takes it from CARGO_PKG_VERSION when
155
# the attribute says a bare `version,`, and that can only ever hold three
156
# semver numbers. Replacing the bare form with an explicit literal is what
157
# makes `cross-cleaner-cli --version` read 2.0.4.2.5 for a 2.0.4.2.5
158
# package.
159
#
160
# The patch is verified rather than assumed: if upstream moves the clap
161
# attribute, sed would quietly match nothing and the binaries would fall
162
# back to reporting 2.0.4 with no error anywhere. Each file is checked
163
# after the substitution, so that regression fails the build loudly.
164
#
165
# Two shapes have to be covered, and both appear upstream today: a bare
166
# `version,` line inside a multi-line #[command(...)] (cli/src/args.rs) and
167
# `#[command(version, about, ...)]` on one line (tui and desktop).
168
local manifest
169
for manifest in \
170
crates/cli/src/args.rs \
171
crates/tui/src/main.rs \
172
crates/desktop/src/main.rs
173
do
174
[[ -f "$srcdir/$_srcdir_tag/$manifest" ]] || {
175
printf 'expected %s to exist; upstream moved it\n' "$manifest" >&2
176
return 1
177
}
178
sed -i \
179
-e "s/^\([[:space:]]*\)version,$/\1version = \"$pkgver\",/" \
180
-e "s/#\[command(version, /#[command(version = \"$pkgver\", /" \
181
"$srcdir/$_srcdir_tag/$manifest"
182
grep -q "version = \"$pkgver\"," "$srcdir/$_srcdir_tag/$manifest" || {
183
printf 'could not set the version string in %s\n' "$manifest" >&2
184
return 1
185
}
186
done
187
188
# packaging/linux/cross-cleaner.appdata.xml carries %%VERSION%% and %%DATE%%
189
# for the release workflow to fill in. The date cannot come from the
190
# commit here: the source is a tag archive, not a git checkout, so there is
191
# no .git to ask. The build date is used instead, which is the only moment
192
# this package knows about.
193
local release_date
194
release_date=$(date -u +%Y-%m-%d)
195
sed -e "s/%%VERSION%%/$pkgver/g" \
196
-e "s/%%DATE%%/$release_date/g" \
197
packaging/linux/cross-cleaner.appdata.xml > "$srcdir/cross-cleaner.appdata.xml"
198
if grep -q '%%' "$srcdir/cross-cleaner.appdata.xml"; then
199
printf 'unsubstituted placeholder left in the AppStream metadata\n' >&2
200
return 1
201
fi
202
203
desktop-file-validate packaging/linux/cross-cleaner.desktop
204
desktop-file-validate packaging/linux/cross-cleaner-tui.desktop
205
# Non-fatal, matching the release workflow: a metadata lint should be
206
# visible without being able to block an install.
207
appstreamcli validate --pedantic "$srcdir/cross-cleaner.appdata.xml" || :
208
}
209
210
# One cargo invocation per binary, as .github/workflows/release.yml does it.
211
build() {
212
cd "$srcdir/$_srcdir_tag"
213
214
# Unset the compiler flags makepkg exports, and tell rustc not to read a
215
# rustflags setting from anywhere. Arch's CFLAGS
216
#
217
# -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions
218
# -Wp,-D_FORTIFY_SOURCE=3 -fstack-clash-protection -fcf-protection ...
219
#
220
# are handed to the `cc` crate, which passes them straight to the C compiler
221
# that ring's build.rs uses for its crypto core. At least one of them makes
222
# that build produce objects whose symbols the final link cannot resolve,
223
# and the whole binary then fails to link:
224
#
225
# ld.lld: error: undefined symbol: ring_core_0_17_14__x25519_sc_mask
226
# ld.lld: error: undefined symbol: ring_core_0_17_14__aes_nohw_set_encrypt_key
227
# ... every symbol of ring's native core
228
#
229
# ring's own build.rs output is correct throughout -- it emits both
230
# `rustc-link-lib=static=ring_core_0_17_14_` and `rustc-link-search`, and
231
# the archive really does contain all 157 symbols. What breaks is the link
232
# step, which sees the `-L` search path but not the `-l`.
233
#
234
# Verified by bisection on a reduced crate (ureq -> rustls -> ring): the
235
# build passes with makepkg's CFLAGS removed and fails with them set, while
236
# LTO, RUSTFLAGS, LDFLAGS and the rest of makepkg's environment are all
237
# neutral. Note this is NOT upstream's fat LTO profile causing it -- the
238
# release profile in Cargo.toml builds these binaries fine on Ubuntu.
239
#
240
# Clearing the variables is also the more correct behaviour for a package:
241
# these are the distribution's hardening flags for distribution-built
242
# software, not something a third-party package should silently inherit.
243
unset CFLAGS CXXFLAGS CPPFLAGS FCFLAGS FFLAGS ARFLAGS LDFLAGS LTOFLAGS
244
unset RUSTFLAGS CARGO_ENCODED_RUSTFLAGS
245
246
# No --locked. The Cargo.lock committed in the release tags is stale with
247
# respect to the manifests in those same tags: tag v2.0.4.2.5 declares
248
# version = "2.0.4" in crates/*/Cargo.toml while its Cargo.lock still records
249
# the workspace crates at 2.0.1, so cargo insists on rewriting the lock and
250
# --locked aborts the build before anything is compiled.
251
#
252
# The thing --locked was here to protect still holds without it. Cargo.lock
253
# already pins gpu-allocator to a concrete git revision through
254
# Cargo.toml's [patch.crates-io], and cargo does not revisit entries that
255
# are present and still satisfy the manifests -- the only edits it makes are
256
# the workspace version numbers above. Upstream's own release builds do not
257
# pass --locked either.
258
cargo build --release --no-default-features -p desktop
259
cargo build --release --no-default-features -p tui
260
cargo build --release --no-default-features -p cli
261
}
262
263
# No check() on purpose. The workspace release profile sets panic = "abort",
264
# which is not what the test harness wants, and the android crate in the
265
# workspace needs the NDK to build at all. The upstream CI does not run
266
# `cargo test` either, so there is no suite this package would be able to run
267
# that CI is not already running.
268
package() {
269
cd "$srcdir/$_srcdir_tag"
270
271
# cargo names each binary after its package. They are renamed to
272
# hyphenated commands so the desktop entries and the AppImage agree with
273
# this package: Exec lines and shell completions must not change per release.
274
install -Dm755 target/release/desktop "$pkgdir/usr/bin/cross-cleaner"
275
install -Dm755 target/release/tui "$pkgdir/usr/bin/cross-cleaner-tui"
276
install -Dm755 target/release/cli "$pkgdir/usr/bin/cross-cleaner-cli"
277
278
install -Dm644 packaging/linux/cross-cleaner.desktop \
279
"$pkgdir/usr/share/applications/cross-cleaner.desktop"
280
install -Dm644 packaging/linux/cross-cleaner-tui.desktop \
281
"$pkgdir/usr/share/applications/cross-cleaner-tui.desktop"
282
283
install -Dm644 "$srcdir/icons/cross-cleaner.png" \
284
"$pkgdir/usr/share/icons/hicolor/96x96/apps/cross-cleaner.png"
285
286
install -Dm644 "$srcdir/cross-cleaner.appdata.xml" \
287
"$pkgdir/usr/share/metainfo/cross-cleaner.appdata.xml"
288
}
289
Changes since previous scan
--- PKGBUILD @ 2026-10-17 00:21+++ PKGBUILD @ 2026-10-17 07:17@@ -22,7 +22,7 @@ # nothing else -- regenerating it must not delete the explanation around it. # ---AUR-VERSION-BEGIN--- pkgver=2.0.4.4-pkgrel=1+pkgrel=1.1 source=("cross-cleaner-v${pkgver}.tar.gz::https://github.com/Cross-Cleaner/Cross-Cleaner/archive/refs/tags/v${pkgver}.tar.gz") sha256sums=('86e98f694c97f518e573c267add2873fc91a751b7905a4a374d326b35b745af5') # ---AUR-VERSION-END---Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-10-17 07:17:15 | Low | 1 |
| 2026-10-17 00:21:55 | Clean | 2 |
| 2026-10-16 15:16:11 | Low | 1 |
| 2026-10-14 00:06:47 | Clean | 2 |
| 2026-10-13 11:16:23 | Low | 1 |
| 2026-10-11 00:26:05 | Clean | 2 |
| 2026-10-10 14:14:18 | Low | 1 |
| 2026-10-10 10:13:47 | Low | 1 |
| 2026-10-10 08:13:38 | Low | 1 |