]> sigrok.org Git - sigrok-util.git/blame - cross-compile/appimage/contrib/functions.sh
sigrok-cross-mingw: Optionally emit progress messages.
[sigrok-util.git] / cross-compile / appimage / contrib / functions.sh
CommitLineData
1f369f0c
UH
1# This file is supposed to be sourced by each Recipe
2# that wants to use the functions contained herein
3# like so:
ca369dfa 4# wget -q https://github.com/AppImage/AppImages/raw/${PKG2AICOMMIT}/functions.sh -O ./functions.sh
1f369f0c
UH
5# . ./functions.sh
6
7# RECIPE=$(realpath "$0")
8
ca369dfa
UH
9# Specify a certain commit if you do not want to use master
10# by using:
11# export PKG2AICOMMIT=<git sha>
12if [ -z "$PKG2AICOMMIT" ] ; then
13 PKG2AICOMMIT=master
14fi
15
1f369f0c
UH
16# Options for apt-get to use local files rather than the system ones
17OPTIONS="-o Debug::NoLocking=1
18-o APT::Cache-Limit=125829120
19-o Dir::Etc::sourcelist=./sources.list
20-o Dir::State=./tmp
21-o Dir::Cache=./tmp
22-o Dir::State::status=./status
23-o Dir::Etc::sourceparts=-
24-o APT::Get::List-Cleanup=0
25-o APT::Get::AllowUnauthenticated=1
26-o Debug::pkgProblemResolver=true
27-o Debug::pkgDepCache::AutoInstall=true
28-o APT::Install-Recommends=0
29-o APT::Install-Suggests=0
30"
31
af040d31
UH
32# Detect if we are running inside Docker
33grep docker /proc/1/cgroup >/dev/null && export DOCKER_BUILD=1 || true
34
8c7df980
UH
35# Detect system architecture to know which binaries of AppImage tools
36# should be downloaded and used.
37case "$(uname -i)" in
38 x86_64|amd64)
39# echo "x86-64 system architecture"
40 SYSTEM_ARCH="x86_64";;
41 i?86)
42# echo "x86 system architecture"
43 SYSTEM_ARCH="i686";;
44# arm*)
45# echo "ARM system architecture"
46# SYSTEM_ARCH="";;
ca369dfa 47 unknown|AuthenticAMD|GenuineIntel)
8c7df980
UH
48# uname -i not answer on debian, then:
49 case "$(uname -m)" in
50 x86_64|amd64)
51# echo "x86-64 system architecture"
52 SYSTEM_ARCH="x86_64";;
53 i?86)
54# echo "x86 system architecture"
55 SYSTEM_ARCH="i686";;
56 esac ;;
57 *)
58 echo "Unsupported system architecture"
59 exit 1;;
60esac
61
1f369f0c
UH
62# Either get the file from remote or from a static place.
63# critical for builds without network access like in Open Build Service
64cat_file_from_url()
65{
66 cat_excludelist="wget -q $1 -O -"
67 [ -e "$STATIC_FILES/${1##*/}" ] && cat_excludelist="cat $STATIC_FILES/${1##*/}"
68 $cat_excludelist
69}
70
71git_pull_rebase_helper()
72{
73 git reset --hard HEAD
74 git pull
75}
76
77# Patch /usr to ././ in ./usr
78# to make the contents of usr/ relocateable
79# (this requires us to cd ./usr before running the application; AppRun does that)
80patch_usr()
81{
82 find usr/ -type f -executable -exec sed -i -e "s|/usr|././|g" {} \;
83}
84
85# Download AppRun and make it executable
86get_apprun()
87{
8c7df980
UH
88 TARGET_ARCH=${ARCH:-$SYSTEM_ARCH}
89 wget -c https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-${TARGET_ARCH} -O AppRun
1f369f0c
UH
90 chmod a+x AppRun
91}
92
93# Copy the library dependencies of all exectuable files in the current directory
94# (it can be beneficial to run this multiple times)
95copy_deps()
96{
97 PWD=$(readlink -f .)
98 FILES=$(find . -type f -executable -or -name *.so.* -or -name *.so | sort | uniq )
99 for FILE in $FILES ; do
100 ldd "${FILE}" | grep "=>" | awk '{print $3}' | xargs -I '{}' echo '{}' >> DEPSFILE
101 done
102 DEPS=$(cat DEPSFILE | sort | uniq)
103 for FILE in $DEPS ; do
104 if [ -e $FILE ] && [[ $(readlink -f $FILE)/ != $PWD/* ]] ; then
105 cp -v --parents -rfL $FILE ./ || true
106 fi
107 done
108 rm -f DEPSFILE
109}
110
111# Move ./lib/ tree to ./usr/lib/
112move_lib()
113{
114 mkdir -p ./usr/lib ./lib && find ./lib/ -exec cp -v --parents -rfL {} ./usr/ \; && rm -rf ./lib
115 mkdir -p ./usr/lib ./lib64 && find ./lib64/ -exec cp -v --parents -rfL {} ./usr/ \; && rm -rf ./lib64
116}
117
118# Delete blacklisted files
119delete_blacklisted()
120{
af040d31 121 BLACKLISTED_FILES=$(cat_file_from_url https://github.com/AppImage/pkg2appimage/raw/${PKG2AICOMMIT}/excludelist | sed 's|#.*||g')
1f369f0c
UH
122 echo $BLACKLISTED_FILES
123 for FILE in $BLACKLISTED_FILES ; do
8c7df980
UH
124 FILES="$(find . -name "${FILE}" -not -path "./usr/optional/*")"
125 for FOUND in $FILES ; do
126 rm -vf "$FOUND" "$(readlink -f "$FOUND")"
127 done
1f369f0c 128 done
8c7df980 129
1f369f0c
UH
130 # Do not bundle developer stuff
131 rm -rf usr/include || true
132 rm -rf usr/lib/cmake || true
133 rm -rf usr/lib/pkgconfig || true
134 find . -name '*.la' | xargs -i rm {}
135}
136
137# Echo highest glibc version needed by the executable files in the current directory
138glibc_needed()
139{
ca369dfa
UH
140 find . -name *.so -or -name *.so.* -or -type f -executable -exec strings {} \; | grep ^GLIBC_2 | sed s/GLIBC_//g | sort --version-sort | uniq | tail -n 1
141 # find . -name *.so -or -name *.so.* -or -type f -executable -exec readelf -s '{}' 2>/dev/null \; | sed -n 's/.*@GLIBC_//p'| awk '{print $1}' | sort --version-sort | tail -n 1
1f369f0c
UH
142}
143# Add desktop integration
144# Usage: get_desktopintegration name_of_desktop_file_and_exectuable
145get_desktopintegration()
146{
af040d31
UH
147 # REALBIN=$(grep -o "^Exec=.*" *.desktop | sed -e 's|Exec=||g' | cut -d " " -f 1 | head -n 1)
148 # cat_file_from_url https://raw.githubusercontent.com/AppImage/AppImageKit/deprecated/AppImageAssistant/desktopintegration > ./usr/bin/$REALBIN.wrapper
149 # chmod a+x ./usr/bin/$REALBIN.wrapper
150 echo "The desktopintegration script is deprecated. Please advise users to use https://github.com/AppImage/appimaged instead."
151 # sed -i -e "s|^Exec=$REALBIN|Exec=$REALBIN.wrapper|g" $1.desktop
1f369f0c
UH
152}
153
154# Generate AppImage; this expects $ARCH, $APP and $VERSION to be set
155generate_appimage()
156{
8c7df980
UH
157 # Download AppImageAssistant
158 URL="https://github.com/AppImage/AppImageKit/releases/download/6/AppImageAssistant_6-${SYSTEM_ARCH}.AppImage"
159 wget -c "$URL" -O AppImageAssistant
160 chmod a+x ./AppImageAssistant
161
1f369f0c
UH
162 # if [[ "$RECIPE" == *ecipe ]] ; then
163 # echo "#!/bin/bash -ex" > ./$APP.AppDir/Recipe
164 # echo "# This recipe was used to generate this AppImage." >> ./$APP.AppDir/Recipe
165 # echo "# See http://appimage.org for more information." >> ./$APP.AppDir/Recipe
166 # echo "" >> ./$APP.AppDir/Recipe
167 # cat $RECIPE >> ./$APP.AppDir/Recipe
168 # fi
169 #
170 # Detect the architecture of what we are packaging.
171 # The main binary could be a script, so let's use a .so library
172 BIN=$(find . -name *.so* -type f | head -n 1)
173 INFO=$(file "$BIN")
174 if [ -z $ARCH ] ; then
175 if [[ $INFO == *"x86-64"* ]] ; then
176 ARCH=x86_64
177 elif [[ $INFO == *"i686"* ]] ; then
178 ARCH=i686
179 elif [[ $INFO == *"armv6l"* ]] ; then
180 ARCH=armhf
181 else
182 echo "Could not automatically detect the architecture."
183 echo "Please set the \$ARCH environment variable."
184 exit 1
185 fi
186 fi
8c7df980 187
1f369f0c 188 mkdir -p ../out || true
8c7df980 189 rm ../out/$APP"-"$VERSION".glibc"$GLIBC_NEEDED"-"$ARCH".AppImage" 2>/dev/null || true
ca369dfa 190 GLIBC_NEEDED=$(glibc_needed)
8c7df980 191 ./AppImageAssistant ./$APP.AppDir/ ../out/$APP"-"$VERSION".glibc"$GLIBC_NEEDED"-"$ARCH".AppImage"
1f369f0c
UH
192}
193
194# Generate AppImage type 2
ca369dfa
UH
195# Additional parameters given to this routine will be passed on to appimagetool
196#
197# If the environment variable NO_GLIBC_VERSION is set, the required glibc version
198# will not be added to the AppImage filename
1f369f0c
UH
199generate_type2_appimage()
200{
201 # Get the ID of the last successful build on Travis CI
8c7df980 202 # ID=$(wget -q https://api.travis-ci.org/repos/AppImage/appimagetool/builds -O - | head -n 1 | sed -e 's|}|\n|g' | grep '"result":0' | head -n 1 | sed -e 's|,|\n|g' | grep '"id"' | cut -d ":" -f 2)
1f369f0c
UH
203 # Get the transfer.sh URL from the logfile of the last successful build on Travis CI
204 # Only Travis knows why build ID and job ID don't match and why the above doesn't give both...
205 # URL=$(wget -q "https://s3.amazonaws.com/archive.travis-ci.org/jobs/$((ID+1))/log.txt" -O - | grep "https://transfer.sh/.*/appimagetool" | tail -n 1 | sed -e 's|\r||g')
206 # if [ -z "$URL" ] ; then
207 # URL=$(wget -q "https://s3.amazonaws.com/archive.travis-ci.org/jobs/$((ID+2))/log.txt" -O - | grep "https://transfer.sh/.*/appimagetool" | tail -n 1 | sed -e 's|\r||g')
208 # fi
af040d31
UH
209 if [ -z "$(which appimagetool)" ] ; then
210 URL="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-${SYSTEM_ARCH}.AppImage"
211 wget -c "$URL" -O appimagetool
212 chmod a+x ./appimagetool
213 appimagetool=$(readlink -f appimagetool)
214 else
215 appimagetool=$(which appimagetool)
216 fi
ca369dfa
UH
217 if [ "$DOCKER_BUILD" ]; then
218 appimagetool_tempdir=$(mktemp -d)
219 mv appimagetool "$appimagetool_tempdir"
220 pushd "$appimagetool_tempdir" &>/dev/null
221 ls -al
222 ./appimagetool --appimage-extract
223 rm appimagetool
224 appimagetool=$(readlink -f squashfs-root/AppRun)
225 popd &>/dev/null
226 _appimagetool_cleanup() { [ -d "$appimagetool_tempdir" ] && rm -r "$appimagetool_tempdir"; }
227 trap _appimagetool_cleanup EXIT
228 fi
229
230 if [ -z ${NO_GLIBC_VERSION+true} ]; then
231 GLIBC_NEEDED=$(glibc_needed)
232 VERSION_EXPANDED=$VERSION.glibc$GLIBC_NEEDED
233 else
234 VERSION_EXPANDED=$VERSION
235 fi
236
1f369f0c 237 set +x
ca369dfa 238 GLIBC_NEEDED=$(glibc_needed)
1f369f0c 239 if ( [ ! -z "$KEY" ] ) && ( ! -z "$TRAVIS" ) ; then
8c7df980 240 wget https://github.com/AppImage/AppImageKit/files/584665/data.zip -O data.tar.gz.gpg
1f369f0c
UH
241 ( set +x ; echo $KEY | gpg2 --batch --passphrase-fd 0 --no-tty --skip-verify --output data.tar.gz --decrypt data.tar.gz.gpg )
242 tar xf data.tar.gz
243 sudo chown -R $USER .gnu*
244 mv $HOME/.gnu* $HOME/.gnu_old ; mv .gnu* $HOME/
ca369dfa 245 VERSION=$VERSION_EXPANDED "$appimagetool" $@ -n -s --bintray-user $BINTRAY_USER --bintray-repo $BINTRAY_REPO -v ./$APP.AppDir/
1f369f0c 246 else
ca369dfa 247 VERSION=$VERSION_EXPANDED "$appimagetool" $@ -n --bintray-user $BINTRAY_USER --bintray-repo $BINTRAY_REPO -v ./$APP.AppDir/
1f369f0c
UH
248 fi
249 set -x
250 mkdir -p ../out/ || true
251 mv *.AppImage* ../out/
252}
253
254# Generate status file for use by apt-get; assuming that the recipe uses no newer
8c7df980 255# ingredients than what would require more recent dependencies than what we assume
1f369f0c
UH
256# to be part of the base system
257generate_status()
258{
259 mkdir -p ./tmp/archives/
260 mkdir -p ./tmp/lists/partial
261 touch tmp/pkgcache.bin tmp/srcpkgcache.bin
af040d31
UH
262 if [ -e "${HERE}/usr/share/pkg2appimage/excludedeblist" ] ; then
263 EXCLUDEDEBLIST="${HERE}/usr/share/pkg2appimage/excludedeblist"
264 else
265 wget -q -c "https://github.com/AppImage/AppImages/raw/${PKG2AICOMMIT}/excludedeblist"
266 EXCLUDEDEBLIST=excludedeblist
267 fi
1f369f0c
UH
268 rm status 2>/dev/null || true
269 for PACKAGE in $(cat excludedeblist | cut -d "#" -f 1) ; do
270 printf "Package: $PACKAGE\nStatus: install ok installed\nArchitecture: all\nVersion: 9:999.999.999\n\n" >> status
271 done
272}
273
274# Find the desktop file and copy it to the AppDir
275get_desktop()
276{
277 find usr/share/applications -iname "*${LOWERAPP}.desktop" -exec cp {} . \; || true
278}
279
8c7df980
UH
280fix_desktop() {
281 # fix trailing semicolons
282 for key in Actions Categories Implements Keywords MimeType NotShowIn OnlyShowIn; do
283 sed -i '/'"$key"'.*[^;]$/s/$/;/' $1
284 done
285}
286
1f369f0c
UH
287# Find the icon file and copy it to the AppDir
288get_icon()
289{
290 find ./usr/share/pixmaps/$LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
291 find ./usr/share/icons -path *64* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
292 find ./usr/share/icons -path *128* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
293 find ./usr/share/icons -path *512* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
294 find ./usr/share/icons -path *256* -name $LOWERAPP.png -exec cp {} . \; 2>/dev/null || true
295 ls -lh $LOWERAPP.png || true
296}
297
298# Find out the version
299get_version()
300{
301 THEDEB=$(find ../*.deb -name $LOWERAPP"_*" | head -n 1)
302 if [ -z "$THEDEB" ] ; then
303 echo "Version could not be determined from the .deb; you need to determine it manually"
304 fi
ca369dfa 305 VERSION=$(echo $THEDEB | cut -d "~" -f 1 | cut -d "_" -f 2 | cut -d "-" -f 1 | sed -e 's|1%3a||g' | sed -e 's|.dfsg||g' )
1f369f0c
UH
306 echo $VERSION
307}
308
309# transfer.sh
8c7df980 310transfer() { if [ $# -eq 0 ]; then echo "No arguments specified. Usage:\necho transfer /tmp/test.md\ncat /tmp/test.md | transfer test.md"; return 1; fi
1f369f0c
UH
311tmpfile=$( mktemp -t transferXXX ); if tty -s; then basefile=$(basename "$1" | sed -e 's/[^a-zA-Z0-9._-]/-/g'); curl --progress-bar --upload-file "$1" "https://transfer.sh/$basefile" >> $tmpfile; else curl --progress-bar --upload-file "-" "https://transfer.sh/$1" >> $tmpfile ; fi; cat $tmpfile; rm -f $tmpfile; }
312
313# Patch binary files; fill with padding if replacement is shorter than original
314# http://everydaywithlinux.blogspot.de/2012/11/patch-strings-in-binary-files-with-sed.html
315# Example: patch_strings_in_file foo "/usr/local/lib/foo" "/usr/lib/foo"
8c7df980 316patch_strings_in_file() {
1f369f0c
UH
317 local FILE="$1"
318 local PATTERN="$2"
319 local REPLACEMENT="$3"
8c7df980 320 # Find all unique strings in FILE that contain the pattern
1f369f0c
UH
321 STRINGS=$(strings ${FILE} | grep ${PATTERN} | sort -u -r)
322 if [ "${STRINGS}" != "" ] ; then
323 echo "File '${FILE}' contain strings with '${PATTERN}' in them:"
324 for OLD_STRING in ${STRINGS} ; do
325 # Create the new string with a simple bash-replacement
326 NEW_STRING=${OLD_STRING//${PATTERN}/${REPLACEMENT}}
327 # Create null terminated ASCII HEX representations of the strings
328 OLD_STRING_HEX="$(echo -n ${OLD_STRING} | xxd -g 0 -u -ps -c 256)00"
329 NEW_STRING_HEX="$(echo -n ${NEW_STRING} | xxd -g 0 -u -ps -c 256)00"
330 if [ ${#NEW_STRING_HEX} -le ${#OLD_STRING_HEX} ] ; then
331 # Pad the replacement string with null terminations so the
332 # length matches the original string
333 while [ ${#NEW_STRING_HEX} -lt ${#OLD_STRING_HEX} ] ; do
334 NEW_STRING_HEX="${NEW_STRING_HEX}00"
335 done
8c7df980 336 # Now, replace every occurrence of OLD_STRING with NEW_STRING
1f369f0c
UH
337 echo -n "Replacing ${OLD_STRING} with ${NEW_STRING}... "
338 hexdump -ve '1/1 "%.2X"' ${FILE} | \
339 sed "s/${OLD_STRING_HEX}/${NEW_STRING_HEX}/g" | \
340 xxd -r -p > ${FILE}.tmp
341 chmod --reference ${FILE} ${FILE}.tmp
342 mv ${FILE}.tmp ${FILE}
343 echo "Done!"
344 else
345 echo "New string '${NEW_STRING}' is longer than old" \
346 "string '${OLD_STRING}'. Skipping."
347 fi
348 done
349 fi
350}