| #! /bin/sh |
| # Copyright (C) 2012-2024 Free Software Foundation, Inc. |
| # |
| # 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, 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 <https://www.gnu.org/licenses/>. |
| |
| # Check support for different compression formats used by distribution |
| # archives. |
| |
| am_create_testdir=empty |
| . test-init.sh |
| |
| plan_ 75 |
| |
| # ---------------------------------------------------- # |
| # Common and/or auxiliary subroutines and variables. # |
| # ---------------------------------------------------- # |
| |
| ocwd=$(pwd) || fatal_ "getting current working directory" |
| |
| unset TAR |
| |
| # Create common aclocal.m4 file, for later tests. |
| mkdir setup \ |
| && cd setup \ |
| && echo 'AC_INIT([x], [0]) AM_INIT_AUTOMAKE' > configure.ac \ |
| && $ACLOCAL \ |
| && mv aclocal.m4 .. \ |
| && cd .. \ |
| && rm -rf setup \ |
| || fatal_ "creating common aclocal.m4 file" |
| |
| # Some make implementations (e.g., HP-UX) don't grok '-j', some require |
| # no space between '-j' and the number of jobs (e.g., older GNU make |
| # versions), and some *do* require a space between '-j' and the number |
| # of jobs (e.g., Solaris dmake). We need a runtime test to see what |
| # works. |
| for MAKE_j4 in "$MAKE -j4" "$MAKE -j 4" false; do |
| echo all: | $MAKE_j4 -f - && break |
| : For shells with buggy 'set -e'. |
| done |
| |
| # Set variables '$compressor' and '$suffix'. |
| setup_vars_for_compression_format () |
| { |
| suffix=NONE compressor=NONE |
| case $1 in |
| gzip) suffix=tar.gz compressor=gzip ;; |
| lzip) suffix=tar.lz compressor=lzip ;; |
| xz) suffix=tar.xz compressor=xz ;; |
| bzip2) suffix=tar.bz2 compressor=bzip2 ;; |
| zip) suffix=zip compressor=zip ;; |
| zstd) suffix=tar.zst compressor=zstd ;; |
| *) fatal_ "invalid compression format '$1'";; |
| esac |
| } |
| |
| have_compressor () |
| { |
| test $# -eq 1 || fatal_ "have_compressor(): bad usage" |
| if test $1 = gzip; then |
| # Assume gzip(1) is available on every reasonable portability target. |
| return 0 |
| fi |
| needed_programs=$1 |
| # Assume by default the other compressors we care about support the |
| # '--version' option. We'll special-case the one which don't. |
| checker_option=--version |
| case $1 in |
| bzip2) |
| # Do not use --version, or older versions bzip2 would try to |
| # compress stdin. This would cause binary output in the test |
| # logs, with potential breakage of our testsuite harness. |
| checker_option=--help |
| ;; |
| zip) |
| # OpenSolaris zip do not support the '--version' option, but |
| # accepts the '-v' one with a similar meaning (if no further |
| # arguments are given). |
| checker_option=-v |
| # Also, we need 'unzip' to decompress the created zipped archives |
| # (bug#15181). |
| needed_programs='zip unzip' |
| ;; |
| esac |
| # Redirect to stderr to avoid polluting the output, in case this |
| # function is used in a command substitution (as it is, later in |
| # this script). |
| for p in $needed_programs; do |
| $p $checker_option </dev/null >&2 || return 1 |
| done |
| return 0 |
| } |
| |
| all_compression_formats='gzip lzip xz bzip2 zip zstd' |
| |
| all_compressors=$( |
| for x in $all_compression_formats; do |
| setup_vars_for_compression_format $x |
| echo $compressor |
| done | tr "$nl" ' ') |
| echo All compressors: $all_compressors |
| |
| missing_compressors=$( |
| for c in $all_compressors; do |
| have_compressor $c || echo $c |
| done | tr "$nl" ' ') |
| echo Missing compressors: $missing_compressors |
| |
| # Redefine to avoid re-running the already executed checks. |
| have_compressor () |
| { |
| case " $missing_compressors " in *\ $1\ *) false;; *) : ;; esac |
| } |
| |
| have_all_compressors () |
| { |
| test -z "$missing_compressors" |
| } |
| |
| start_subtest () |
| { |
| name=$1; shift |
| test -n "$name" || fatal_ "start_subtest: no subtest name given" |
| if test $# -gt 0; then |
| eval "$@" || fatal_ "start_subtest: evaluating assignments" |
| fi |
| ac_opts=$(echo $ac_opts | tr ',' ' ') |
| am_opts=$(echo $am_opts | tr ',' ' ') |
| mkdir "$name" |
| cd "$name" |
| unindent > configure.ac <<END |
| AC_INIT([$name], [1.0]) |
| AM_INIT_AUTOMAKE([$ac_opts]) |
| AC_CONFIG_FILES([Makefile]) |
| AC_OUTPUT |
| END |
| echo "AUTOMAKE_OPTIONS = $am_opts" > Makefile.am |
| # It is imperative that aclocal.m4 is copied after configure.ac has |
| # been created, to avoid a spurious trigger of the automatic remake |
| # rules for configure & co. |
| cp "$ocwd"/aclocal.m4 \ |
| "$am_scriptdir"/missing \ |
| "$am_scriptdir"/install-sh \ |
| . |
| } |
| |
| end_subtest () |
| { |
| unset name; unset ac_opts; unset am_opts; |
| cd "$ocwd" || fatal_ "couldn't chdir back to '$ocwd'" |
| } |
| |
| command_ok_if_have_compressor () |
| { |
| if have_compressor "$compressor"; then |
| command_ok_ "$@" |
| else |
| skip_ -r "'$compressor' not available" "$1" |
| fi |
| } |
| |
| can_compress () |
| { |
| test $# -eq 2 || fatal_ "can_compress: bad number of arguments" |
| tarname=$1 format=$2 |
| setup_vars_for_compression_format "$format" |
| |
| command_ok_ "'dist-$format' target always created" $MAKE -n dist-$format |
| |
| command_ok_if_have_compressor "'make dist-$format' work by default" \ |
| eval ' |
| rm -rf *$tarname* \ |
| && $MAKE dist-$format \ |
| && test -f $tarname-1.0.$suffix \ |
| && ls -l *$tarname* \ |
| && test "$(echo *$tarname*)" = $tarname-1.0.$suffix' |
| |
| unset suffix compressor format tarname |
| } |
| |
| # ---------------------------------------- # |
| # Defaults layout of the dist-* targets. # |
| # ---------------------------------------- # |
| |
| start_subtest defaults |
| |
| command_ok_ "default [automake]" $AUTOMAKE |
| command_ok_ "default [autoconf]" $AUTOCONF |
| command_ok_ "default [configure]" ./configure |
| command_ok_ "default [make distcheck]" $MAKE distcheck |
| |
| command_ok_ "'make dist' only builds *.tar.gz by default" \ |
| test "$(ls *defaults*)" = defaults-1.0.tar.gz |
| |
| rm -rf *defaults* |
| |
| for fmt in $all_compression_formats; do |
| can_compress defaults $fmt |
| done |
| unset fmt |
| |
| end_subtest |
| |
| # ----------------------------------------------------------- # |
| # Check diagnostic for no-dist-gzip without another dist-*. # |
| # ----------------------------------------------------------- # |
| |
| nogzip_stderr () |
| { |
| grep "$1:.*no-dist-gzip" stderr \ |
| && grep "$1:.* at least one archive format must be enabled" stderr |
| } |
| |
| nogzip_automake_failure () |
| { |
| AUTOMAKE_fails -d "no-dist-gzip ($1) without other formats is an error" |
| command_ok_ "no-dist-gzip ($1) without other formats gives diagnostic" \ |
| nogzip_stderr "$2" |
| } |
| |
| start_subtest am-nogz-only am_opts=no-dist-gzip ac_opts= |
| nogzip_automake_failure 'am' 'Makefile\.am:1' |
| end_subtest |
| |
| start_subtest ac-nogz-only am_opts= ac_opts=no-dist-gzip |
| nogzip_automake_failure 'ac' 'configure\.ac:2' |
| end_subtest |
| |
| # ------------------------------------------------- # |
| # Check use of no-dist-gzip with a dist-* option. # |
| # ------------------------------------------------- # |
| |
| append_to_opt () |
| { |
| var=$1_opts val=$2 |
| eval "$var=\${$var:+\"\$$var,\"}\$val" || fatal_ "evaluating \${$var}" |
| unset var val |
| } |
| |
| nogzip () |
| { |
| test $#,$1,$3,$5 = 6,in,and,in \ |
| && case $2,$6 in ac,ac|ac,am|am,ac|am,am) :;; *) false;; esac \ |
| || fatal_ "nogzip: invalid usage" |
| format=$4 where_dist_nogzip=$2 where_dist_format=$6 |
| shift 6 |
| |
| am_opts= ac_opts= |
| append_to_opt $where_dist_format dist-$format |
| append_to_opt $where_dist_nogzip no-dist-gzip |
| setup_vars_for_compression_format "$format" |
| # Do these before the am_opts and ac_opts variable can be munged |
| # by 'start_subtest'. |
| desc= |
| test -n "$am_opts" && desc=${desc:+"$desc "}"am=$am_opts" |
| test -n "$ac_opts" && desc=${desc:+"$desc "}"ac=$ac_opts" |
| |
| start_subtest nogzip-$format am_opts=$am_opts ac_opts=$ac_opts |
| |
| unindent >> Makefile.am <<END |
| check-ark-name: |
| test \$(DIST_ARCHIVES) = \$(distdir).$suffix |
| check-ark-exists: |
| test -f \$(distdir).$suffix |
| check-no-tar-gz: |
| test ! -f \$(distdir).tar.gz |
| END |
| |
| command_ok_ "$desc [automake]" $AUTOMAKE |
| command_ok_ "$desc [autoconf]" $AUTOCONF |
| command_ok_ "$desc [configure]" ./configure |
| command_ok_ "$desc [ark-name]" $MAKE check-ark-name |
| command_ok_if_have_compressor "$desc [distcheck]" $MAKE distcheck |
| command_ok_if_have_compressor "$desc [ark-exists]" $MAKE check-ark-exists |
| command_ok_ "$desc [no .tar.gz]" $MAKE check-no-tar-gz |
| |
| unset desc |
| |
| end_subtest |
| } |
| |
| # $1 $2 $3 $4 $5 $6 |
| nogzip in am and bzip2 in am |
| nogzip in ac and xz in am |
| nogzip in am and lzip in ac |
| nogzip in ac and zip in ac |
| nogzip in ac and zstd in ac |
| |
| |
| # ----------------------------------------------------------- # |
| # The 'dist-gzip' target is created also with no-dist-gzip. # |
| # ----------------------------------------------------------- # |
| |
| start_subtest dist-gzip-persistence am_opts=no-dist-gzip,dist-xz |
| command_ok_ "dist-gzip persistence [automake]" $AUTOMAKE |
| command_ok_ "dist-gzip persistence [autoconf]" $AUTOCONF |
| command_ok_ "dist-gzip persistence [configure]" ./configure |
| can_compress dist-gzip-persistence gzip |
| end_subtest |
| |
| |
| # ----------------------- # |
| # Parallel compression. # |
| # ----------------------- # |
| |
| # We only use formats requiring 'gzip', 'bzip2' and 'xz' programs, |
| # since there are the most likely to be all found on the majority |
| # of systems. |
| |
| start_subtest parallel-compression ac_opts=dist-bzip2 am_opts=dist-xz |
| |
| desc=gzip+bzip2+xz |
| tarname=parallel-compression-1.0 |
| |
| check_tarball () |
| { |
| format=$1 |
| setup_vars_for_compression_format $format |
| ( |
| tarball=$tarname.$suffix \ |
| && test -f $tarball \ |
| && mkdir check-$format \ |
| && cp $tarball check-$format \ |
| && cd check-$format \ |
| && $compressor -d $tarball \ |
| && tar xvf $tarname.tar \ |
| && diff ../Makefile.in $tarname/Makefile.in \ |
| && cd .. \ |
| && rm -rf check-$format |
| ) |
| } |
| |
| command_ok_ "$desc [automake]" $AUTOMAKE |
| |
| if ! have_compressor xz && ! have_compressor bzip2; then |
| skip_reason="both 'bzip2' and 'xz' are unavailable" |
| elif ! have_compressor xz; then |
| skip_reason="'xz' not available" |
| elif ! have_compressor bzip2; then |
| skip_reason="'bzip2' not available" |
| else |
| skip_reason= |
| fi |
| if test "$MAKE_j4" = false; then |
| test -z "$skip_reason" || skip_reason="$skip_reason, and " |
| skip_reason="${skip_reason}make concurrency unavailable" |
| fi |
| |
| if test -n "$skip_reason"; then |
| skip_row_ 6 -r "$skip_reason" "$desc" |
| else |
| command_ok_ "$desc [autoconf]" $AUTOCONF |
| command_ok_ "$desc [configure]" ./configure |
| command_ok_ "$desc [make -j4 dist-all]" $MAKE_j4 dist |
| ls -l # For debugging. |
| command_ok_ "$desc [check .tar.gz tarball]" check_tarball gzip |
| command_ok_ "$desc [check .tar.bz2 tarball]" check_tarball bzip2 |
| command_ok_ "$desc [check .tar.xz tarball]" check_tarball xz |
| fi |
| |
| unset tarname desc skip_reason |
| |
| end_subtest |
| |
| |
| # --------------------------------------------------------- # |
| # The various 'dist-*' targets can happily work together. # |
| # --------------------------------------------------------- # |
| |
| start_subtest all-together |
| |
| desc='all compressors together' |
| tarname=all-together-1.0 |
| |
| echo 'AM_INIT_AUTOMAKE([' > am-init.m4 |
| echo 'AUTOMAKE_OPTIONS =' > Makefile.am |
| |
| # Add half 'dist-*' options to AM_INIT_AUTOMAKE, half to AUTOMAKE_OPTIONS. |
| flip=: |
| for fmt in $all_compression_formats; do |
| test $fmt = gzip && continue |
| if $flip; then |
| echo " dist-$fmt" >> am-init.m4 |
| flip=false |
| else |
| echo "AUTOMAKE_OPTIONS += dist-$fmt" >> Makefile.am |
| flip=: |
| fi |
| done |
| unset flip fmt |
| |
| echo '])' >> am-init.m4 |
| |
| sed 's/AM_INIT_AUTOMAKE.*/m4_include([am-init.m4])/' configure.ac > t |
| mv -f t configure.ac |
| |
| # For debugging. |
| cat Makefile.am |
| cat configure.ac |
| cat am-init.m4 |
| |
| command_ok_ "$desc [aclocal]" $ACLOCAL --force |
| command_ok_ "$desc [automake]" $AUTOMAKE |
| command_ok_ "$desc [autoconf]" $AUTOCONF |
| command_ok_ "$desc [configure]" ./configure |
| |
| if have_all_compressors; then |
| command_ok_ "$desc [make distcheck, real]" $MAKE distcheck |
| else |
| skip_ -r "not all compressors available" "$desc [make distcheck, real]" |
| fi |
| |
| # We fake existence of all the compressors here, so that we don't have |
| # to require any of them to run the further tests. This is especially |
| # important since it's very unlikely that a non-developer has all the |
| # compression tools installed on his machine at the same time. |
| |
| mkdir bin |
| cd bin |
| cat > check-distdir <<END |
| #!/bin/sh |
| { ls -l '$tarname' && diff Makefile.am '$tarname'/Makefile.am; } >&2 \ |
| || { echo "== distdir fail =="; exit 1; } |
| END |
| cat > grep-distdir-error <<'END' |
| #!/bin/sh |
| grep 'distdir fail' && exit 1 |
| : |
| END |
| chmod a+x check-distdir grep-distdir-error |
| for prog in tar $all_compressors; do |
| case $prog in |
| tar|zip) cp check-distdir $prog;; |
| *) cp grep-distdir-error $prog;; |
| esac |
| done |
| unset prog |
| ls -l # For debugging. |
| cd .. |
| |
| oPATH=$PATH |
| PATH=$(pwd)/bin$PATH_SEPARATOR$PATH; export PATH |
| |
| command_ok_ \ |
| "$desc ['make dist-all', stubbed]" \ |
| $MAKE dist-all |
| |
| subdesc="$desc ['make dist -j4', stubbed]" |
| if test "$MAKE_j4" = false; then |
| skip_ -r "make concurrency unavailable" "$subdesc" |
| else |
| command_ok_ "$subdesc" $MAKE_j4 dist |
| fi |
| unset subdesc |
| |
| PATH=$oPATH; export PATH |
| |
| end_subtest |
| |
| : |