From 36fd44a7d7f3f5d9d6d0691d3fb9fc00a04e8377 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Wed, 23 Jul 2003 21:04:17 +0000 Subject: [PATCH] * automake.in (handle_multilib): Register all-multi. (file_contents_internal): Insert n when concatenating actions from "factored" rules. * lib/config-ml.in: New file, from GCC, including a patch from Ralf Corsepius (see GCC's PR 11526). * lib/symlink-tree.in: New file, from GCC. * lib/Makefile.am (dist_script_DATA): Add config-ml.in and symlink-tree. * lib/am/clean.am (distclean-generic): Do not delete Makefile here... (distclean, maintainer-clean): ... do it here. * lib/am/depend.am (distclean-depend): Likewise, replace by (distclean, maintainer-clean): ... these. * lib/am/multilib.am (all-recursive, install-recursive, mostlyclean-recursive, clean-recursive, distclean-recursive, maintainer-clean-recursive): Remove these rules. (mostlyclean-am, clean-am, distclean-am, maintainer-clean-am): Replace by ... (mostlyclean, clean, distclean, maintainer-clean): ... these. (all-am): Remove, done in handle_multilib. (install-am): Replace by ... (install-exec-am): ... this. * tests/Makefile.am (TESTS): Add multlib.test. * tests/multlib.test: New file, based on a test case by Ralf Corsepius --- ChangeLog | 27 ++ automake.in | 14 +- lib/Makefile.am | 3 +- lib/Makefile.in | 9 +- lib/am/clean.am | 16 +- lib/am/depend.am | 10 +- lib/am/multilib.am | 36 +-- lib/config-ml.in | 852 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/symlink-tree | 53 ++++ tests/Makefile.am | 1 + tests/Makefile.in | 5 +- tests/multlib.test | 139 +++++++++ 12 files changed, 1129 insertions(+), 36 deletions(-) create mode 100644 lib/config-ml.in create mode 100755 lib/symlink-tree create mode 100755 tests/multlib.test diff --git a/ChangeLog b/ChangeLog index d4c232b..e766477 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2003-07-23 Alexandre Duret-Lutz + + * automake.in (handle_multilib): Register all-multi. + (file_contents_internal): Insert \n when concatenating actions + from "factored" rules. + * lib/config-ml.in: New file, from GCC, including a patch + from Ralf Corsepius (see GCC's PR 11526). + * lib/symlink-tree.in: New file, from GCC. + * lib/Makefile.am (dist_script_DATA): Add config-ml.in and + symlink-tree. + * lib/am/clean.am (distclean-generic): Do not delete Makefile here... + (distclean, maintainer-clean): ... do it here. + * lib/am/depend.am (distclean-depend): Likewise, replace by + (distclean, maintainer-clean): ... these. + * lib/am/multilib.am (all-recursive, install-recursive, + mostlyclean-recursive, clean-recursive, distclean-recursive, + maintainer-clean-recursive): Remove these rules. + (mostlyclean-am, clean-am, distclean-am, maintainer-clean-am): Replace + by ... + (mostlyclean, clean, distclean, maintainer-clean): ... these. + (all-am): Remove, done in handle_multilib. + (install-am): Replace by ... + (install-exec-am): ... this. + * tests/Makefile.am (TESTS): Add multlib.test. + * tests/multlib.test: New file, based on a test case by + Ralf Corsepius + 2003-07-23 Tom Tromey * lib/missing (autom4te): Typo. diff --git a/automake.in b/automake.in index 98c2644..4fb66e8 100755 --- a/automake.in +++ b/automake.in @@ -3329,9 +3329,10 @@ sub handle_tags # Handle multilib support. sub handle_multilib { - if ($seen_multilib && $relative_dir eq '.') + if ($seen_multilib && $relative_dir eq '.') { - $output_rules .= &file_contents ('multilib', new Automake::Location); + $output_rules .= &file_contents ('multilib', new Automake::Location); + push (@all, 'all-multi'); } } @@ -6402,7 +6403,14 @@ sub file_contents_internal ($$$%) if (defined $dependencies{$_} && $cond != FALSE) { &depend ($_, @deps); - $actions{$_} .= $actions; + if ($actions{$_}) + { + $actions{$_} .= "\n$actions"; + } + else + { + $actions{$_} = $actions; + } } else { diff --git a/lib/Makefile.am b/lib/Makefile.am index 20df449..63a6db1 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -28,7 +28,8 @@ dist_pkgvdata_DATA = COPYING INSTALL texinfo.tex ansi2knr.c ansi2knr.1 ## what we want. So we make them executable by hand. scriptdir = $(pkgvdatadir) dist_script_DATA = config.guess config.sub install-sh mdate-sh missing \ -mkinstalldirs elisp-comp ylwrap acinstall depcomp compile py-compile + mkinstalldirs elisp-comp ylwrap acinstall depcomp compile py-compile \ + config-ml.in symlink-tree install-data-hook: @$(POST_INSTALL) diff --git a/lib/Makefile.in b/lib/Makefile.in index 363acb8..b107357 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -105,7 +105,8 @@ dist_pkgvdata_DATA = COPYING INSTALL texinfo.tex ansi2knr.c ansi2knr.1 scriptdir = $(pkgvdatadir) dist_script_DATA = config.guess config.sub install-sh mdate-sh missing \ -mkinstalldirs elisp-comp ylwrap acinstall depcomp compile py-compile + mkinstalldirs elisp-comp ylwrap acinstall depcomp compile py-compile \ + config-ml.in symlink-tree subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -365,7 +366,7 @@ mostlyclean-generic: clean-generic: distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -375,7 +376,7 @@ clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive - + -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive @@ -399,7 +400,7 @@ install-man: installcheck-am: installcheck-local maintainer-clean: maintainer-clean-recursive - + -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive diff --git a/lib/am/clean.am b/lib/am/clean.am index 1b0e399..b344e14 100644 --- a/lib/am/clean.am +++ b/lib/am/clean.am @@ -30,9 +30,19 @@ clean-generic: distclean-am: distclean-generic clean-am distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f $(CONFIG_CLEAN_FILES) %DISTCLEAN_RMS% +## Makefiles and their dependencies cannot be cleaned by +## an -am dependency, because that would prevent other distclean +## dependencies from calling make recursively. (The multilib +## cleaning rules do this.) +## +## If you change distclean here, you probably also want to change +## maintainer-clean below. +distclean: + -rm -f Makefile + maintainer-clean-am: maintainer-clean-generic distclean-am maintainer-clean-generic: ## FIXME: shouldn't we really print these messages before running @@ -41,6 +51,10 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." %MAINTAINER_CLEAN_RMS% +## See comment for distclean. +maintainer-clean: + -rm -f Makefile + .PHONY: clean mostlyclean distclean maintainer-clean \ clean-generic mostlyclean-generic distclean-generic maintainer-clean-generic diff --git a/lib/am/depend.am b/lib/am/depend.am index 5e24ec1..be4eccc 100644 --- a/lib/am/depend.am +++ b/lib/am/depend.am @@ -17,8 +17,12 @@ ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ## 02111-1307, USA. -distclean-am: distclean-depend -distclean-depend: +## Depdirs's files are dependency of this Makefile, so we should never +## erase them in -am or -recursive rules; that would prevent any other +## rules from being recursive (for instance multilib clean rules are +## recursive). +distclean: -rm -rf %DEPDIRS% -.PHONY: distclean-depend +maintainer-clean: + -rm -rf %DEPDIRS% diff --git a/lib/am/multilib.am b/lib/am/multilib.am index c232c75..a0d7b19 100644 --- a/lib/am/multilib.am +++ b/lib/am/multilib.am @@ -30,18 +30,6 @@ install-multi: .PHONY: all-multi install-multi -if %?SUBDIRS% -all-recursive: all-multi -install-recursive: install-multi -else !%?SUBDIRS% -all-am: all-multi -install-am: install-multi -endif !%?SUBDIRS% - -mostlyclean-am: mostlyclean-multi -clean-am: clean-multi -distclean-am: distclean-multi -maintainer-clean-am: maintainer-clean-multi mostlyclean-multi: $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean @@ -54,15 +42,17 @@ maintainer-clean-multi: .PHONY: mostlyclean-multi clean-multi distclean-multi maintainer-clean-multi +install-exec-am: install-multi +## No uninstall rule? + -if %?SUBDIRS% -mostlyclean-recursive: mostlyclean-multi -clean-recursive: clean-multi -distclean-recursive: distclean-multi -maintainer-clean-recursive: maintainer-clean-multi -else !%?SUBDIRS% -mostlyclean-am: mostlyclean-multi -clean-am: clean-multi -distclean-am: distclean-multi -maintainer-clean-am: maintainer-clean-multi -endif !%?SUBDIRS% +## These cleaning rules are recursive. They should not be +## registered as dependencies of *-am rules. For instance +## otherwise running `make clean' would cause both +## clean-multi and mostlyclean-multi to be run, while only +## clean-multi is really expected (since clean-multi recursively +## call clean, it already do the job of mostlyclean). +mostlyclean: mostlyclean-multi +clean: clean-multi +distclean: distclean-multi +maintainer-clean: maintainer-clean-multi diff --git a/lib/config-ml.in b/lib/config-ml.in new file mode 100644 index 0000000..9368839 --- /dev/null +++ b/lib/config-ml.in @@ -0,0 +1,852 @@ +# Configure fragment invoked in the post-target section for subdirs +# wanting multilib support. +# +# It is advisable to support a few --enable/--disable options to let the +# user select which libraries s/he really wants. +# +# Subdirectories wishing to use multilib should put the following lines +# in the "post-target" section of configure.in. +# +# if [ "${srcdir}" = "." ] ; then +# if [ "${with_target_subdir}" != "." ] ; then +# . ${with_multisrctop}../../config-ml.in +# else +# . ${with_multisrctop}../config-ml.in +# fi +# else +# . ${srcdir}/../config-ml.in +# fi +# +# +# Things are complicated because 6 separate cases must be handled: +# 2 (native, cross) x 3 (absolute-path, relative-not-dot, dot) = 6. +# +# srcdir=. is special. It must handle make programs that don't handle VPATH. +# To implement this, a symlink tree is built for each library and for each +# multilib subdir. +# +# The build tree is layed out as +# +# ./ +# newlib +# m68020/ +# newlib +# m68881/ +# newlib +# +# The nice feature about this arrangement is that inter-library references +# in the build tree work without having to care where you are. Note that +# inter-library references also work in the source tree because symlink trees +# are built when srcdir=. +# +# Unfortunately, trying to access the libraries in the build tree requires +# the user to manually choose which library to use as GCC won't be able to +# find the right one. This is viewed as the lesser of two evils. +# +# Configure variables: +# ${with_target_subdir} = "." for native, or ${target_alias} for cross. +# Set by top level Makefile. +# ${with_multisrctop} = how many levels of multilibs there are in the source +# tree. It exists to handle the case of configuring in the source tree: +# ${srcdir} is not constant. +# ${with_multisubdir} = name of multilib subdirectory (eg: m68020/m68881). +# +# Makefile variables: +# MULTISRCTOP = number of multilib levels in source tree (+1 if cross) +# (FIXME: note that this is different than ${with_multisrctop}. Check out.). +# MULTIBUILDTOP = number of multilib levels in build tree +# MULTIDIRS = list of multilib subdirs (eg: m68000 m68020 ...) +# (only defined in each library's main Makefile). +# MULTISUBDIR = installed subdirectory name with leading '/' (eg: /m68000) +# (only defined in each multilib subdir). + +# FIXME: Multilib is currently disabled by default for everything other than +# newlib. It is up to each target to turn on multilib support for the other +# libraries as desired. + +# Autoconf incoming variables: +# srcdir, host, ac_configure_args +# +# We *could* figure srcdir and host out, but we'd have to do work that +# our caller has already done to figure them out and requiring these two +# seems reasonable. +# Note that `host' in this case is GCC's `target'. Target libraries are +# configured for a particular host. + +Makefile=${ac_file-Makefile} +ml_config_shell=${CONFIG_SHELL-/bin/sh} +ml_arguments="${ac_configure_args}" +ml_realsrcdir=${srcdir} + +# Scan all the arguments and set all the ones we need. + +ml_verbose=--verbose +for option in ${ml_arguments} +do + case $option in + \'--*\' ) eval option="$option" ;; + --*) ;; + -*) option=-$option ;; + esac + + case $option in + --*=*) + optarg=`echo $option | sed -e 's/^[^=]*=//'` + ;; + esac + + case $option in + --disable-*) + enableopt=`echo ${option} | sed 's:^--disable-:enable_:;s:-:_:g'` + eval $enableopt=no + ;; + --enable-*) + case "$option" in + *=*) ;; + *) optarg=yes ;; + esac + enableopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'` + eval $enableopt="$optarg" + ;; + --norecursion | --no*) + ml_norecursion=yes + ;; + --silent | --sil* | --quiet | --q*) + ml_verbose=--silent + ;; + --verbose | --v | --verb*) + ml_verbose=--verbose + ;; + --with-*) + case "$option" in + *=*) ;; + *) optarg=yes ;; + esac + withopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'` + eval $withopt="$optarg" + ;; + --without-*) + withopt=`echo ${option} | sed 's:^--::;s:out::;s:-:_:g'` + eval $withopt=no + ;; + esac +done + +# Only do this if --enable-multilib. +if [ "${enable_multilib}" = yes ]; then + +# Compute whether this is the library's top level directory +# (ie: not a multilib subdirectory, and not a subdirectory like newlib/src). +# ${with_multisubdir} tells us we're in the right branch, but we could be +# in a subdir of that. +# ??? The previous version could void this test by separating the process into +# two files: one that only the library's toplevel configure.in ran (to +# configure the multilib subdirs), and another that all configure.in's ran to +# update the Makefile. It seemed reasonable to collapse all multilib support +# into one file, but it does leave us with having to perform this test. +ml_toplevel_p=no +if [ -z "${with_multisubdir}" ]; then + if [ "${srcdir}" = "." ]; then + # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}. + # ${with_target_subdir} = "." for native, otherwise target alias. + if [ "${with_target_subdir}" = "." ]; then + if [ -f ${ml_realsrcdir}/../config-ml.in ]; then + ml_toplevel_p=yes + fi + else + if [ -f ${ml_realsrcdir}/../../config-ml.in ]; then + ml_toplevel_p=yes + fi + fi + else + # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}. + if [ -f ${ml_realsrcdir}/../config-ml.in ]; then + ml_toplevel_p=yes + fi + fi +fi + +# If this is the library's top level directory, set multidirs to the +# multilib subdirs to support. This lives at the top because we need +# `multidirs' set right away. + +if [ "${ml_toplevel_p}" = yes ]; then + +multidirs= +for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do + dir=`echo $i | sed -e 's/;.*$//'` + if [ "${dir}" = "." ]; then + true + else + if [ -z "${multidirs}" ]; then + multidirs="${dir}" + else + multidirs="${multidirs} ${dir}" + fi + fi +done + +# Target libraries are configured for the host they run on, so we check +# $host here, not $target. + +case "${host}" in +arc-*-elf*) + if [ x$enable_biendian != xyes ] + then + old_multidirs=${multidirs} + multidirs="" + for x in ${old_multidirs}; do + case "${x}" in + *be*) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + ;; +arm-*-*) + if [ x"$enable_fpu" = xno ] + then + old_multidirs=${multidirs} + multidirs="" + for x in ${old_multidirs}; do + case "${x}" in + *fpu*) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x"$enable_26bit" = xno ] + then + old_multidirs=${multidirs} + multidirs="" + for x in ${old_multidirs}; do + case "${x}" in + *26bit*) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x"$enable_underscore" = xno ] + then + old_multidirs=${multidirs} + multidirs="" + for x in ${old_multidirs}; do + case "${x}" in + *under*) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x"$enable_interwork" = xno ] + then + old_multidirs=${multidirs} + multidirs="" + for x in ${old_multidirs}; do + case "${x}" in + *interwork*) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_biendian = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *le* ) : ;; + *be* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x"$enable_nofmult" = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *nofmult* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + ;; +m68*-*-*) + if [ x$enable_softfloat = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *soft-float* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_m68881 = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *m68881* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_m68000 = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *m68000* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_m68020 = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *m68020* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + ;; +mips*-*-*) + if [ x$enable_single_float = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *single* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_biendian = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *el* ) : ;; + *eb* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_softfloat = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *soft-float* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + case " $multidirs " in + *" mabi=64 "*) + # We will not be able to create libraries with -mabi=64 if + # we cannot even link a trivial program. It usually + # indicates the 64bit libraries are missing. + if echo 'main() {}' > conftest.c && + ${CC-gcc} -mabi=64 conftest.c -o conftest; then + : + else + echo Could not link program with -mabi=64, disabling it. + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *mabi=64* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + rm -f conftest.c conftest + ;; + esac + ;; +powerpc*-*-* | rs6000*-*-*) + if [ x$enable_aix64 = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *ppc64* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_pthread = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *pthread* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_softfloat = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *soft-float* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_powercpu = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + power | */power | */power/* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_powerpccpu = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *powerpc* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_powerpcos = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *mcall-linux* | *mcall-solaris* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_biendian = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *mlittle* | *mbig* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + if [ x$enable_sysv = xno ] + then + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *mcall-sysv* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + ;; +sparc*-*-*) + case " $multidirs " in + *" m64 "*) + # We will not be able to create libraries with -m64 if + # we cannot even link a trivial program. It usually + # indicates the 64bit libraries are missing. + if echo 'main() {}' > conftest.c && + ${CC-gcc} -m64 conftest.c -o conftest; then + : + else + echo Could not link program with -m64, disabling it. + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + *m64* ) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + fi + rm -f conftest.c conftest + ;; + esac + ;; +esac + +# Remove extraneous blanks from multidirs. +# Tests like `if [ -n "$multidirs" ]' require it. +multidirs=`echo "$multidirs" | sed -e 's/^[ ][ ]*//' -e 's/[ ][ ]*$//' -e 's/[ ][ ]*/ /g'` + +# Add code to library's top level makefile to handle building the multilib +# subdirs. + +cat > Multi.tem <<\EOF + +PWD=$${PWDCMD-pwd} + +# FIXME: There should be an @-sign in front of the `if'. +# Leave out until this is tested a bit more. +multi-do: + if [ -z "$(MULTIDIRS)" ]; then \ + true; \ + else \ + rootpre=`${PWD}`/; export rootpre; \ + srcrootpre=`cd $(srcdir); ${PWD}`/; export srcrootpre; \ + lib=`echo $${rootpre} | sed -e 's,^.*/\([^/][^/]*\)/$$,\1,'`; \ + compiler="$(CC)"; \ + for i in `$${compiler} --print-multi-lib 2>/dev/null`; do \ + dir=`echo $$i | sed -e 's/;.*$$//'`; \ + if [ "$${dir}" = "." ]; then \ + true; \ + else \ + if [ -d ../$${dir}/$${lib} ]; then \ + flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \ + if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) \ + CFLAGS="$(CFLAGS) $${flags}" \ + prefix="$(prefix)" \ + exec_prefix="$(exec_prefix)" \ + GCJFLAGS="$(GCJFLAGS) $${flags}" \ + CXXFLAGS="$(CXXFLAGS) $${flags}" \ + LIBCFLAGS="$(LIBCFLAGS) $${flags}" \ + LIBCXXFLAGS="$(LIBCXXFLAGS) $${flags}" \ + LDFLAGS="$(LDFLAGS) $${flags}" \ + DESTDIR="$(DESTDIR)" \ + INSTALL="$(INSTALL)" \ + INSTALL_DATA="$(INSTALL_DATA)" \ + INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \ + INSTALL_SCRIPT="$(INSTALL_SCRIPT)" \ + $(DO)); then \ + true; \ + else \ + exit 1; \ + fi; \ + else true; \ + fi; \ + fi; \ + done; \ + fi + +# FIXME: There should be an @-sign in front of the `if'. +# Leave out until this is tested a bit more. +multi-clean: + if [ -z "$(MULTIDIRS)" ]; then \ + true; \ + else \ + lib=`${PWD} | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \ + for dir in Makefile $(MULTIDIRS); do \ + if [ -f ../$${dir}/$${lib}/Makefile ]; then \ + if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) $(DO)); \ + then true; \ + else exit 1; \ + fi; \ + else true; \ + fi; \ + done; \ + fi +EOF + +cat ${Makefile} Multi.tem > Makefile.tem +rm -f ${Makefile} Multi.tem +mv Makefile.tem ${Makefile} + +fi # ${ml_toplevel_p} = yes + +if [ "${ml_verbose}" = --verbose ]; then + echo "Adding multilib support to Makefile in ${ml_realsrcdir}" + if [ "${ml_toplevel_p}" = yes ]; then + echo "multidirs=${multidirs}" + fi + echo "with_multisubdir=${with_multisubdir}" +fi + +if [ "${srcdir}" = "." ]; then + if [ "${with_target_subdir}" != "." ]; then + ml_srcdotdot="../" + else + ml_srcdotdot="" + fi +else + ml_srcdotdot="" +fi + +if [ -z "${with_multisubdir}" ]; then + ml_subdir= + ml_builddotdot= + : # ml_srcdotdot= # already set +else + ml_subdir="/${with_multisubdir}" + # The '[^/][^/]*' appears that way to work around a SunOS sed bug. + ml_builddotdot=`echo ${with_multisubdir} | sed -e 's:[^/][^/]*:..:g'`/ + if [ "$srcdir" = "." ]; then + ml_srcdotdot=${ml_srcdotdot}${ml_builddotdot} + else + : # ml_srcdotdot= # already set + fi +fi + +if [ "${ml_toplevel_p}" = yes ]; then + ml_do='$(MAKE)' + ml_clean='$(MAKE)' +else + ml_do=true + ml_clean=true +fi + +# TOP is used by newlib and should not be used elsewhere for this purpose. +# MULTI{SRC,BUILD}TOP are the proper ones to use. MULTISRCTOP is empty +# when srcdir != builddir. MULTIBUILDTOP is always some number of ../'s. +# FIXME: newlib needs to be updated to use MULTI{SRC,BUILD}TOP so we can +# delete TOP. Newlib may wish to continue to use TOP for its own purposes +# of course. +# MULTIDIRS is non-empty for the cpu top level Makefile (eg: newlib/Makefile) +# and lists the subdirectories to recurse into. +# MULTISUBDIR is non-empty in each cpu subdirectory's Makefile +# (eg: newlib/h8300h/Makefile) and is the installed subdirectory name with +# a leading '/'. +# MULTIDO is used for targets like all, install, and check where +# $(FLAGS_TO_PASS) augmented with the subdir's compiler option is needed. +# MULTICLEAN is used for the *clean targets. +# +# ??? It is possible to merge MULTIDO and MULTICLEAN into one. They are +# currently kept separate because we don't want the *clean targets to require +# the existence of the compiler (which MULTIDO currently requires) and +# therefore we'd have to record the directory options as well as names +# (currently we just record the names and use --print-multi-lib to get the +# options). + +sed -e "s:^TOP[ ]*=[ ]*\([./]*\)[ ]*$:TOP = ${ml_builddotdot}\1:" \ + -e "s:^MULTISRCTOP[ ]*=.*$:MULTISRCTOP = ${ml_srcdotdot}:" \ + -e "s:^MULTIBUILDTOP[ ]*=.*$:MULTIBUILDTOP = ${ml_builddotdot}:" \ + -e "s:^MULTIDIRS[ ]*=.*$:MULTIDIRS = ${multidirs}:" \ + -e "s:^MULTISUBDIR[ ]*=.*$:MULTISUBDIR = ${ml_subdir}:" \ + -e "s:^MULTIDO[ ]*=.*$:MULTIDO = $ml_do:" \ + -e "s:^MULTICLEAN[ ]*=.*$:MULTICLEAN = $ml_clean:" \ + ${Makefile} > Makefile.tem +rm -f ${Makefile} +mv Makefile.tem ${Makefile} + +# If this is the library's top level, configure each multilib subdir. +# This is done at the end because this is the loop that runs configure +# in each multilib subdir and it seemed reasonable to finish updating the +# Makefile before going on to configure the subdirs. + +if [ "${ml_toplevel_p}" = yes ]; then + +# We must freshly configure each subdirectory. This bit of code is +# actually partially stolen from the main configure script. FIXME. + +if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then + + if [ "${ml_verbose}" = --verbose ]; then + echo "Running configure in multilib subdirs ${multidirs}" + echo "pwd: `${PWDCMD-pwd}`" + fi + + ml_origdir=`${PWDCMD-pwd}` + ml_libdir=`echo $ml_origdir | sed -e 's,^.*/,,'` + # cd to top-level-build-dir/${with_target_subdir} + cd .. + + for ml_dir in ${multidirs}; do + + if [ "${ml_verbose}" = --verbose ]; then + echo "Running configure in multilib subdir ${ml_dir}" + echo "pwd: `${PWDCMD-pwd}`" + fi + + if [ -d ${ml_dir} ]; then true; else + # ``mkdir -p ${ml_dir}'' See also mkinstalldirs. + pathcomp="" + for d in `echo ":${ml_dir}" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`; do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$? + fi + if test ! -d "$pathcomp"; then + exit $lasterr + fi + pathcomp="$pathcomp/" + done + fi + if [ -d ${ml_dir}/${ml_libdir} ]; then true; else mkdir ${ml_dir}/${ml_libdir}; fi + + # Eg: if ${ml_dir} = m68000/m68881, dotdot = ../../ + dotdot=../`echo ${ml_dir} | sed -e 's|[^/]||g' -e 's|/|../|g'` + + case ${srcdir} in + ".") + echo Building symlink tree in `${PWDCMD-pwd}`/${ml_dir}/${ml_libdir} + if [ "${with_target_subdir}" != "." ]; then + ml_unsubdir="../" + else + ml_unsubdir="" + fi + (cd ${ml_dir}/${ml_libdir}; + ../${dotdot}${ml_unsubdir}symlink-tree ../${dotdot}${ml_unsubdir}${ml_libdir} "") + if [ -f ${ml_dir}/${ml_libdir}/Makefile ]; then + if [ x"${MAKE}" = x ]; then + (cd ${ml_dir}/${ml_libdir}; make distclean) + else + (cd ${ml_dir}/${ml_libdir}; ${MAKE} distclean) + fi + fi + ml_newsrcdir="." + ml_srcdiroption= + multisrctop=${dotdot} + ;; + *) + case "${srcdir}" in + /* | [A-Za-z]:[\\/]* ) # absolute path + ml_newsrcdir=${srcdir} + ;; + *) # otherwise relative + ml_newsrcdir=${dotdot}${srcdir} + ;; + esac + ml_srcdiroption="-srcdir=${ml_newsrcdir}" + multisrctop= + ;; + esac + + case "${progname}" in + /* | [A-Za-z]:[\\/]* ) ml_recprog=${progname} ;; + *) ml_recprog=${dotdot}${progname} ;; + esac + + # FIXME: POPDIR=${PWD=`pwd`} doesn't work here. + ML_POPDIR=`${PWDCMD-pwd}` + cd ${ml_dir}/${ml_libdir} + + if [ -f ${ml_newsrcdir}/configure ]; then + ml_recprog="${ml_newsrcdir}/configure --cache-file=../config.cache" + fi + + # find compiler flag corresponding to ${ml_dir} + for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do + dir=`echo $i | sed -e 's/;.*$//'` + if [ "${dir}" = "${ml_dir}" ]; then + flags=`echo $i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'` + break + fi + done + ml_config_env='CC="${CC_}$flags" CXX="${CXX_}$flags" GCJ="${GCJ_}$flags"' + + if [ "${with_target_subdir}" = "." ]; then + CC_=$CC' ' + CXX_=$CXX' ' + GCJ_=$GCJ' ' + else + # Create a regular expression that matches any string as long + # as ML_POPDIR. + popdir_rx=`echo ${ML_POPDIR} | sed 's,.,.,g'` + CC_= + for arg in ${CC}; do + case $arg in + -[BIL]"${ML_POPDIR}"/*) + CC_="${CC_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\1/p"`' ' ;; + "${ML_POPDIR}"/*) + CC_="${CC_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;; + *) + CC_="${CC_}${arg} " ;; + esac + done + + CXX_= + for arg in ${CXX}; do + case $arg in + -[BIL]"${ML_POPDIR}"/*) + CXX_="${CXX_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;; + "${ML_POPDIR}"/*) + CXX_="${CXX_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;; + *) + CXX_="${CXX_}${arg} " ;; + esac + done + + GCJ_= + for arg in ${GCJ}; do + case $arg in + -[BIL]"${ML_POPDIR}"/*) + GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;; + "${ML_POPDIR}"/*) + GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;; + *) + GCJ_="${GCJ_}${arg} " ;; + esac + done + + if test "x${LD_LIBRARY_PATH+set}" = xset; then + LD_LIBRARY_PATH_= + for arg in `echo "$LD_LIBRARY_PATH" | tr ':' ' '`; do + case "$arg" in + "${ML_POPDIR}"/*) + arg=`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"` + ;; + esac + if test "x$LD_LIBRARY_PATH_" != x; then + LD_LIBRARY_PATH_=$LD_LIBRARY_PATH_:$arg + else + LD_LIBRARY_PATH_=$arg + fi + done + ml_config_env="$ml_config_env LD_LIBRARY_PATH=$LD_LIBRARY_PATH_" + fi + + if test "x${SHLIB_PATH+set}" = xset; then + SHLIB_PATH_= + for arg in `echo "$SHLIB_PATH" | tr ':' ' '`; do + case "$arg" in + "${ML_POPDIR}"/*) + arg=`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"` + ;; + esac + if test "x$SHLIB_PATH_" != x; then + SHLIB_PATH_=$SHLIB_PATH_:$arg + else + SHLIB_PATH_=$arg + fi + done + ml_config_env="$ml_config_env SHLIB_PATH=$SHLIB_PATH_" + fi + fi + + if eval ${ml_config_env} ${ml_config_shell} ${ml_recprog} \ + --with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \ + ${ml_arguments} ${ml_srcdiroption} ; then + true + else + exit 1 + fi + + cd ${ML_POPDIR} + + done + + cd ${ml_origdir} +fi + +fi # ${ml_toplevel_p} = yes +fi # ${enable_multilib} = yes diff --git a/lib/symlink-tree b/lib/symlink-tree new file mode 100755 index 0000000..5b18cab --- /dev/null +++ b/lib/symlink-tree @@ -0,0 +1,53 @@ +#!/bin/sh +# Create a symlink tree. +# +# Syntax: symlink-tree srcdir "ignore1 ignore2 ..." +# +# where srcdir is the directory to create a symlink tree to, +# and "ignoreN" is a list of files/directories to ignore. + +prog=$0 +srcdir=$1 +ignore="$2" + +if test $# -lt 1; then + echo "symlink-tree error: Usage: symlink-tree srcdir \"ignore1 ignore2 ...\"" + exit 1 +fi + +ignore_additional=". .. CVS" + +# If we were invoked with a relative path name, adjust ${prog} to work +# in subdirs. +case ${prog} in +/* | [A-Za-z]:[\\/]*) ;; +*) prog=../${prog} ;; +esac + +# Set newsrcdir to something subdirectories can use. +case ${srcdir} in +/* | [A-Za-z]:[\\/]*) newsrcdir=${srcdir} ;; +*) newsrcdir=../${srcdir} ;; +esac + +for f in `ls -a ${srcdir}`; do + if [ -d ${srcdir}/$f ]; then + found= + for i in ${ignore} ${ignore_additional}; do + if [ "$f" = "$i" ]; then + found=yes + fi + done + if [ -z "${found}" ]; then + echo "$f ..working in" + if [ -d $f ]; then true; else mkdir $f; fi + (cd $f; ${prog} ${newsrcdir}/$f "${ignore}") + fi + else + echo "$f ..linked" + rm -f $f + ln -s ${srcdir}/$f . + fi +done + +exit 0 diff --git a/tests/Makefile.am b/tests/Makefile.am index 0ac9689..d36edcc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -293,6 +293,7 @@ mdate3.test \ mdate4.test \ mkinst2.test \ mkinstall.test \ +multlib.test \ nobase.test \ nodef.test \ nodef2.test \ diff --git a/tests/Makefile.in b/tests/Makefile.in index d122543..dcdfd75 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -392,6 +392,7 @@ mdate3.test \ mdate4.test \ mkinst2.test \ mkinstall.test \ +multlib.test \ nobase.test \ nodef.test \ nodef2.test \ @@ -736,7 +737,7 @@ mostlyclean-generic: clean-generic: distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -746,6 +747,7 @@ clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am + -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local @@ -768,6 +770,7 @@ install-man: installcheck-am: maintainer-clean: maintainer-clean-am + -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/tests/multlib.test b/tests/multlib.test new file mode 100755 index 0000000..61c4f0a --- /dev/null +++ b/tests/multlib.test @@ -0,0 +1,139 @@ +#! /bin/sh +# Copyright (C) 2003 Free Software Foundation, Inc. +# +# This file is part of GNU Automake. +# +# GNU Automake 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. +# +# GNU Automake 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 Automake; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# Check multilib support. +# Based on a test case from Ralf Corsepius. + +required='gcc GNUmake' +. ./defs || exit 1 + +set -e + +cat >>configure.in <<'END' +AC_CONFIG_SRCDIR(libfoo/foo.c) +AC_CONFIG_AUX_DIR(.) +AC_CONFIG_SUBDIRS(libfoo) +AC_CONFIG_SUBDIRS(libbar) +AC_OUTPUT +END + +cat >mycc <<'END' +#! /bin/sh +case ${1+"$@"} in + *-print-multi-lib*) + echo ".;" + echo "debug;@g" + exit 0 ;; +esac +gcc ${1+"$@"} +END + +chmod +x mycc + +cat >Makefile.am <<'EOF' +SUBDIRS = @subdirs@ +EXTRA_DIST = config-ml.in symlink-tree +EOF + +# libfoo tests multilib supports when there are no subdirectories +# libbar tests multilib supports when there are subdirectories + +mkdir libfoo + +cat >libfoo/configure.in <<'END' +AC_PREREQ(2.57) +AC_INIT(libfoo, 0.1, nobody@localhost) +AC_CONFIG_SRCDIR(foo.c) +# Apparently it doesn't work to have auxdir=.. when +# multilib uses symlinked trees. +AC_CONFIG_AUX_DIR(.) +AM_INIT_AUTOMAKE(foreign) +AC_PROG_CC +AC_PROG_RANLIB +AM_ENABLE_MULTILIB(Makefile,[..]) +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT +END + +cat >libfoo/Makefile.am <<'END' +noinst_LIBRARIES = libfoo.a +libfoo_a_SOURCES = foo.c +END + +: > libfoo/foo.c + +mkdir libbar + +cat >libbar/configure.in <<'END' +AC_PREREQ(2.57) +AC_INIT(libbar, 0.1, nobody@localhost) +# Apparently it doesn't work to have auxdir=.. when +# multilib uses symlinked trees. +AC_CONFIG_AUX_DIR(.) +AM_INIT_AUTOMAKE(foreign) +AC_PROG_CC +AC_PROG_RANLIB +AM_ENABLE_MULTILIB(Makefile,[..]) +AC_CONFIG_FILES([Makefile sub/Makefile]) +AC_OUTPUT +END + +cat >libbar/Makefile.am <<'END' +SUBDIRS = sub +noinst_LIBRARIES = libbar.a +libbar_a_SOURCES = bar.c +END + +mkdir libbar/sub + +: >libbar/sub/Makefile.am + +: > libbar/bar.c + +cp $testsrcdir/../lib/config-ml.in . +cp $testsrcdir/../lib/symlink-tree . + +$ACLOCAL +$AUTOCONF +$AUTOMAKE --add-missing +cd libfoo +$ACLOCAL +$AUTOCONF +$AUTOMAKE --add-missing +cd ../libbar +$ACLOCAL +$AUTOCONF +$AUTOMAKE --add-missing +cd .. + + +# Check VPATH builds +mkdir build +cd build +../configure --enable-multilib CC=`pwd`/../mycc +$MAKE +$MAKE install +$MAKE distcleancheck + +# Check standard builds. +cd .. +# Why to I have to specify --with-target-subdir? +./configure --enable-multilib --with-target-subdir=. CC=`pwd`/mycc +$MAKE -- 2.7.4