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
|
+++
title = "Slackware Templates for Packages"
author = "Danilo M."
type = "tech"
date = "2026-05-11T18:51:37+02:00"
draft = true
excerpt = "slackpkg and dependency management in Slackware."
image = "/uppies/2026/05/water-02-1024x768.jpg"
tags = ["linux", "howto", "do it yourself"]
categories = ["Code", "DIY"]
+++
Slackware is great for system management because it allows you to easily modify anything by simply changing a value in a text file.
Slackware is a little less great when you need to install a package for software that has several dependencies :sweat:. It doesn't have automatic dependency management by default, so all the work falls on the user who manages the system.
The same applies to package compilation; since it doesn't manage dependencies, you also have to do everything manually during compilation, compiling the packages in the correct order to get the software you want to install.
## SlackRepo
To solve this last problem, there are software programs like [sbopkg](https://www.sbopkg.org/) that allow you to generate compilation queues to compile the packages needed for the software in the correct order.
One step further than sbopkg is **slackrepo**, software that I have already talked about in my [article about managing packages in slackware in 2026](../manage-slackware-packages-2026/), as it also allows you to compile the packages in the correct order with respect to the dependencies of each individual program, but in addition, it installs the already compiled dependencies one by one and then removes them once the compilation of the software that required them is finished.
The most interesting feature of slackrepo, however, is the ability to queue "hooks" to the execution of the program, i.e., to execute code that is not part of slackrepo to extend its functionality. In particular, in my setup, I use several hooks:
- I update the repository via git by performing the rebase each time.
- I generate the HTML files that are then inserted into the [repository](https://packages.danix.xyz/).
- I generate the .template files for those software programs that have one or more dependencies.
- I upload the files to the repository using rsync.
{{< actions url="https://packages.danix.xyz" desc="my packages" use="site" caption="My packages repository for slackware64-current" >}}
### hook "git fetch"
This hook takes care of updating the local repository by cloning Ponce's git (I'm on *-current*), then it performs the rebase and stops the execution if there are any conflicts, so I know if any of my personal packages conflict with SBo's. In case of conflicts, I can resolve them by deleting my package or the official one, depending on the situation.
```bash
function danix_gitfetch_hook
{
local upstream_branch='current'
local personal_branch='danix-current'
cd "$SR_SBREPO" || return 1
local currbranch
currbranch=$(git rev-parse --abbrev-ref HEAD)
if [ "$currbranch" != "$personal_branch" ]; then
echo "slackrepo: WARNING: SBREPO is on branch '$currbranch', expected '$personal_branch'. Skipping git update."
return 0
fi
local muck
muck=$(git status -s .)
if [ -n "$muck" ]; then
echo "slackrepo: WARNING: SBREPO has uncommitted changes. Skipping git update."
return 0
fi
echo "slackrepo: Fetching upstream SBo..."
git fetch origin || { echo "slackrepo: WARNING: git fetch failed."; return 1; }
echo "slackrepo: Rebasing $personal_branch onto origin/$upstream_branch..."
git rebase --rebase-merges -X theirs origin/"$upstream_branch" || {
echo "slackrepo: ERROR: rebase failed. Resolve conflicts in $SR_SBREPO and run 'git rebase --continue'."
return 1
}
return 0
}
```
### hook "gen web files"
This hook takes care of launching my script `gen_web_hook.sh` (visible on [my git](https://git.danix.xyz/pkgs-html-structure/tree/gen_web_hook.sh)) to generate the HTML files that will then be uploaded online to the package repository and that are used for viewing the repository online.
```bash
function gen_web_hook
{
if [ "$OPT_DRY_RUN" = 'y' ] || [ ! -s "$CHANGELOG" ]; then
return 0
fi
SR_PKGREPO="$SR_PKGREPO" /usr/local/bin/gen_web_hook.sh
local stat=$?
[ $stat -ne 0 ] && log_warning "gen_web_hook failed, status $stat"
return $stat
}
```
{{< actions url="https://git.danix.xyz" desc="my git repository" use="repo" caption="Have a look at my code on my git repo." >}}
### hook "template generator"
Here is the function that takes care of generating the .template files used by slackpkg to install the packages.
```bash
function dep_template_hook
{
local template_dir="${TEMPLATE_DIR:-/repo/templates}"
[ "$OPT_DRY_RUN" = 'y' ] && return 0
[ ${#OKLIST[@]} -eq 0 ] && return 0
mkdir -p "$template_dir" || return 1
local itemid prgnam dep depname outfile
for itemid in "${OKLIST[@]}"; do
[ -z "${FULLDEPS[$itemid]}" ] && continue
prgnam="${ITEMPRGNAM[$itemid]}"
outfile="$template_dir/${prgnam}.template"
{
for dep in ${FULLDEPS[$itemid]}; do
depname="${ITEMPRGNAM[$dep]}"
printf '%s\n' "${depname:-$dep}"
done
printf '%s\n' "$prgnam"
} > "$outfile"
log_normal "dep_template_hook: wrote $outfile"
done
return 0
}
```
### hook "rsync push"
Finally, the hook that takes care of uploading the modified files to my online repository:
```bash
function rsync_push_hook
{
# RSYNC_TARGET/RSYNC_EXCLUDES are unset by slackrepo after config sourcing;
# use hardcoded values here since they can't be passed via SR_ prefix mechanism.
local rsync_target='<SERVER_RSYNC>'
local rsync_excludes='<FILES_ESCLUSI.txt>'
local rsync_password_file='<PASSWORD_SERVER_RSYNC>'
if [ "$OPT_DRY_RUN" = 'y' ] || [ ! -s "$CHANGELOG" ]; then
return 0
fi
local rsync_bin
rsync_bin=$(which rsync 2>/dev/null)
if [ ! -x "$rsync_bin" ]; then
log_warning "rsync not found, skipping rsync_push_hook"
return 1
fi
local args=( -havz --delete-after )
[ -n "$rsync_excludes" ] && [ -f "$rsync_excludes" ] && \
args+=( --exclude-from="$rsync_excludes" )
[ -f "$rsync_password_file" ] && args+=( --password-file="$rsync_password_file" )
log_normal "Pushing packages to $rsync_target ..."
"$rsync_bin" "${args[@]}" "$SR_PKGREPO"/ "$rsync_target"
local rsyncstat=$?
if [ "$rsyncstat" != 0 ]; then
log_warning "rsync_push_hook failed, status $rsyncstat"
return 1
fi
log_normal "rsync push complete."
return 0
}
```
## The .template files and slackpkg
At the end of the compilation of software that has some dependencies, in my repository, the file `<package_name>.template` will be generated, which I can copy into `/etc/slackpkg/templates` and call with:
```bash
slackpkg install-template package_name
```
and slackpkg will automatically prompt me to install all the dependencies listed in the template, effectively simplifying dependency management.
An example of a template, directly from my repository, is [waybar.template](https://packages.danix.xyz/templates/waybar.template):
```
date
jsoncpp
Catch2
spdlog
waybar
```
I hope this article can be useful to someone, even if only as a starting point to simplify things a bit :wink:
{{< actions url="/it/is/here/" desc="Contact me" use="site" caption="If you have any comments, leave a message." >}}
|