1#! /bin/sh 2# Copyright (C) 2012-2021 Free Software Foundation, Inc. 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 2, or (at your option) 7# any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17# Check dependency tracking in various flavours. 18# Contains both libtool and non-libtool case. 19# Sourced by the various (autogenerated) 'depcomp*.tap' tests. 20# Examples of reported failures that motivated those test are 21# listed below. 22 23# ------------------------------------------------------------------------- 24 25# <https://lists.gnu.org/archive/html/automake-patches/2011-04/msg00028.html> 26# 27# Here's the bug: makedepend will prefix VPATH to the object file name, 28# thus the second make will invoke depcomp with object='../../src/foo.o', 29# causing errors such as: 30# 31# touch: cannot touch '../../src/.deps/foo.TPo': No such file or directory 32# makedepend: error: cannot open "../../src/.deps/foo.TPo" 33# ../../depcomp: line 560: ../../src/.deps/foo.TPo: No such file or directory 34 35# ------------------------------------------------------------------------- 36 37# <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=8473> 38# <https://lists.gnu.org/archive/html/automake-patches/2011-04/msg00079.html> 39# 40# Here's the bug: hp depmode will prefix VPATH to the object file name, 41# thus the second gmake will invoke depcomp with object='../../src/foo.o', 42# causing errors such as (broken on multiple lines for clarity): 43# 44# cpp: "", line 0: error 4066: Cannot create 45# "../../gllib/.deps/nonblocking.TPo" file for 46# "-M../../gllib/.deps/nonblocking.TPo" option. 47# (No such file or directory[errno=2]) 48# 49 50# ------------------------------------------------------------------------- 51 52# <https://lists.gnu.org/archive/html/automake-patches/2011-04/msg00140.html> 53# <https://lists.gnu.org/archive/html/automake-patches/2011-05/msg00019.html> 54# 55# A partial failure of an earlier version of this test; some bad 56# post-processing of the '*.Po' files led to the following broken 57# contents of 'src/sub/.deps/subfoo.Po': 58# 59# > sub/subfoo.o: ../../depmod-data.dir/src/sub/subfoo.c \ 60# > ../../depmod-data.dir/src/foo.h 61# > ../../depmod-data.dir/src/sub/subfoo.c \: 62# > ../../depmod-data.dir/src/foo.h: 63# 64# which caused make to die with an error like: 65# 66# "sub/.deps/subfoo.Po:3: *** missing separator. Stop." 67 68# ------------------------------------------------------------------------- 69 70# This code expects test-init.sh has already been included in advance. 71 72ocwd=$(pwd) || fatal_ "getting current working directory" 73longpath=this-is/a-path/which-has/quite-a/definitely/truly/long_long_name 74cachevar=am_cv_CC_dependencies_compiler_type 75 76srctree=depmod-1.0 77mkdir $srctree 78cd $srctree 79 80cd_top () 81{ 82 cd "$ocwd" || fatal_ "cannot chdir back to top directory" 83} 84 85delete () 86{ 87 test -f "$1" || fatal_ "$1: file does not exist" 88 rm -f "$1" || fatal_ "$1: couldn't remove" 89} 90 91edit () 92{ 93 file=$1; shift 94 sed "$@" <"$file" > t && mv -f t "$file" \ 95 || fatal_ "$file: editing of file failed" 96} 97 98rewrite () 99{ 100 file=$1; shift 101 "$@" > "$file" || fatal_ "$file: couldn't rewrite" 102} 103 104setup_srcdir () 105{ 106 srcdir=$1 # This is intended to be global. 107 mkdir -p "$srcdir" \ 108 || fatal_ "couldn't create source directory '$srcdir'" 109 cp -pR "$ocwd/$srctree"/* "$srcdir"/ \ 110 || fatal_ "couldn't populate source directory '$srcdir'" 111} 112 113 114check_no_depfiles () 115{ 116 find . -name '*.Plo' -o -name '*.Po' | grep . && return 1 117 return 0 118} 119 120check_distclean () 121{ 122 # "make distcleancheck" can only run from a VPATH build. 123 if test $vpath = no; then 124 make_ok distclean && check_no_depfiles 125 else 126 $MAKE distcleancheck 127 fi 128} 129 130cat > configure.ac <<END 131AC_INIT([$me], [1.0]) 132AC_CONFIG_AUX_DIR([build-aux]) 133AM_INIT_AUTOMAKE([subdir-objects]) 134AC_PROG_CC 135AM_PROG_AR 136$(if test $depcomp_with_libtool = yes; then 137 echo AC_PROG_LIBTOOL 138 else 139 echo AC_PROG_RANLIB 140 fi) 141AC_CONFIG_FILES([Makefile src/Makefile]) 142AC_OUTPUT 143END 144 145mkdir build-aux sub src src/sub2 146 147case $depcomp_with_libtool in 148 yes) 149 po=Plo objext=lo a=la 150 normalized_target=libfoo_la 151 # On platforms requiring that no undefined symbols exist in order 152 # to build shared libraries (e.g. Windows DLLs), you have to 153 # explicitly declare that the libtool library you are building 154 # does not actually have any undefined symbols, for libtool to 155 # even try to build it as a shared library. Without that 156 # explicit declaration, libtool falls back to a static library 157 # only, regardless of any --enable-shared flags etc. 158 LIBPRIMARY=LTLIBRARIES LINKADD=LIBADD NOUNDEF=-no-undefined 159 libbaz_ldflags="libbaz_${a}_LDFLAGS = $NOUNDEF" 160 echo lib_LTLIBRARIES = libfoo.la >> Makefile.am 161 make_ok () 162 { 163 run_make -M -- ${1+"$@"} 164 $FGREP 'unknown directive' output && return 1 165 rm -f output 166 # Checks for stray files possibly left around by less common 167 # depmodes. 168 find . -name '*.[ud]' | grep . && return 1 169 return 0 170 } 171 ;; 172 no) 173 po=Po objext='$(OBJEXT)' a=a 174 normalized_target=foo 175 LIBPRIMARY=LIBRARIES LINKADD=LDADD NOUNDEF= 176 libbaz_ldflags= 177 echo bin_PROGRAMS = foo >> Makefile.am 178 make_ok () 179 { 180 $MAKE ${1+"$@"} 181 } 182 ;; 183 *) 184 fatal_ "invalid value '$depcomp_with_libtool' for variable" \ 185 "\$depcomp_with_libtool" 186 ;; 187esac 188 189cat >> Makefile.am <<END 190SUBDIRS = src 191# We include subfoo only to be sure that the munging in depcomp 192# doesn't remove too much from the object file name. 193${normalized_target}_SOURCES = foo.c sub/subfoo.c foo.h sub/subfoo.h 194${normalized_target}_LDFLAGS = $NOUNDEF 195${normalized_target}_${LINKADD} = src/libbaz.$a 196 197.PHONY: grep-test 198grep-test: 199## For debugging. 200 cat \$(DEPDIR)/foo.$po || : 201 cat sub/\$(DEPDIR)/subfoo.$po || : 202 cat src/\$(DEPDIR)/baz.$po || : 203 cat src/sub2/\$(DEPDIR)/sub2foo.$po || : 204## Checks are done here. 205 grep '^foo.$objext.*:' \$(DEPDIR)/foo.$po 206 grep '^sub/subfoo\.$objext.*:' sub/\$(DEPDIR)/subfoo.$po 207 grep '^baz\.$objext.*:' src/\$(DEPDIR)/baz.$po 208 grep '^sub2/sub2foo\.$objext.*:' src/sub2/\$(DEPDIR)/sub2foo.$po 209END 210 211cat > src/Makefile.am <<END 212noinst_${LIBPRIMARY} = libbaz.$a 213# We include sub2foo only to be sure that the munging in depcomp 214# doesn't remove too much from the object file name. 215libbaz_${a}_SOURCES = baz.c sub2/sub2foo.c baz.h sub2/sub2foo.h 216$libbaz_ldflags 217END 218 219cat > foo.c <<'END' 220#include "foo.h" 221#include "src/baz.h" 222#include <stdlib.h> 223int main (void) 224{ 225 printf ("foo bar\n"); 226 exit (EXIT_SUCCESS + subfoo () + baz ()); 227} 228END 229 230cat > foo.h <<'END' 231#include <stdio.h> 232#include "sub/subfoo.h" 233END 234 235cat > sub/subfoo.c <<'END' 236#include "sub/subfoo.h" 237int subfoo (void) { return 0; } 238END 239 240echo '/* empty */' > src/sub2/sub2foo.h 241 242cat > sub/subfoo.h <<'END' 243#include <stdio.h> 244extern int subfoo (void); 245END 246 247cat > src/baz.c <<'END' 248#include "baz.h" 249int baz (void) { return 0; } 250END 251 252cat > src/baz.h <<'END' 253extern int baz (void); 254END 255 256cat > src/sub2/sub2foo.c <<'END' 257#include "sub2foo.h" 258int sub2foo (void) { return 0; } 259END 260 261test $depcomp_with_libtool = no || libtoolize \ 262 || fatal_ "libtoolize failed" 263$ACLOCAL && $AUTOCONF && $AUTOMAKE -a \ 264 || fatal_ "autotools failed" 265test -f build-aux/depcomp \ 266 || fatal_ "depcomp script not installed" 267 268# To offer extra coverage for the depmodes (like "aix" of "hp2") where the 269# name of the compiler-generated depfiles can depend on whether libtool is 270# in use *and* on which kind of libraries libtool is building (static, 271# shared, or both), we would like to run the libtool-oriented tests thrice: 272# once after having run configure with the '--disable-shared' option, once 273# after having run it with the '--enable-shared' options, and once by 274# leaving it to configure to automatically select which kind of library (or 275# libraries) to build. 276# 277# But doing such three-fold checks unconditionally for all the depmodes 278# would slow down the already too slow libtool tests unacceptably (up to a 279# 150-200% factor), with no real gain in coverage for most of the depmodes. 280# So, since the depmodes that would benefit from the extra tests are never 281# forced to configure in out tests below, but can only be automatically 282# selected by '--enable-dependency-tracking', we make this threefold check 283# only in this later case. 284 285if test $depmode,$depcomp_with_libtool = auto,yes; then 286 do_all_tests () 287 { 288 do_test default 289 do_test noshared --disable-shared 290 do_test nostatic --disable-static 291 } 292else 293 do_all_tests () { do_test; } 294fi 295 296case $depmode in 297 auto) 298 displayed_depmode='..*' # At least one character long. 299 cfg_deptrack=--enable-dependency-tracking ;; 300 disabled) 301 displayed_depmode=none 302 cfg_deptrack=--disable-dependency-tracking ;; 303 *) 304 displayed_depmode="(cached) $depmode" 305 cfg_deptrack="$cachevar=$depmode" 306 # Sanity check: ensure the cache variable we force is truly 307 # used by configure. 308 $FGREP $cachevar configure \ 309 || fatal_ "configure lacks required cache variable '$cachevar'";; 310esac 311 312cd_top 313 314do_test () 315{ 316 cd_top 317 if test $vpath = no; then 318 pfx="in-tree build" 319 else 320 pfx="$vpath VPATH" 321 fi 322 if test $# -gt 0; then 323 subdir=$1; shift 324 pfx="$pfx, $subdir" 325 test -d $subdir || mkdir $subdir || fatal_ "creating directory $subdir" 326 cd $subdir 327 fi 328 pfx="[$pfx]" 329 case $vpath in 330 simple) 331 mkdir -p vpath-simple/build 332 cd vpath-simple/build 333 setup_srcdir .. 334 ;; 335 long) 336 mkdir -p vpath-long/src vpath-long/wrk 337 cd vpath-long/wrk 338 setup_srcdir ../src/$longpath 339 ;; 340 absolute) 341 mkdir -p vpath-abs/build 342 cd vpath-abs/build 343 absdir=$(cd .. && pwd) || fatal_ "getting absolute directory" 344 setup_srcdir "$absdir/vpath-abs" 345 unset absdir 346 ;; 347 no) 348 mkdir intree 349 cd intree 350 setup_srcdir . 351 ;; 352 *) 353 fatal_ "invalid value '$vpath' for variable \$vpath" 354 ;; 355 esac 356 357 command_ok_ \ 358 "$pfx configure" \ 359 "$srcdir/configure" $cfg_deptrack ${1+"$@"} >stdout 360 cat stdout 361 362 command_ok_ \ 363 "$pfx right depmode selected" \ 364 grep "^checking dependency style .*\.\.\. $displayed_depmode$" stdout 365 rm -f stdout 366 367 command_ok_ "$pfx simple make" make_ok 368 # Some bugs in VPATH builds only kick in during a rebuild. 369 command_ok_ "$pfx clean & rebuild" eval '$MAKE clean && make_ok' 370 371 if test $depmode = disabled; then 372 command_ok_ "$pfx no dependency files generated" check_no_depfiles 373 r=ok \ 374 && grep "[ $tab]depmode=none" Makefile \ 375 && rewrite "$srcdir"/src/sub2/sub2foo.h echo 'choke me' \ 376 && delete "$srcdir"/sub/subfoo.h \ 377 && make_ok \ 378 || r='not ok' 379 result_ "$r" "$pfx dependency tracking is truly disabled" 380 elif grep "[ $tab]depmode=none" Makefile; then 381 skip_row_ 2 -r "automatic dependency tracking couldn't be activated" 382 else 383 command_ok_ "$pfx generated $po files look correct" $MAKE grep-test 384 r=ok \ 385 && : "Some checks in the subdir." \ 386 && $sleep \ 387 && : "Ensure rebuild rules really kick in." \ 388 && rewrite "$srcdir"/src/sub2/sub2foo.h echo 'choke me' \ 389 && cd src \ 390 && not $MAKE \ 391 && cd .. \ 392 && : "Ensure the deleted header bug is fixed." \ 393 && delete "$srcdir"/src/sub2/sub2foo.h \ 394 && edit "$srcdir"/src/sub2/sub2foo.c -e 1d \ 395 && cd src \ 396 && make_ok \ 397 && : "Now do similar checks for the parent directory." \ 398 && cd .. \ 399 && rewrite "$srcdir"/sub/subfoo.h echo 'choke me' \ 400 && not $MAKE \ 401 && delete "$srcdir"/sub/subfoo.h \ 402 && edit "$srcdir"/sub/subfoo.c -e 1d \ 403 && edit "$srcdir"/foo.h -e 2d \ 404 && make_ok \ 405 || r='not ok' 406 result_ "$r" "$pfx dependency tracking works" 407 fi 408 409 command_ok_ "$pfx make distclean" check_distclean 410 cd_top 411} 412 413for vpath in no simple long absolute; do 414 do_all_tests 415done 416 417: 418