On 28/10/19 3:01 am, la.luge@free.fr wrote:
Uses stat -c '%i %s' and sort -u to count hardlink one time. Gives same result than cat | wc -c without harlinks and good result with hardlinks. Doesn't use filenames
Forwarding to the pacman-dev list. My concern is that this is using the same information that du does to get the file size. And we have had repeated issue after issue for calculating file sizes with du, though we are not entirely sure of the cause (weird filesystem behaviour being the best guess). So I'd prefer just to stick to wc -c.
From fc44b2a226dea56104819ff7ac05e90af01b3316 Mon Sep 17 00:00:00 2001 From: nenesse <la.luge@free.fr> Date: Sun, 27 Oct 2019 17:49:38 +0100 Subject: [PATCH] makepkg-do-not-count-hard-links-multiple-times Uses stat -c '%i %s' and sort -u to count hardlink one time. Gives same result than cat | wc -c without hardlinks and good result with hardlinks. Doesn't use filenames To: mailto:pacman-dev@archlinux.org
--- build-aux/edit-script.sh.in | 1 + configure.ac | 5 ++++ meson.build | 5 ++++ scripts/Makefile.am | 1 + scripts/libmakepkg/util/dirsize.sh.in | 34 +++++++++++++++++++++++++++ scripts/makepkg.sh.in | 2 +- 6 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 scripts/libmakepkg/util/dirsize.sh.in
diff --git a/build-aux/edit-script.sh.in b/build-aux/edit-script.sh.in index 640d32f8..8bd8205d 100644 --- a/build-aux/edit-script.sh.in +++ b/build-aux/edit-script.sh.in @@ -19,6 +19,7 @@ mode=$3 -e "s|@TEMPLATE_DIR[@]|@TEMPLATE_DIR@|g" \ -e "s|@DEBUGSUFFIX[@]|@DEBUGSUFFIX@|g" \ -e "s|@INODECMD[@]|@INODECMD@|g" \ + -e "s|@INODESIZECMD[@]|@INODESIZECMD@|g" \ -e "s|@FILECMD[@]|@FILECMD@|g" \ -e "s|@SEDINPLACEFLAGS[@]|@SEDINPLACEFLAGS@|g" \ -e "s|@SEDPATH[@]|@SEDPATH@|g" \ diff --git a/configure.ac b/configure.ac index d68b3591..ddc93020 100644 --- a/configure.ac +++ b/configure.ac @@ -371,6 +371,7 @@ GCC_VISIBILITY_CC # Host-dependant definitions DEFAULT_SEDINPLACEFLAGS=" --follow-symlinks -i" INODECMD="stat -c '%i %n'" +INODESIZECMD="stat -c '%i %s'" STRIP_BINARIES="--strip-all" STRIP_SHARED="--strip-unneeded" STRIP_STATIC="--strip-debug" @@ -378,6 +379,7 @@ case "${host_os}" in *bsd*) INODECMD="stat -f '%i %N'" DEFAULT_SEDINPLACEFLAGS=" -i \"\"" + INODESIZECMD="stat -f '%i %z'" ;; darwin*) host_os_darwin=yes @@ -386,11 +388,13 @@ case "${host_os}" in STRIP_BINARIES="" STRIP_SHARED="-S" STRIP_STATIC="-S" + INODECMD="/usr/bin/stat -f '%i %z'" ;; esac AM_CONDITIONAL([DARWIN], test "x$host_os_darwin" = "xyes") AC_PATH_PROGS([SEDPATH], [sed], [sed], [/usr/bin$PATH_SEPARATOR/bin] ) AC_SUBST(INODECMD) +AC_SUBST(INODESIZECMD) AC_SUBST(STRIP_BINARIES) AC_SUBST(STRIP_SHARED) AC_SUBST(STRIP_STATIC) @@ -576,6 +580,7 @@ ${PACKAGE_NAME}: Architecture : ${CARCH} Host Type : ${CHOST} File inode command : ${INODECMD} + File inode/size command: ${INODESIZECMD} In-place sed command : ${SEDPATH} ${SEDINPLACEFLAGS} File seccomp command : ${FILECMD}
diff --git a/meson.build b/meson.build index c5704efe..99d15ed6 100644 --- a/meson.build +++ b/meson.build @@ -223,6 +223,7 @@ add_project_arguments('-include', 'config.h', language : 'c') filecmd = 'file' default_sedinplaceflags = ' --follow-symlinks -i' inodecmd = 'stat -c \'%i %n\'' +inodesizecmd = 'stat -c \'%i %s\'' strip_binaries = '--strip-all' strip_shared = '--strip-unneeded' strip_static = '--strip-debug' @@ -237,12 +238,14 @@ endif os = host_machine.system() if os.startswith('darwin') inodecmd = '/usr/bin/stat -f \'%i %n\'' + inodesizecmd = '/usr/bin/stat -f \'%i %z\'' default_sedinplaceflags = ' -i \'\'' strip_binaries = '' strip_shared = '-s' strip_static = '-s' elif os.contains('bsd') or os == 'dragonfly' inodecmd = 'stat -f \'%i %n\'' + inodesizecmd = 'stat -f \'%i %z\'' default_sedinplaceflags = ' -i \'\'' endif
@@ -276,6 +279,7 @@ substs.set('BUILDSCRIPT', BUILDSCRIPT) substs.set('TEMPLATE_DIR', get_option('makepkg-template-dir')) substs.set('DEBUGSUFFIX', get_option('debug-suffix')) substs.set('INODECMD', inodecmd) +substs.set('INODESIZECMD', inodesizecmd) substs.set('FILECMD', filecmd) substs.set('SEDINPLACEFLAGS', sedinplaceflags) substs.set('SEDPATH', SED.path()) @@ -430,6 +434,7 @@ message('\n '.join([ ' Architecture : @0@'.format(carch), ' Host Type : @0@'.format(chost), ' File inode command : @0@'.format(inodecmd), + ' File inode/size command : @0@'.format(inodesizecmd), ' In-place sed command : @0@ @1@'.format(SED.path(), sedinplaceflags), ' File seccomp command : @0@'.format(filecmd), ' libalpm version : @0@'.format(libalpm_version), diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 88e9612d..fe9fb297 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -184,6 +184,7 @@ edit = sed \ -e 's|@TEMPLATE_DIR[@]|$(TEMPLATE_DIR)|g' \ -e 's|@DEBUGSUFFIX[@]|$(DEBUGSUFFIX)|g' \ -e "s|@INODECMD[@]|$(INODECMD)|g" \ + -e "s|@INODESIZECMD[@]|$(INODESIZECMD)|g" \ -e "s|@FILECMD[@]|$(FILECMD)|g" \ -e 's|@SEDINPLACEFLAGS[@]|$(SEDINPLACEFLAGS)|g' \ -e 's|@SEDPATH[@]|$(SEDPATH)|g' \ diff --git a/scripts/libmakepkg/util/dirsize.sh.in b/scripts/libmakepkg/util/dirsize.sh.in new file mode 100644 index 00000000..8f2bd09b --- /dev/null +++ b/scripts/libmakepkg/util/dirsize.sh.in @@ -0,0 +1,34 @@ +#!/usr/bin/bash +# +# dirsize.sh - calculate size of all files in a directory +# +# Copyright (c) 2019 Pacman Development Team <pacman-dev@archlinux.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +[[ -n "$LIBMAKEPKG_UTIL_DIRSIZE_SH" ]] && return +LIBMAKEPKG_UTIL_DIRSIZE_SH=1 + +LIBRARY=${LIBRARY:-'/usr/share/makepkg'} + +dirsize() { + local size=0 sz _ + + while read _ sz; do + size=$(( size + sz )) + done < <(find . -type f -exec @INODESIZECMD@ -- {} + 2>/dev/null|sort -u) + + echo $size +} diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 997c8668..f7a9459b 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -584,7 +584,7 @@ write_kv_pair() { }
write_pkginfo() { - local size="$(find . -type f -exec cat {} + 2>/dev/null | wc -c)" + local size="$(dirsize)"
merge_arch_attrs