Skip to content

Commit 33720f3

Browse files
committed
Add script to build the Debian packages
1 parent 13fd5c3 commit 33720f3

File tree

2 files changed

+247
-0
lines changed

2 files changed

+247
-0
lines changed

install/deb-build.sh

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
function usage()
6+
{
7+
echo -e "\
8+
Build the application and create the package.\n\
9+
Usage:\n\
10+
$(basename "$0") [-b bld_dir] [-p pkg_dir] [-q qmake] [-s suffix] [-v version]\n\
11+
\n\
12+
Options:\n\
13+
-b bld_dir The directory where the application will be built.\n\
14+
By default it is <source_root>/build\n\
15+
-p pkg_dir The directory where the package will be built.\n\
16+
By default this is <bld_dir>/<pkg_name>_<pkg_version>\n\
17+
-q qmake The name or full path of the qmake utility. In some\n\
18+
distributives, qmake for Qt 6 is named qmake6.\n\
19+
-s suffux The suffix that will be added to the package name after the\n\
20+
version and before the architecture type.\n\
21+
Nothing is added by default.\n\
22+
-v version Define the package version. By default version gettings from\n\
23+
the version.h file.\n\
24+
\n\
25+
It is assumed that the necessary dependencies and tools are already installed\n\
26+
in the system.\n\
27+
\n\
28+
The created package is saved in the current working directory.\
29+
" 1>&2
30+
}
31+
32+
MAKE_JOBS=$(nproc)
33+
MODE_FORCE_CLEAN=1
34+
#MODE_QUIET=1
35+
36+
SCRIPT_DIR=$(realpath "$(dirname "$0")")
37+
38+
# The package configuration must define the get_version function
39+
# and the following variables:
40+
# SOURCE_DIR
41+
# PACKAGE_NAME
42+
# PACKAGE_INSTALL_PREFIX
43+
# PACKAGE_BINS
44+
# PACKAGE_DEBIAN_DESCRIPTION
45+
source ${SCRIPT_DIR}/package.cfg
46+
47+
function echo_step()
48+
{
49+
[ -v MODE_QUIET ] && return
50+
echo -e "\n================================================================================"
51+
echo -e "$1"
52+
echo -e "================================================================================\n"
53+
}
54+
55+
# Returns 0 if there is no 'key' value in the 'list' array.
56+
# param:
57+
# key - key
58+
# list[] - list of a keys
59+
function is_uniquue () {
60+
local item
61+
62+
for item in "${@:2}"; do
63+
[[ ${item} == "${1}" ]] && return 1
64+
done
65+
66+
return 0
67+
}
68+
69+
# Returns a list of libraries on which the binaries depend
70+
# param:
71+
# bins[] - list of a binaries
72+
function get_libs () {
73+
local app
74+
local lib
75+
local lib_list
76+
77+
for app in "${@}"; do
78+
for lib in $(objdump -p "${app}" | grep NEEDED | awk '{print $2}'); do
79+
if is_uniquue "${lib}" "${lib_list[@]}"; then
80+
lib_list+=("${lib}")
81+
fi
82+
done
83+
done
84+
85+
echo "${lib_list[@]}"
86+
}
87+
88+
# Returns a list of packages on which the binaries depend
89+
# param:
90+
# arch - architecture name
91+
# bins[] - list of a binaries
92+
function get_deb_packages () {
93+
local pack
94+
local pack_list
95+
96+
for pack in $(dpkg -S $(get_libs "${@:2}") | grep "${1}" | awk -F: '{print $1}'); do
97+
if is_uniquue "${pack}" "${pack_list[@]}"; then
98+
pack_list+=("${pack}")
99+
fi
100+
done
101+
102+
echo "${pack_list[@]}"
103+
}
104+
105+
# Returns a list of packages on which the binaries depend
106+
# param:
107+
# arch - architecture name
108+
# bins[] - list of a binaries
109+
function get_deb_dependies () {
110+
local pack
111+
local dep_list
112+
local comma=0
113+
114+
for pack in $(get_deb_packages "${1}" "${@:2}"); do
115+
ver=$(dpkg-query -f='${Version}' -W "${pack}:${1}")
116+
[[ ${comma} -eq 1 ]] && dep_list+=", "
117+
dep_list+="${pack} (>= ${ver})"
118+
comma=1
119+
done
120+
121+
echo "${dep_list}"
122+
}
123+
124+
QMAKE=qmake
125+
BUILD_DIR=${SOURCE_DIR}/build
126+
PACKAGE_VERSION=$(get_version)
127+
PACKAGE_ARCH=$(dpkg --print-architecture)
128+
129+
while getopts ":b:p:q:s:v:h" options; do
130+
case "${options}" in
131+
b)
132+
BUILD_DIR=${OPTARG}
133+
;;
134+
p)
135+
PACKAGE_DIR=${OPTARG}
136+
FORCE_PACKAGE_DIR=1
137+
;;
138+
q)
139+
QMAKE=${OPTARG}
140+
;;
141+
s)
142+
PACKAGE_SUFFIX=_${OPTARG}
143+
;;
144+
v)
145+
PACKAGE_VERSION=${OPTARG}
146+
FORCE_VERSION=1
147+
;;
148+
h)
149+
usage
150+
exit 0
151+
;;
152+
*)
153+
echo -e "Error: unknown option '-${OPTARG}'.\n"
154+
usage
155+
exit 1
156+
;;
157+
esac
158+
done
159+
160+
if ! [ -v FORCE_PACKAGE_DIR ]; then
161+
PACKAGE_DIR=${BUILD_DIR}/${PACKAGE_NAME}_${PACKAGE_VERSION}
162+
fi
163+
PACKAGE_FULL_NAME="${PACKAGE_NAME}-${PACKAGE_VERSION}${PACKAGE_SUFFIX}_${PACKAGE_ARCH}"
164+
165+
echo_step "Try to build package with:\n\
166+
PACKAGE_NAME ${PACKAGE_NAME}\n\
167+
PACKAGE_SUFFIX ${PACKAGE_SUFFIX}\n\
168+
PACKAGE_VERSION ${PACKAGE_VERSION}\n\
169+
PACKAGE_ARCH ${PACKAGE_ARCH}\n\
170+
PACKAGE_FULL_NAME ${PACKAGE_FULL_NAME}\n\
171+
SOURCE_DIR ${SOURCE_DIR}\n\
172+
BUILD_DIR ${BUILD_DIR}\n\
173+
PACKAGE_DIR ${PACKAGE_DIR}\n\
174+
"
175+
176+
if [ -v MODE_FORCE_CLEAN ]; then
177+
echo_step "Clean the build tree and the package dir"
178+
if [ -d "$BUILD_DIR" ]; then
179+
echo "Remove $BUILD_DIR"
180+
rm -rf "$BUILD_DIR"
181+
fi
182+
if [ -d "$PACKAGE_DIR" ]; then
183+
echo "Remove $PACKAGE_DIR"
184+
rm -rf "$PACKAGE_DIR"
185+
fi
186+
fi
187+
188+
echo_step "Run qmake"
189+
if [ -v FORCE_VERSION ]; then
190+
QMAKE_OPTIONS="VERSION=$PACKAGE_VERSION "
191+
fi
192+
QMAKE_OPTIONS+="PREFIX=$PACKAGE_INSTALL_PREFIX $SOURCE_DIR"
193+
OLD_PWD=$PWD
194+
mkdir -p "$BUILD_DIR"
195+
cd "$BUILD_DIR"
196+
$QMAKE -r $QMAKE_OPTIONS
197+
198+
echo_step "Make translations"
199+
# At the time qmake is first called, the *.qm files do not yet exist and qmake
200+
# does not generate code to install these files. Therefore, after compiling
201+
# the *.qm files, call qmake again to generate the installation code correctly.
202+
make lrelease -j $MAKE_JOBS
203+
$QMAKE $QMAKE_OPTIONS
204+
205+
echo_step "Make application"
206+
make -j $MAKE_JOBS
207+
208+
echo_step "Copy application to the package directory"
209+
mkdir -p "$PACKAGE_DIR"/DEBIAN
210+
make install INSTALL_ROOT="$PACKAGE_DIR"
211+
cd "$OLD_PWD"
212+
213+
echo_step "Create package"
214+
echo -n "Getting depends..."
215+
for bin_obj in "${PACKAGE_BINS[@]}"; do
216+
BINS+=("$PACKAGE_DIR/$PACKAGE_INSTALL_PREFIX/${bin_obj}")
217+
done
218+
PACKAGE_DEPENDS=$(get_deb_dependies "$PACKAGE_ARCH" ${BINS[@]})
219+
echo " Done"
220+
221+
cat <<EOF > "$PACKAGE_DIR"/DEBIAN/control
222+
Package: $PACKAGE_NAME
223+
Version: $PACKAGE_VERSION
224+
Section: devel
225+
Priority: optional
226+
Depends: $PACKAGE_DEPENDS
227+
Architecture: $PACKAGE_ARCH
228+
Maintainer: Nick Egorrov <nicegorov@yandex.ru>
229+
Description: $PACKAGE_DEBIAN_DESCRIPTION
230+
Installed-Size: $(du -s "$PACKAGE_DIR" | tr -cd 0-9)
231+
EOF
232+
233+
if [ -f "${PACKAGE_FULL_NAME}.deb" ]; then
234+
echo "Remove old portable ${PACKAGE_FULL_NAME}.deb"
235+
rm "${PACKAGE_FULL_NAME}.deb"
236+
fi
237+
dpkg-deb -v --build "$PACKAGE_DIR" "${PACKAGE_FULL_NAME}.deb"

install/package.cfg

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
SOURCE_DIR=$(realpath "$SCRIPT_DIR"/../)
3+
PACKAGE_NAME=gcodeworkshop
4+
PACKAGE_INSTALL_PREFIX=/usr
5+
declare -a PACKAGE_BINS=("bin/gcodeworkshop" "bin/gcodefileserver")
6+
PACKAGE_DEBIAN_DESCRIPTION="GCodeWorkShop is a text editor for CNC programmers."
7+
8+
function get_version () {
9+
cat ${SOURCE_DIR}/gcodeshared/include/version.h | grep 'define\s*GCODEWORKSHOP_VERSION' | awk -F'"' '{print $(NF-1)}'
10+
}

0 commit comments

Comments
 (0)