mirror of
https://github.com/termux/termux-packages.git
synced 2024-11-23 14:56:16 +00:00
377 lines
15 KiB
Bash
377 lines
15 KiB
Bash
termux_step_massage() {
|
|
[ "$TERMUX_PKG_METAPACKAGE" = "true" ] && return
|
|
|
|
cd "$TERMUX_PKG_MASSAGEDIR/$TERMUX_PREFIX_CLASSICAL"
|
|
|
|
local ADDING_PREFIX=""
|
|
if [ "$TERMUX_PACKAGE_LIBRARY" = "glibc" ]; then
|
|
ADDING_PREFIX="glibc/"
|
|
fi
|
|
|
|
# Remove lib/charset.alias which is installed by gettext-using packages:
|
|
rm -f lib/charset.alias
|
|
|
|
# Remove cache file created by update-desktop-database:
|
|
rm -f share/applications/mimeinfo.cache
|
|
|
|
# Remove cache file created by glib-compile-schemas:
|
|
rm -f share/glib-2.0/schemas/gschemas.compiled
|
|
|
|
# Remove cache file generated when using glib-cross-bin:
|
|
rm -rf opt/glib/cross/share/glib-2.0/codegen/__pycache__
|
|
|
|
# Removing the pacman log that is often included in the package:
|
|
rm -f var/log/pacman.log
|
|
|
|
# Remove cache file created by gtk-update-icon-cache:
|
|
rm -f share/icons/hicolor/icon-theme.cache
|
|
|
|
# Remove locale files we're not interested in::
|
|
rm -Rf share/locale
|
|
|
|
# `update-mime-database` updates NOT ONLY "$PREFIX/share/mime/mime.cache".
|
|
# Simply removing this specific file does not solve the issue.
|
|
if [ -e "share/mime/mime.cache" ]; then
|
|
termux_error_exit "MIME cache found in package. Please disable \`update-mime-database\`."
|
|
fi
|
|
|
|
# Remove old kept libraries (readline) and directories (rust):
|
|
find . -name '*.old' -print0 | xargs -0 -r rm -fr
|
|
|
|
# Move over sbin to bin:
|
|
for file in sbin/*; do if test -f "$file"; then mv "$file" bin/; fi; done
|
|
if [ "$TERMUX_PACKAGE_LIBRARY" = "glibc" ]; then
|
|
for file in glibc/sbin/*; do if test -f "$file"; then mv "$file" glibc/bin/; fi; done
|
|
fi
|
|
|
|
# Remove world permissions and make sure that user still have read-write permissions.
|
|
chmod -Rf u+rw,g-rwx,o-rwx . || true
|
|
|
|
if [ "$TERMUX_PACKAGE_LIBRARY" = "bionic" ]; then
|
|
if [ "$TERMUX_PKG_NO_STRIP" != "true" ] && [ "$TERMUX_DEBUG_BUILD" = "false" ]; then
|
|
# Strip binaries. file(1) may fail for certain unusual files, so disable pipefail.
|
|
set +e +o pipefail
|
|
find . \( -path "./bin/*" -o -path "./lib/*" -o -path "./libexec/*" \) -type f |
|
|
xargs -r file | grep -E "ELF .+ (executable|shared object)" | cut -f 1 -d : |
|
|
xargs -r "$STRIP" --strip-unneeded --preserve-dates
|
|
set -e -o pipefail
|
|
fi
|
|
|
|
if [ "$TERMUX_PKG_NO_ELF_CLEANER" != "true" ]; then
|
|
# Remove entries unsupported by Android's linker:
|
|
find . \( -path "./bin/*" -o -path "./lib/*" -o -path "./libexec/*" -o -path "./opt/*" \) -type f -print0 | xargs -r -0 \
|
|
"$TERMUX_ELF_CLEANER" --api-level $TERMUX_PKG_API_LEVEL
|
|
fi
|
|
fi
|
|
|
|
local pattern=""
|
|
for file in ${TERMUX_PKG_NO_SHEBANG_FIX_FILES}; do
|
|
if [[ -z "${pattern}" ]]; then
|
|
pattern="${file}"
|
|
continue
|
|
fi
|
|
pattern+='|'"${file}"
|
|
done
|
|
if [[ -n "${pattern}" ]]; then
|
|
pattern='(|./)('"${pattern}"')$'
|
|
fi
|
|
|
|
if [ "$TERMUX_PKG_NO_SHEBANG_FIX" != "true" ]; then
|
|
# Fix shebang paths:
|
|
while IFS= read -r -d '' file; do
|
|
if [[ -n "${pattern}" ]] && [[ -n "$(echo "${file}" | grep -E "${pattern}")" ]]; then
|
|
echo "INFO: Skip shebang fix for ${file}"
|
|
continue
|
|
fi
|
|
if head -c 100 "$file" | head -n 1 | grep -E "^#!.*/bin/.*" | grep -q -E -v -e "^#! ?/system" -e "^#! ?$TERMUX_PREFIX_CLASSICAL"; then
|
|
sed --follow-symlinks -i -E "1 s@^#\!(.*)/bin/(.*)@#\!$TERMUX_PREFIX/bin/\2@" "$file"
|
|
fi
|
|
done < <(find -L . -type f -print0)
|
|
fi
|
|
|
|
# Delete the info directory file.
|
|
rm -rf ./${ADDING_PREFIX}share/info/dir
|
|
|
|
# Mostly specific to X11-related packages.
|
|
rm -f ./${ADDING_PREFIX}share/icons/hicolor/icon-theme.cache
|
|
|
|
test ! -z "$TERMUX_PKG_RM_AFTER_INSTALL" && rm -Rf $TERMUX_PKG_RM_AFTER_INSTALL
|
|
|
|
find . -type d -empty -delete # Remove empty directories
|
|
|
|
if [ -d ./${ADDING_PREFIX}share/man ]; then
|
|
# Remove non-english man pages:
|
|
find ./${ADDING_PREFIX}share/man -mindepth 1 -maxdepth 1 -type d ! -name man\* | xargs -r rm -rf
|
|
|
|
# Compress man pages with gzip:
|
|
find ./${ADDING_PREFIX}share/man -type f ! -iname \*.gz -print0 | xargs -r -0 gzip -9 -n
|
|
|
|
# Update man page symlinks, e.g. unzstd.1 -> zstd.1:
|
|
while IFS= read -r -d '' file; do
|
|
local _link_value
|
|
_link_value=$(readlink $file)
|
|
rm $file
|
|
ln -s $_link_value.gz $file.gz
|
|
done < <(find ./${ADDING_PREFIX}share/man -type l ! -iname \*.gz -print0)
|
|
fi
|
|
|
|
# Remove python-glibc package files that are created
|
|
# due to its launch during package compilation.
|
|
if [ "$TERMUX_PACKAGE_LIBRARY" = "glibc" ] && [ "$TERMUX_PKG_NAME" != "python-glibc" ]; then
|
|
rm -f ./${ADDING_PREFIX}lib/python${TERMUX_PYTHON_VERSION}/__pycache__/{base64,platform,quopri}.cpython-${TERMUX_PYTHON_VERSION//./}.pyc
|
|
fi
|
|
|
|
# Check so files were actually installed. Exclude
|
|
# share/doc/$TERMUX_PKG_NAME/ as a license file is always
|
|
# installed there.
|
|
if [ "$(find . -path "./${ADDING_PREFIX}share/doc/$TERMUX_PKG_NAME" -prune -o -type f -print | head -n1)" = "" ]; then
|
|
if [ -f "$TERMUX_PKG_SRCDIR"/configure.ac -o -f "$TERMUX_PKG_SRCDIR"/configure.in ]; then
|
|
termux_error_exit "No files in package. Maybe you need to run autoreconf -fi before configuring."
|
|
else
|
|
termux_error_exit "No files in package."
|
|
fi
|
|
fi
|
|
|
|
local HARDLINKS
|
|
HARDLINKS="$(find . -type f -links +1)"
|
|
if [ -n "$HARDLINKS" ]; then
|
|
if [ "$TERMUX_PACKAGE_LIBRARY" = "bionic" ]; then
|
|
termux_error_exit "Package contains hard links: $HARDLINKS"
|
|
elif [ "$TERMUX_PACKAGE_LIBRARY" = "glibc" ]; then
|
|
local declare hard_list
|
|
for i in $HARDLINKS; do
|
|
hard_list[$(ls -i "$i" | awk '{printf $1}')]+="$i "
|
|
done
|
|
local root_file
|
|
for i in ${!hard_list[@]}; do
|
|
root_file=""
|
|
for j in ${hard_list[$i]}; do
|
|
if [ -z "$root_file" ]; then
|
|
root_file="$j"
|
|
continue
|
|
fi
|
|
ln -sf "${TERMUX_PREFIX_CLASSICAL}/${root_file:2}" "${j}"
|
|
done
|
|
done
|
|
fi
|
|
fi
|
|
|
|
# Check for directory "$PREFIX/man" which indicates packaging error.
|
|
if [ -d "./${ADDING_PREFIX}man" ]; then
|
|
termux_error_exit "Package contains directory \"\$PREFIX/man\" ($TERMUX_PREFIX/man). Use \"\$PREFIX/share/man\" ($TERMUX_PREFIX/share/man) instead."
|
|
fi
|
|
|
|
# Check for directory "$PREFIX/$PREFIX" which almost always indicates
|
|
# packaging error.
|
|
if [ -d "./${TERMUX_PREFIX#/}" ]; then
|
|
termux_error_exit "Package contains directory \"\$PREFIX/\$PREFIX\" ($TERMUX_PREFIX/${TERMUX_PREFIX#/})"
|
|
fi
|
|
|
|
# Check for Debianish Python directory which indicates packaging error.
|
|
local _python_deb_install_layout_dir="${ADDING_PREFIX}lib/python3/dist-packages"
|
|
if [ -d "./${_python_deb_install_layout_dir}" ]; then
|
|
termux_error_exit "Package contains directory \"\$PREFIX/${_python_deb_install_layout_dir}\" ($TERMUX_PREFIX/${_python_deb_install_layout_dir})"
|
|
fi
|
|
|
|
# Check so that package is not affected by
|
|
# https://github.com/android/ndk/issues/1614, or
|
|
# https://github.com/termux/termux-packages/issues/9944
|
|
if [[ "${TERMUX_PACKAGE_LIBRARY}" == "bionic" ]]; then
|
|
echo "INFO: READELF=${READELF} ... $(command -v ${READELF})"
|
|
export pattern_file_undef=$(mktemp)
|
|
echo "INFO: Generating undefined symbols regex to ${pattern_file_undef}"
|
|
local t0=$(get_epoch)
|
|
local SYMBOLS=$(${READELF} -s $(${TERMUX_HOST_PLATFORM}-clang -print-libgcc-file-name) | grep -E "FUNC[[:space:]]+GLOBAL[[:space:]]+HIDDEN" | awk '{ print $8 }')
|
|
SYMBOLS+=" $(echo libandroid_{sem_{open,close,unlink},shm{ctl,get,at,dt}})"
|
|
SYMBOLS+=" $(grep "^ [_a-zA-Z0-9]*;" ${TERMUX_SCRIPTDIR}/scripts/lib{c,dl,m}.map.txt | cut -d":" -f2 | sed -e "s/^ //" -e "s/;.*//")"
|
|
SYMBOLS+=" ${TERMUX_PKG_EXTRA_UNDEF_SYMBOLS_TO_CHECK}"
|
|
SYMBOLS=$(echo $SYMBOLS | tr " " "\n" | sort | uniq)
|
|
create_grep_pattern_undef ${SYMBOLS} > "${pattern_file_undef}"
|
|
local t1=$(get_epoch)
|
|
echo "INFO: Done ... $((t1-t0))s"
|
|
echo "INFO: Total symbols $(echo ${SYMBOLS} | wc -w)"
|
|
export pattern_file_openmp=$(mktemp)
|
|
echo "INFO: Generating OpenMP symbols regex to ${pattern_file_openmp}"
|
|
local t0=$(get_epoch)
|
|
local LIBOMP_SO=$(${TERMUX_HOST_PLATFORM}-clang -print-file-name=libomp.so)
|
|
local LIBOMP_A=$(${TERMUX_HOST_PLATFORM}-clang -print-file-name=libomp.a)
|
|
[[ "${LIBOMP_SO}" == "libomp.so" ]] && echo "WARN: LIBOMP_SO=${LIBOMP_SO}, discarding" >&2 && LIBOMP_SO=""
|
|
[[ "${LIBOMP_A}" == "libomp.a" ]] && echo "WARN: LIBOMP_A=${LIBOMP_A}, discarding" >&2 && LIBOMP_A=""
|
|
export LIBOMP_SO_SYMBOLS='' LIBOMP_A_SYMBOLS='' LIBOMP_SYMBOLS=''
|
|
[[ -n "${LIBOMP_SO}" ]] && LIBOMP_SO_SYMBOLS=$(${READELF} -s "${LIBOMP_SO}" | grep -E "GLOBAL[[:space:]]+DEFAULT" | grep -vE "[[:space:]]UND[[:space:]]" | grep -vE "[[:space:]]sizes$" | awk '{ print $8 }')
|
|
[[ -n "${LIBOMP_A}" ]] && LIBOMP_A_SYMBOLS=$(${READELF} -s "${LIBOMP_A}" | grep -E "GLOBAL[[:space:]]+DEFAULT" | grep -vE "[[:space:]]UND[[:space:]]" | grep -vE "[[:space:]]sizes$" | awk '{ print $8 }')
|
|
LIBOMP_SYMBOLS=$(echo -e "${LIBOMP_SO_SYMBOLS}\n${LIBOMP_A_SYMBOLS}" | sort | uniq)
|
|
create_grep_pattern_openmp ${LIBOMP_SYMBOLS} > "${pattern_file_openmp}"
|
|
local t1=$(get_epoch)
|
|
echo "INFO: Done ... $((t1-t0))s"
|
|
echo "INFO: Total OpenMP symbols $(echo ${LIBOMP_SYMBOLS} | wc -w)"
|
|
|
|
local nproc=$(nproc)
|
|
echo "INFO: Identifying files with nproc=${nproc}"
|
|
local t0=$(get_epoch)
|
|
local files=$(find . -type f)
|
|
# use bash to see if llvm-readelf crash
|
|
# https://github.com/llvm/llvm-project/issues/89534
|
|
local valid=$(echo "${files}" | xargs -P"${nproc}" -i bash -c 'if ${READELF} -h "{}" &>/dev/null; then echo "{}"; fi')
|
|
local t1=$(get_epoch)
|
|
echo "INFO: Done ... $((t1-t0))s"
|
|
local numberOfFiles=$(echo "${files}" | wc -l)
|
|
local numberOfValid=$(echo "${valid}" | wc -l)
|
|
echo "INFO: Found ${numberOfValid} / ${numberOfFiles} files"
|
|
if [[ "${numberOfValid}" -gt "${numberOfFiles}" ]]; then
|
|
termux_error_exit "${numberOfValid} > ${numberOfFiles}"
|
|
fi
|
|
|
|
echo "INFO: Running symbol checks on ${numberOfValid} files with nproc=${nproc}"
|
|
local t0=$(get_epoch)
|
|
local undef=$(echo "${valid}" | xargs -P"${nproc}" -i sh -c '${READELF} -s "{}" | grep -Ef "${pattern_file_undef}"')
|
|
local openmp=$(echo "${valid}" | xargs -P"${nproc}" -i sh -c '${READELF} -s "{}" | grep -Ef "${pattern_file_openmp}"')
|
|
local depend_libomp_so=$(echo "${valid}" | xargs -P$(nproc) -n1 ${READELF} -d 2>/dev/null | sed -ne "s|.*NEEDED.*\[\(.*\)\].*|\1|p" | grep libomp.so)
|
|
local t1=$(get_epoch)
|
|
echo "INFO: Done ... $((t1-t0))s"
|
|
|
|
[[ -n "${undef}" ]] && echo "INFO: Found files with undefined symbols"
|
|
if [[ "${TERMUX_PKG_UNDEF_SYMBOLS_FILES}" == "all" ]]; then
|
|
echo "INFO: Skipping output result as TERMUX_PKG_UNDEF_SYMBOLS_FILES=all"
|
|
undef=""
|
|
fi
|
|
|
|
if [[ -n "${undef}" ]]; then
|
|
echo "INFO: Showing result"
|
|
local t0=$(get_epoch)
|
|
# e: bit0 valid file, bit1 error handling
|
|
local e=0
|
|
local c=0
|
|
local valid_s=$(echo "${valid}" | sort)
|
|
local f excluded_f
|
|
while IFS= read -r f; do
|
|
# exclude object, static files
|
|
case "${f}" in
|
|
*.a) (( e &= ~1 )) || : ;;
|
|
*.dll) (( e &= ~1 )) || : ;;
|
|
*.o) (( e &= ~1 )) || : ;;
|
|
*.obj) (( e &= ~1 )) || : ;;
|
|
*.rlib) (( e &= ~1 )) || : ;;
|
|
*.syso) (( e &= ~1 )) || : ;;
|
|
*) (( e |= 1 )) || : ;;
|
|
esac
|
|
while IFS= read -r excluded_f; do
|
|
[[ "${f}" == ${excluded_f} ]] && (( e &= ~1 )) && break
|
|
done < <(echo "${TERMUX_PKG_UNDEF_SYMBOLS_FILES}")
|
|
[[ "${TERMUX_PKG_UNDEF_SYMBOLS_FILES}" == "error" ]] && (( e |= 1 )) || :
|
|
[[ $(( e & 1 )) == 0 ]] && echo "SKIP: ${f}" && continue
|
|
local undef_sym=$(${READELF} -s "${f}" | grep -Ef "${pattern_file_undef}")
|
|
if [[ -n "${undef_sym}" ]]; then
|
|
((c++)) || :
|
|
if [[ $(( e & 1 )) != 0 ]]; then
|
|
echo -e "ERROR: ${f} contains undefined symbols:\n${undef_sym}" >&2
|
|
(( e |= 2 )) || :
|
|
else
|
|
local undef_symu=$(echo "${undef_sym}" | awk '{ print $8 }' | sort | uniq)
|
|
local undef_symu_len=$(echo ${undef_symu} | wc -w)
|
|
echo "SKIP: ${f} contains undefined symbols: ${undef_symu_len}" >&2
|
|
fi
|
|
fi
|
|
done < <(echo "${valid_s}")
|
|
local t1=$(get_epoch)
|
|
echo "INFO: Done ... $((t1-t0))s"
|
|
echo "INFO: Found ${c} files with undefined symbols after exclusion"
|
|
[[ "${c}" -gt "${numberOfValid}" ]] && termux_error_exit "${c} > ${numberOfValid}"
|
|
[[ $(( e & 2 )) != 0 ]] && termux_error_exit "Refer above"
|
|
fi
|
|
|
|
if [[ -n "${openmp}" ]]; then
|
|
echo "INFO: Found files with OpenMP symbols"
|
|
echo "INFO: Showing result"
|
|
local t0=$(get_epoch)
|
|
# e: bit0 valid file, bit1 error handling
|
|
local e=0
|
|
local c=0
|
|
local valid_s=$(echo "${valid}" | sort)
|
|
local f
|
|
while IFS= read -r f; do
|
|
# exclude object, static files
|
|
case "${f}" in
|
|
*.a) (( e &= ~1 )) || : ;;
|
|
*.dll) (( e &= ~1 )) || : ;;
|
|
*.o) (( e &= ~1 )) || : ;;
|
|
*.obj) (( e &= ~1 )) || : ;;
|
|
*.rlib) (( e &= ~1 )) || : ;;
|
|
*.syso) (( e &= ~1 )) || : ;;
|
|
*) (( e |= 1 )) || : ;;
|
|
esac
|
|
[[ $(( e & 1 )) == 0 ]] && echo "SKIP: ${f}" && continue
|
|
local openmp_sym=$(${READELF} -s "${f}" | grep -Ef "${pattern_file_openmp}")
|
|
if [[ -n "${openmp_sym}" ]]; then
|
|
((c++)) || :
|
|
echo -e "INFO: ${f} contains OpenMP symbols: $(echo "${openmp_sym}" | wc -l)" >&2
|
|
fi
|
|
done < <(echo "${valid_s}")
|
|
local t1=$(get_epoch)
|
|
echo "INFO: Done ... $((t1-t0))s"
|
|
echo "INFO: Found ${c} files with OpenMP symbols after exclusion"
|
|
[[ "${c}" -gt "${numberOfValid}" ]] && termux_error_exit "${c} > ${numberOfValid}"
|
|
fi
|
|
if [[ -n "${depend_libomp_so}" && "${TERMUX_PKG_NO_OPENMP_CHECK}" != "true" ]]; then
|
|
echo "ERROR: Found files depend on libomp.so" >&2
|
|
echo "ERROR: Showing result" >&2
|
|
local t0=$(get_epoch)
|
|
local valid_s=$(echo "${valid}" | sort)
|
|
{
|
|
local f
|
|
while IFS= read -r f; do
|
|
local f_needed=$(${READELF} -d "${f}" 2>/dev/null | sed -ne "s|.*NEEDED.*\[\(.*\)\].*|\1|p" | sort | uniq | tr "\n" " " | sed -e "s/ /, /g")
|
|
echo "ERROR: ${f}: ${f_needed%, }"
|
|
done < <(echo "${valid_s}")
|
|
} | grep libomp.so >&2
|
|
local t1=$(get_epoch)
|
|
echo "ERROR: Done ... $((t1-t0))s" >&2
|
|
termux_error_exit "Refer above"
|
|
fi
|
|
|
|
rm -f "${pattern_file_undef}" "${pattern_file_openmp}"
|
|
unset pattern_file_undef pattern_file_openmp
|
|
fi
|
|
|
|
if [ "$TERMUX_PACKAGE_FORMAT" = "debian" ]; then
|
|
termux_create_debian_subpackages
|
|
elif [ "$TERMUX_PACKAGE_FORMAT" = "pacman" ]; then
|
|
termux_create_pacman_subpackages
|
|
fi
|
|
|
|
# Remove unnecessary files in haskell packages:
|
|
if ! [[ $TERMUX_PKG_NAME =~ ghc|ghc-libs ]]; then
|
|
test -f ./${ADDING_PREFIX}lib/ghc-*/settings && rm -rf ./${ADDING_PREFIX}lib/ghc-*/settings
|
|
fi
|
|
|
|
# .. remove empty directories (NOTE: keep this last):
|
|
find . -type d -empty -delete
|
|
}
|
|
|
|
# Local function called by termux_step_massage
|
|
create_grep_pattern_undef() {
|
|
local symbol_type='NOTYPE[[:space:]]+GLOBAL[[:space:]]+DEFAULT[[:space:]]+UND[[:space:]]+'
|
|
echo -n "$symbol_type$1"'$'
|
|
shift 1
|
|
local arg
|
|
for arg in "$@"; do
|
|
echo -n "|$symbol_type$arg"'$'
|
|
done
|
|
}
|
|
|
|
create_grep_pattern_openmp() {
|
|
local symbol_type='[[:space:]]'
|
|
echo -n "$symbol_type$1"'$|'"$symbol_type$1"'@VERSION$'
|
|
shift 1
|
|
local arg
|
|
for arg in "$@"; do
|
|
echo -n "|$symbol_type$arg"'$|'"$symbol_type$arg"'@VERSION$'
|
|
done
|
|
}
|
|
|
|
get_epoch() {
|
|
[[ -e /proc/uptime ]] && cut -d"." -f1 /proc/uptime && return
|
|
[[ -n "$(command -v date)" ]] && date +%s && return
|
|
echo 0
|
|
}
|