Here's an experimental patch that allow conditional dependencies between
modules.
I've tested it on a patch like this one:
--- modules/strtoumax.orig Tue Apr 26 02:18:36 2011
+++ modules/strtoumax Tue Apr 26 01:11:38 2011
@@ -8,7 +8,7 @@
Depends-on:
strtoimax
-strtoull
+strtoull [test $ac_cv_func_strtoumax = no && test
$ac_cv_type_unsigned_long_long_int = yes]
inttypes
stdint
As you can see, the syntax is a bracketed shell expression that is executed
after the module's configure.ac code has run. It has to fit in one line -
no line breaks here please.
Conditional dependencies are enabled by the option --conditional-dependencies.
(If this option is not given, the condition is parsed but ignored.)
It is
- supposed to work with --create-testdir (tested),
- supposed to work with --import (not tested),
- not working with --with-tests (yields an error message).
If you get an error like
gllib/Makefile.am:137: GL_GENERATE_STDDEF_H does not appear in AM_CONDITIONAL
it is a symptom of a bug of AM_CONDITIONAL in Automake. To work around it,
make the module 'stddef' unconditional by providing it on the command line.
Please test it!
Bruno
--
In memoriam Nikolay Gikalo <http://en.wikipedia.org/wiki/Nikolay_Gikalo>
*** gnulib-tool.orig Tue Apr 26 02:25:00 2011
--- gnulib-tool Tue Apr 26 02:11:08 2011
***************
*** 223,228 ****
--- 223,232 ----
--avoid=MODULE Avoid including the given MODULE. Useful if you
have code that provides equivalent functionality.
This option can be repeated.
+ --conditional-dependencies
+ Support conditional dependencies (experimental,
+ may save configure time and object code, not
+ compatible with --with-tests).
--libtool Use libtool rules.
--no-libtool Don't use libtool rules.
***************
*** 912,917 ****
--- 916,923 ----
# - excl_unportable_tests true if --without-unportable-tests was given, blank
# otherwise
# - avoidlist list of modules to avoid, from --avoid
+ # - cond_dependencies true if --conditional-dependencies was given, blank
+ # otherwise
# - lgpl yes or a number if --lgpl was given, blank otherwise
# - makefile_name from --makefile-name
# - libtool true if --libtool was given, false if --no-libtool was
***************
*** 953,958 ****
--- 959,965 ----
excl_privileged_tests=
excl_unportable_tests=
avoidlist=
+ cond_dependencies=
lgpl=
makefile_name=
libtool=
***************
*** 1002,1008 ****
--extract-* )
mode=`echo "X$1" | sed -e 's/^X--//'`
shift ;;
! --copy-file | --copy-fil | --copy-fi | --copy-f | --copy- | --copy | --cop | --co )
mode=copy-file
shift ;;
--dir )
--- 1009,1015 ----
--extract-* )
mode=`echo "X$1" | sed -e 's/^X--//'`
shift ;;
! --copy-file | --copy-fil | --copy-fi | --copy-f | --copy- | --copy | --cop )
mode=copy-file
shift ;;
--dir )
***************
*** 1153,1158 ****
--- 1160,1168 ----
arg=`echo "X$1" | sed -e 's/^X--avoid=//'`
func_append avoidlist " $arg"
shift ;;
+ --conditional-dependencies | --conditional-dependencie | --conditional-dependenci | --conditional-dependenc | --conditional-dependen | --conditional-depende | --conditional-depend | --conditional-depen | --conditional-depe | --conditional-dep | --conditional-de | --conditional-d | --conditional- | --conditional | --conditiona | --condition | --conditio | --conditi | --condit | --condi | --cond | --con)
+ cond_dependencies=true
+ shift ;;
--lgpl )
lgpl=yes
shift ;;
***************
*** 1298,1303 ****
--- 1308,1317 ----
if test -z "$pobase" && test -n "$po_domain"; then
func_warning "--po-domain has no effect without a --po-base option"
fi
+ if test -n "$cond_dependencies" && test -n "$inctests"; then
+ echo "gnulib-tool: option --conditional-dependencies is not supported with --with-tests" 1>&2
+ func_exit 1
+ fi
# Determine the minimum supported autoconf version from the project's
# configure.ac.
***************
*** 2128,2138 ****
fi
}
! # func_get_automake_snippet module
# Input:
# - local_gnulib_dir from --local-dir
# - modcache true or false, from --cache-modules/--no-cache-modules
! func_get_automake_snippet ()
{
if ! $modcache; then
func_lookup_file "modules/$1"
--- 2142,2152 ----
fi
}
! # func_get_automake_snippet_part1 module
# Input:
# - local_gnulib_dir from --local-dir
# - modcache true or false, from --cache-modules/--no-cache-modules
! func_get_automake_snippet_part1 ()
{
if ! $modcache; then
func_lookup_file "modules/$1"
***************
*** 2152,2157 ****
--- 2166,2179 ----
fi
fi
fi
+ }
+
+ # func_get_automake_snippet_part2 module
+ # Input:
+ # - local_gnulib_dir from --local-dir
+ # - modcache true or false, from --cache-modules/--no-cache-modules
+ func_get_automake_snippet_part2 ()
+ {
case "$1" in
*-tests)
# *-tests module live in tests/, not lib/.
***************
*** 2176,2183 ****
--- 2198,2207 ----
sed_extract_mentioned_files='s/^lib_SOURCES[ ]*+=[ ]*//p'
already_mentioned_files=` \
{ if ! $modcache; then
+ func_lookup_file "modules/$1"
sed -n -e "/^Makefile\.am$sed_extract_prog" < "$lookedup_file"
else
+ func_cache_lookup_module "$1"
if $have_associative; then
if eval 'test -n "${modcache_makefile[$1]+set}"'; then
eval 'echo "${modcache_makefile[$1]}"'
***************
*** 2243,2248 ****
--- 2267,2282 ----
esac
}
+ # func_get_automake_snippet module
+ # Input:
+ # - local_gnulib_dir from --local-dir
+ # - modcache true or false, from --cache-modules/--no-cache-modules
+ func_get_automake_snippet ()
+ {
+ func_get_automake_snippet_part1 "$1"
+ func_get_automake_snippet_part2 "$1"
+ }
+
# func_get_include_directive module
# Input:
# - local_gnulib_dir from --local-dir
***************
*** 2380,2385 ****
--- 2414,2593 ----
return 0
}
+ # sed expression to keep the first 32 characters of each line.
+ sed_first_32_chars='s/^\(................................\).*/\1/'
+
+ # func_module_m4macro_name module
+ # computes the m4 macro name that will contain the m4 macros for the module.
+ # Input:
+ # - macro_prefix prefix to use
+ # Output:
+ # - result m4 macro name
+ func_module_m4macro_name ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ result=${macro_prefix}_GNULIB_M4CODE_`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ result=${macro_prefix}_GNULIB_M4CODE_$1 ;;
+ esac
+ }
+
+ # func_module_shellvar_name module
+ # computes the shell variable name the will be set to true once the m4 macros
+ # for the module have been executed.
+ # Output:
+ # - result shell variable name
+ func_module_shellvar_name ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ result=${macro_prefix}_gnulib_enabled_`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ result=${macro_prefix}_gnulib_enabled_$1 ;;
+ esac
+ }
+
+ # func_module_conditional_name module
+ # computes the automake conditional name for the module.
+ # Output:
+ # - conditional condition name
+ func_module_conditional_name ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ conditional=${macro_prefix}_GNULIB_ENABLED_`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ conditional=${macro_prefix}_GNULIB_ENABLED_$1 ;;
+ esac
+ }
+
+ # func_uncond_add_module A
+ # notes the presence of A as an unconditional module.
+ #
+ # func_conddep_add_module A B cond
+ # notes the presence of a conditional dependency from module B to module A,
+ # subject to the condition that B is enabled and cond is true.
+ #
+ # func_cond_module_p A
+ # tests whether module A is conditional.
+ #
+ # func_cond_module_dependers A
+ # returns the set of modules B that depend on A conditionally.
+ # Output: - result
+ #
+ # func_cond_module_condition A
+ # returns the condition when A should be enabled, once all dependers modules
+ # have been handled.
+ # Output: - result
+ #
+ if $have_associative; then
+ declare -A conddep_isuncond
+ declare -A conddep_dependers
+ declare -A conddep_condition
+ func_uncond_add_module ()
+ {
+ eval 'conddep_isuncond[$1]=true'
+ eval 'unset conddep_dependers[$1]'
+ eval 'unset conddep_condition[$1]'
+ }
+ func_conddep_add_module ()
+ {
+ eval 'isuncond="${conddep_isuncond[$1]}"'
+ if test -z "$isuncond"; then
+ func_module_shellvar_name "$1"
+ shellvar="$result"
+ eval 'previous_dependers="${conddep_dependers[$1]}"'
+ if test -n "$previous_dependers"; then
+ eval 'conddep_dependers[$1]="${conddep_dependers[$1]} $2"'
+ eval 'conddep_condition[$1]="${conddep_condition[$1]} || { ${shellvar} && { $3; }; }"'
+ else
+ eval 'conddep_dependers[$1]="$2"'
+ eval 'conddep_condition[$1]="{ ${shellvar} && { $3; }; }"'
+ fi
+ fi
+ }
+ func_cond_module_p ()
+ {
+ eval 'previous_dependers="${conddep_dependers[$1]}"'
+ test -n "$previous_dependers"
+ }
+ func_cond_module_dependers ()
+ {
+ eval 'result="${conddep_dependers[$1]}"'
+ }
+ func_cond_module_condition ()
+ {
+ eval 'result="${conddep_condition[$1]}"'
+ }
+ else
+ func_uncond_add_module ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ suffix=`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ suffix=$1 ;;
+ esac
+ eval 'conddep_isuncond_'"$suffix"'=true'
+ eval 'unset conddep_dependers_'"$suffix"
+ eval 'unset conddep_condition_'"$suffix"
+ }
+ func_conddep_add_module ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ suffix=`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ suffix=$1 ;;
+ esac
+ eval 'isuncond="${conddep_isuncond_'"$suffix"'}"'
+ if test -z "$isuncond"; then
+ func_module_shellvar_name "$1"
+ shellvar="$result"
+ eval 'previous_dependers="${conddep_dependers_'"$suffix"'}"'
+ if test -n "$previous_dependers"; then
+ eval 'conddep_dependers_'"$suffix"'="${conddep_dependers_'"$suffix"'} $2"'
+ eval 'conddep_condition_'"$suffix"'="${conddep_condition_'"$suffix"'} || { ${shellvar} && { $3; }; }"'
+ else
+ eval 'conddep_dependers_'"$suffix"'="$2"'
+ eval 'conddep_condition_'"$suffix"'="{ ${shellvar} && { $3; }; }"'
+ fi
+ fi
+ }
+ func_cond_module_p ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ suffix=`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ suffix=$1 ;;
+ esac
+ eval 'previous_dependers="${conddep_dependers_'"$suffix"'}"'
+ test -n "$previous_dependers"
+ }
+ func_cond_module_dependers ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ suffix=`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ suffix=$1 ;;
+ esac
+ eval 'result="${conddep_dependers_'"$suffix"'}"'
+ }
+ func_cond_module_condition ()
+ {
+ case $1 in
+ *[!a-zA-Z0-9_]*)
+ suffix=`echo "$1" | md5sum | LC_ALL=C sed -e "$sed_first_32_chars"` ;;
+ *)
+ suffix=$1 ;;
+ esac
+ eval 'result="${conddep_condition_'"$suffix"'}"'
+ }
+ fi
+
# func_modules_transitive_closure
# Input:
# - local_gnulib_dir from --local-dir
***************
*** 2411,2421 ****
--- 2619,2634 ----
# - excl_unportable_tests true if tests that fail on some platforms should be
# excluded, blank otherwise
# - avoidlist list of modules to avoid
+ # - cond_dependencies true if conditional dependencies shall be supported,
+ # blank otherwise
# - tmp pathname of a temporary directory
# Output:
# - modules list of modules, including dependencies
+ # - conddep_dependers, conddep_condition information about conditionally
+ # enabled modules
func_modules_transitive_closure ()
{
+ sed_dependencies_without_conditions='s/ *\[.*//'
# In order to process every module only once (for speed), process an "input
# list" of modules, producing an "output list" of modules. During each round,
# more modules can be queued in the input list. Once a module on the input
***************
*** 2425,2430 ****
--- 2638,2653 ----
inmodules="$modules"
outmodules=
fmtc_inc_all_tests="$inc_all_direct_tests"
+ if test -n "$cond_dependencies"; then
+ for module in $inmodules; do
+ func_verify_module
+ if test -n "$module"; then
+ if func_acceptable $module; then
+ func_uncond_add_module $module
+ fi
+ fi
+ done
+ fi
while test -n "$inmodules"; do
inmodules_this_round="$inmodules"
inmodules= # Accumulator, queue for next round
***************
*** 2433,2439 ****
if test -n "$module"; then
if func_acceptable $module; then
func_append outmodules " $module"
! deps=`func_get_dependencies $module`
# Duplicate dependencies are harmless, but Jim wants a warning.
duplicated_deps=`echo "$deps" | LC_ALL=C sort | LC_ALL=C uniq -d`
if test -n "$duplicated_deps"; then
--- 2656,2668 ----
if test -n "$module"; then
if func_acceptable $module; then
func_append outmodules " $module"
! conditional=false
! if test -n "$cond_dependencies"; then
! if func_cond_module_p $module; then
! conditional=true
! fi
! fi
! deps=`func_get_dependencies $module | sed -e "$sed_dependencies_without_conditions"`
# Duplicate dependencies are harmless, but Jim wants a warning.
duplicated_deps=`echo "$deps" | LC_ALL=C sort | LC_ALL=C uniq -d`
if test -n "$duplicated_deps"; then
***************
*** 2486,2491 ****
--- 2715,2737 ----
done
if $inc; then
func_append inmodules " $dep"
+ if test -n "$cond_dependencies"; then
+ sed_extract_condition1='/^ *'"$dep"' *$/{s|^.*$|true|p}'
+ sed_extract_condition2='/^ *'"$dep"' *\[.*\] *$/{s|^ *'"$dep"' *\[\(.*\)\] *$|\1|p}'
+ condition=`func_get_dependencies $module | sed -n -e "$sed_extract_condition1" -e "$sed_extract_condition2"`
+ if test "$condition" = true; then
+ condition=
+ fi
+ if test -n "$condition"; then
+ func_conddep_add_module "$dep" "$module" "$condition"
+ else
+ if $conditional; then
+ func_conddep_add_module "$dep" "$module" true
+ else
+ func_uncond_add_module "$dep"
+ fi
+ fi
+ fi
fi
done
fi
***************
*** 2807,2813 ****
func_verify_nontests_module
if test -n "$module"; then
{
! func_get_automake_snippet "$module" |
LC_ALL=C \
sed -e 's,lib_LIBRARIES,lib%_LIBRARIES,g' \
-e 's,lib_LTLIBRARIES,lib%_LTLIBRARIES,g' \
--- 3053,3059 ----
func_verify_nontests_module
if test -n "$module"; then
{
! func_get_automake_snippet_part1 "$module" |
LC_ALL=C \
sed -e 's,lib_LIBRARIES,lib%_LIBRARIES,g' \
-e 's,lib_LTLIBRARIES,lib%_LTLIBRARIES,g' \
***************
*** 2820,2835 ****
echo "${libname}_${libext}_LIBADD += @${perhapsLT}ALLOCA@"
echo "${libname}_${libext}_DEPENDENCIES += @${perhapsLT}ALLOCA@"
fi
! } > "$tmp"/amsnippet
# Skip the contents if it's entirely empty.
! if grep '[^ ]' "$tmp"/amsnippet > /dev/null ; then
echo "## begin gnulib module $module"
echo
! cat "$tmp"/amsnippet
echo "## end gnulib module $module"
echo
fi
! rm -f "$tmp"/amsnippet
# Test whether there are some source files in subdirectories.
for f in `func_get_filelist "$module"`; do
case $f in
--- 3066,3097 ----
echo "${libname}_${libext}_LIBADD += @${perhapsLT}ALLOCA@"
echo "${libname}_${libext}_DEPENDENCIES += @${perhapsLT}ALLOCA@"
fi
! } > "$tmp"/amsnippet1
! {
! func_get_automake_snippet_part2 "$module" |
! LC_ALL=C sed -e 's,lib_\([A-Z][A-Z]*\),'"${libname}_${libext}"'_\1,g'
! } > "$tmp"/amsnippet2
# Skip the contents if it's entirely empty.
! if grep '[^ ]' "$tmp"/amsnippet1 "$tmp"/amsnippet2 > /dev/null ; then
echo "## begin gnulib module $module"
echo
! if test -n "$cond_dependencies"; then
! if func_cond_module_p "$module"; then
! func_module_conditional_name "$module"
! echo "if $conditional"
! fi
! fi
! cat "$tmp"/amsnippet1
! if test -n "$cond_dependencies"; then
! if func_cond_module_p "$module"; then
! echo "endif"
! fi
! fi
! cat "$tmp"/amsnippet2
echo "## end gnulib module $module"
echo
fi
! rm -f "$tmp"/amsnippet1 "$tmp"/amsnippet2
# Test whether there are some source files in subdirectories.
for f in `func_get_filelist "$module"`; do
case $f in
***************
*** 3386,3391 ****
--- 3648,3655 ----
# otherwise
# - inc_all_tests true if --with-all-tests was given, blank otherwise
# - avoidlist list of modules to avoid, from --avoid
+ # - cond_dependencies true if conditional dependencies shall be supported,
+ # blank otherwise
# - lgpl yes or a number if library's license shall be LGPL,
# blank otherwise
# - makefile_name from --makefile-name
***************
*** 4541,4550 ****
--- 4805,4838 ----
echo " gl_m4_base='$m4base'"
func_emit_initmacro_start $macro_prefix
echo " gl_source_base='$sourcebase'"
+ if test -n "$cond_dependencies"; then
+ # Initialize the shell variables indicating that the modules are enabled.
+ for module in $main_modules; do
+ func_verify_module
+ if test -n "$module"; then
+ func_module_shellvar_name "$module"
+ echo " $result=false"
+ fi
+ done
+ fi
for module in $main_modules; do
func_verify_module
if test -n "$module"; then
echo " # Code from module $module:"
+ if test -n "$cond_dependencies"; then
+ func_module_m4macro_name "$module"
+ echo " AC_DEFUN([$result], ["
+ if func_cond_module_p "$module"; then
+ func_cond_module_dependers "$module"
+ dependers="$result"
+ for depender in $dependers; do
+ func_module_m4macro_name $depender
+ echo " AC_REQUIRE([$result])"
+ done
+ func_cond_module_condition "$module"
+ echo " if $result; then"
+ fi
+ fi
func_get_autoconf_snippet "$module" \
| sed -e '/^$/d;' -e 's/^/ /' \
-e 's/AM_GNU_GETTEXT(\[external\])/dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac./' \
***************
*** 4555,4563 ****
--- 4843,4885 ----
echo 'changequote([, ])dnl'
echo 'AC_SUBST([LTALLOCA])'
fi
+ if test -n "$cond_dependencies"; then
+ func_module_shellvar_name "$module"
+ echo " $result=true"
+ if func_cond_module_p "$module"; then
+ echo " fi"
+ fi
+ echo " ])"
+ fi
fi
done
echo " # End of code from modules"
+ if test -n "$cond_dependencies"; then
+ # Invoke the m4macros of the unconditional modules.
+ for module in $main_modules; do
+ func_verify_module
+ if test -n "$module"; then
+ if func_cond_module_p "$module"; then
+ :
+ else
+ func_module_m4macro_name "$module"
+ echo " $result"
+ fi
+ fi
+ done
+ # Define the Automake conditionals.
+ echo " m4_pattern_allow([^${macro_prefix}_GNULIB_ENABLED_])"
+ for module in $main_modules; do
+ func_verify_module
+ if test -n "$module"; then
+ if func_cond_module_p "$module"; then
+ func_module_conditional_name "$module"
+ func_module_shellvar_name "$module"
+ echo " AM_CONDITIONAL([$conditional], [\$$result])"
+ fi
+ fi
+ done
+ fi
func_emit_initmacro_end $macro_prefix
echo " gltests_libdeps="
echo " gltests_ltlibdeps="
***************
*** 4864,4869 ****
--- 5186,5193 ----
# - excl_unportable_tests true if tests that fail on some platforms should be
# excluded, blank otherwise
# - avoidlist list of modules to avoid
+ # - cond_dependencies true if conditional dependencies shall be supported,
+ # blank otherwise
# - libtool true if --libtool was given, false if --no-libtool was
# given, blank otherwise
# - symbolic true if files should be symlinked, copied otherwise
***************
*** 5269,5277 ****
--- 5593,5625 ----
echo "gl_m4_base='$m4base'"
func_emit_initmacro_start $macro_prefix
echo "gl_source_base='$sourcebase'"
+ if test -n "$cond_dependencies"; then
+ # Initialize the shell variables indicating that the modules are enabled.
+ for module in $modules; do
+ func_verify_nontests_module
+ if test -n "$module"; then
+ func_module_shellvar_name "$module"
+ echo " $result=false"
+ fi
+ done
+ fi
for module in $modules; do
func_verify_nontests_module
if test -n "$module"; then
+ if test -n "$cond_dependencies"; then
+ func_module_m4macro_name "$module"
+ echo " AC_DEFUN([$result], ["
+ if func_cond_module_p "$module"; then
+ func_cond_module_dependers "$module"
+ dependers="$result"
+ for depender in $dependers; do
+ func_module_m4macro_name $depender
+ echo " AC_REQUIRE([$result])"
+ done
+ func_cond_module_condition "$module"
+ echo " if $result; then"
+ fi
+ fi
func_get_autoconf_snippet "$module" \
| sed -e "$sed_replace_build_aux"
if test "$module" = 'alloca' && test "$libtool" = true; then
***************
*** 5280,5287 ****
--- 5628,5669 ----
echo 'changequote([, ])dnl'
echo 'AC_SUBST([LTALLOCA])'
fi
+ if test -n "$cond_dependencies"; then
+ func_module_shellvar_name "$module"
+ echo " $result=true"
+ if func_cond_module_p "$module"; then
+ echo " fi"
+ fi
+ echo " ])"
+ fi
fi
done
+ if test -n "$cond_dependencies"; then
+ # Invoke the m4macros of the unconditional modules.
+ for module in $modules; do
+ func_verify_nontests_module
+ if test -n "$module"; then
+ if func_cond_module_p "$module"; then
+ :
+ else
+ func_module_m4macro_name "$module"
+ echo " $result"
+ fi
+ fi
+ done
+ # Define the Automake conditionals.
+ echo " m4_pattern_allow([^${macro_prefix}_GNULIB_ENABLED_])"
+ for module in $modules; do
+ func_verify_nontests_module
+ if test -n "$module"; then
+ if func_cond_module_p "$module"; then
+ func_module_conditional_name "$module"
+ func_module_shellvar_name "$module"
+ echo " AM_CONDITIONAL([$conditional], [\$$result])"
+ fi
+ fi
+ done
+ fi
func_emit_initmacro_end $macro_prefix
# _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
# created using libtool, because libtool already handles the dependencies.