From 514a842f07ec6b2022df3f14f9adb44feecbabb2 Mon Sep 17 00:00:00 2001 From: Matthias Paulmier Date: Fri, 6 Jul 2018 15:49:28 +0200 Subject: Move functions to LangHandling These functions are language specific functions. To achieve this, we had to add a new module "TmpModule". The functions in this module should be relocated when we find a better place. * lib/Automake/LangHandling.pm: Add handle_emacs_lisp, handle_java, handle_python to this module. * lib/Automake/LangHandling: Add this module to avoid include cycles. --- bin/automake.in | 422 +------------------------------------------ lib/Automake/LangHandling.pm | 92 +++++++++- lib/Automake/TmpModule.pm | 379 ++++++++++++++++++++++++++++++++++++++ lib/Automake/Utils.pm | 1 + lib/Automake/local.mk | 1 + 5 files changed, 466 insertions(+), 429 deletions(-) create mode 100644 lib/Automake/TmpModule.pm diff --git a/bin/automake.in b/bin/automake.in index 168c8b082..761491fbf 100755 --- a/bin/automake.in +++ b/bin/automake.in @@ -50,6 +50,7 @@ BEGIN import Thread::Queue; } } +use Automake::TmpModule; use Automake::ChannelDefs; use Automake::Channels; use Automake::CondStack; @@ -86,9 +87,6 @@ use Carp; ## Subroutine prototypes. ## ## ----------------------- ## -sub am_install_var; -sub am_primary_prefixes; -sub append_exeext (&$); sub check_canonical_spelling; sub check_directories_in_var; sub check_libobjs_sources; @@ -108,13 +106,11 @@ sub handle_clean; sub handle_compile (); sub handle_data (); sub handle_dist (); -sub handle_emacs_lisp (); sub handle_factored_dependencies (); sub handle_footer (); sub handle_gettext (); sub handle_headers (); sub handle_install (); -sub handle_java (); sub handle_languages (); sub handle_lib_objects; sub handle_libraries (); @@ -128,7 +124,6 @@ sub handle_minor_options (); sub handle_options (); sub handle_per_suffix_test; sub handle_programs (); -sub handle_python (); sub handle_scripts (); sub handle_single_transform; sub handle_source_transform; @@ -144,7 +139,6 @@ sub parse_arguments (); sub print_autodist_files; sub read_am_file; sub read_main_am_file; -sub shadow_unconditionally; sub target_cmp; sub usage (); sub user_phony_rule; @@ -605,25 +599,6 @@ sub handle_options () return 1; } -# shadow_unconditionally ($varname, $where) -# ----------------------------------------- -# Return a $(variable) that contains all possible values -# $varname can take. -# If the VAR wasn't defined conditionally, return $(VAR). -# Otherwise we create an am__VAR_DIST variable which contains -# all possible values, and return $(am__VAR_DIST). -sub shadow_unconditionally -{ - my ($varname, $where) = @_; - my $var = var $varname; - if ($var->has_conditional_contents) - { - $varname = "am__${varname}_DIST"; - my @files = uniq ($var->value_as_list_recursive); - define_pretty_variable ($varname, TRUE, $where, @files); - } - return "\$($varname)" -} # Call finish function for each language that was used. sub handle_languages () @@ -899,31 +874,6 @@ sub handle_languages () } -# append_exeext { PREDICATE } $MACRO -# ---------------------------------- -# Append $(EXEEXT) to each filename in $F appearing in the Makefile -# variable $MACRO if &PREDICATE($F) is true. @substitutions@ are -# ignored. -# -# This is typically used on all filenames of *_PROGRAMS, and filenames -# of TESTS that are programs. -sub append_exeext (&$) -{ - my ($pred, $macro) = @_; - - transform_variable_recursively - ($macro, $macro, 'am__EXEEXT', 0, INTERNAL, - sub { - my ($subvar, $val, $cond, $full_cond) = @_; - # Append $(EXEEXT) unless the user did it already, or it's a - # @substitution@. - $val .= '$(EXEEXT)' - if $val !~ /(?:\$\(EXEEXT\)$|^[@]\w+[@]$)/ && &$pred ($val); - return $val; - }); -} - - # Check to make sure a source defined in LIBOBJS is not explicitly # mentioned. This is a separate function (as opposed to being inlined # in handle_source_transform) because it isn't always appropriate to @@ -3357,80 +3307,6 @@ sub handle_tests () } } -sub handle_emacs_lisp () -{ - my @elfiles = am_install_var ('-candist', 'lisp', 'LISP', - 'lisp', 'noinst'); - - return if ! @elfiles; - - define_pretty_variable ('am__ELFILES', TRUE, INTERNAL, - map { $_->[1] } @elfiles); - define_pretty_variable ('am__ELCFILES', TRUE, INTERNAL, - '$(am__ELFILES:.el=.elc)'); - # This one can be overridden by users. - define_pretty_variable ('ELCFILES', TRUE, INTERNAL, '$(LISP:.el=.elc)'); - - push @all, '$(ELCFILES)'; - - require_variables ($elfiles[0][0], "Emacs Lisp sources seen", TRUE, - 'EMACS', 'lispdir'); -} - -sub handle_python () -{ - my @pyfiles = am_install_var ('-defaultdist', 'python', 'PYTHON', - 'noinst'); - return if ! @pyfiles; - - require_variables ($pyfiles[0][0], "Python sources seen", TRUE, 'PYTHON'); - require_conf_file ($pyfiles[0][0], FOREIGN, 'py-compile'); - define_variable ('py_compile', "$am_config_aux_dir/py-compile", INTERNAL); -} - -sub handle_java () -{ - my @sourcelist = am_install_var ('-candist', - 'java', 'JAVA', - 'noinst', 'check'); - return if ! @sourcelist; - - my @prefixes = am_primary_prefixes ('JAVA', 1, - 'noinst', 'check'); - - my $dir; - my @java_sources = (); - foreach my $prefix (@prefixes) - { - (my $curs = $prefix) =~ s/^(?:nobase_)?(?:dist_|nodist_)?//; - - next - if $curs eq 'EXTRA'; - - push @java_sources, '$(' . $prefix . '_JAVA' . ')'; - - if (defined $dir) - { - err_var "${curs}_JAVA", "multiple _JAVA primaries in use" - unless $curs eq $dir; - } - - $dir = $curs; - } - - define_pretty_variable ('am__java_sources', TRUE, INTERNAL, - "@java_sources"); - - if ($dir eq 'check') - { - push (@check, "class$dir.stamp"); - } - else - { - push (@all, "class$dir.stamp"); - } -} - sub handle_minor_options () { @@ -3925,302 +3801,6 @@ sub read_main_am_file read_am_file ($amfile, new Automake::Location, '.'); } - - -################################################################ - - -# @PREFIX -# am_primary_prefixes ($PRIMARY, $CAN_DIST, @PREFIXES) -# ---------------------------------------------------- -# Find all variable prefixes that are used for install directories. A -# prefix 'zar' qualifies iff: -# -# * 'zardir' is a variable. -# * 'zar_PRIMARY' is a variable. -# -# As a side effect, it looks for misspellings. It is an error to have -# a variable ending in a "reserved" suffix whose prefix is unknown, e.g. -# "bni_PROGRAMS". However, unusual prefixes are allowed if a variable -# of the same name (with "dir" appended) exists. For instance, if the -# variable "zardir" is defined, then "zar_PROGRAMS" becomes valid. -# This is to provide a little extra flexibility in those cases which -# need it. -sub am_primary_prefixes -{ - my ($primary, $can_dist, @prefixes) = @_; - - local $_; - my %valid = map { $_ => 0 } @prefixes; - $valid{'EXTRA'} = 0; - foreach my $var (variables $primary) - { - # Automake is allowed to define variables that look like primaries - # but which aren't. E.g. INSTALL_sh_DATA. - # Autoconf can also define variables like INSTALL_DATA, so - # ignore all configure variables (at least those which are not - # redefined in Makefile.am). - # FIXME: We should make sure that these variables are not - # conditionally defined (or else adjust the condition below). - my $def = $var->def (TRUE); - next if $def && $def->owner != VAR_MAKEFILE; - - my $varname = $var->name; - - if ($varname =~ /^(nobase_)?(dist_|nodist_)?(.*)_[[:alnum:]]+$/) - { - my ($base, $dist, $X) = ($1 || '', $2 || '', $3 || ''); - if ($dist ne '' && ! $can_dist) - { - err_var ($var, - "invalid variable '$varname': 'dist' is forbidden"); - } - # Standard directories must be explicitly allowed. - elsif (! defined $valid{$X} && exists $standard_prefix{$X}) - { - err_var ($var, - "'${X}dir' is not a legitimate directory " . - "for '$primary'"); - } - # A not explicitly valid directory is allowed if Xdir is defined. - elsif (! defined $valid{$X} && - $var->requires_variables ("'$varname' is used", "${X}dir")) - { - # Nothing to do. Any error message has been output - # by $var->requires_variables. - } - else - { - # Ensure all extended prefixes are actually used. - $valid{"$base$dist$X"} = 1; - } - } - else - { - prog_error "unexpected variable name: $varname"; - } - } - - # Return only those which are actually defined. - return sort grep { var ($_ . '_' . $primary) } keys %valid; -} - - -# am_install_var (-OPTION..., file, HOW, where...) -# ------------------------------------------------ -# -# Handle 'where_HOW' variable magic. Does all lookups, generates -# install code, and possibly generates code to define the primary -# variable. The first argument is the name of the .am file to munge, -# the second argument is the primary variable (e.g. HEADERS), and all -# subsequent arguments are possible installation locations. -# -# Returns list of [$location, $value] pairs, where -# $value's are the values in all where_HOW variable, and $location -# there associated location (the place here their parent variables were -# defined). -# -# FIXME: this should be rewritten to be cleaner. It should be broken -# up into multiple functions. -# -sub am_install_var -{ - my (@args) = @_; - - my $do_require = 1; - my $can_dist = 0; - my $default_dist = 0; - while (@args) - { - if ($args[0] eq '-noextra') - { - $do_require = 0; - } - elsif ($args[0] eq '-candist') - { - $can_dist = 1; - } - elsif ($args[0] eq '-defaultdist') - { - $default_dist = 1; - $can_dist = 1; - } - elsif ($args[0] !~ /^-/) - { - last; - } - shift (@args); - } - - my ($file, $primary, @prefix) = @args; - - # Now that configure substitutions are allowed in where_HOW - # variables, it is an error to actually define the primary. We - # allow 'JAVA', as it is customarily used to mean the Java - # interpreter. This is but one of several Java hacks. Similarly, - # 'PYTHON' is customarily used to mean the Python interpreter. - reject_var $primary, "'$primary' is an anachronism" - unless $primary eq 'JAVA' || $primary eq 'PYTHON'; - - # Get the prefixes which are valid and actually used. - @prefix = am_primary_prefixes ($primary, $can_dist, @prefix); - - # If a primary includes a configure substitution, then the EXTRA_ - # form is required. Otherwise we can't properly do our job. - my $require_extra; - - my @used = (); - my @result = (); - - foreach my $X (@prefix) - { - my $nodir_name = $X; - my $one_name = $X . '_' . $primary; - my $one_var = var $one_name; - - my $strip_subdir = 1; - # If subdir prefix should be preserved, do so. - if ($nodir_name =~ /^nobase_/) - { - $strip_subdir = 0; - $nodir_name =~ s/^nobase_//; - } - - # If files should be distributed, do so. - my $dist_p = 0; - if ($can_dist) - { - $dist_p = (($default_dist && $nodir_name !~ /^nodist_/) - || (! $default_dist && $nodir_name =~ /^dist_/)); - $nodir_name =~ s/^(dist|nodist)_//; - } - - - # Use the location of the currently processed variable. - # We are not processing a particular condition, so pick the first - # available. - my $tmpcond = $one_var->conditions->one_cond; - my $where = $one_var->rdef ($tmpcond)->location->clone; - - # Append actual contents of where_PRIMARY variable to - # @result, skipping @substitutions@. - foreach my $locvals ($one_var->value_as_list_recursive (location => 1)) - { - my ($loc, $value) = @$locvals; - # Skip configure substitutions. - if ($value =~ /^\@.*\@$/) - { - if ($nodir_name eq 'EXTRA') - { - error ($where, - "'$one_name' contains configure substitution, " - . "but shouldn't"); - } - # Check here to make sure variables defined in - # configure.ac do not imply that EXTRA_PRIMARY - # must be defined. - elsif (! defined $configure_vars{$one_name}) - { - $require_extra = $one_name - if $do_require; - } - } - else - { - # Strip any $(EXEEXT) suffix the user might have added, - # or this will confuse handle_source_transform() and - # check_canonical_spelling(). - # We'll add $(EXEEXT) back later anyway. - # Do it here rather than in handle_programs so the - # uniquifying at the end of this function works. - ${$locvals}[1] =~ s/\$\(EXEEXT\)$// - if $primary eq 'PROGRAMS'; - - push (@result, $locvals); - } - } - # A blatant hack: we rewrite each _PROGRAMS primary to include - # EXEEXT. - append_exeext { 1 } $one_name - if $primary eq 'PROGRAMS'; - # "EXTRA" shouldn't be used when generating clean targets, - # all, or install targets. We used to warn if EXTRA_FOO was - # defined uselessly, but this was annoying. - next - if $nodir_name eq 'EXTRA'; - - if ($nodir_name eq 'check') - { - push (@check, '$(' . $one_name . ')'); - } - else - { - push (@used, '$(' . $one_name . ')'); - } - - # Is this to be installed? - my $install_p = $nodir_name ne 'noinst' && $nodir_name ne 'check'; - - # If so, with install-exec? (or install-data?). - my $exec_p = ($nodir_name =~ /$EXEC_DIR_PATTERN/o); - - my $check_options_p = $install_p && !! option 'std-options'; - - # Use the location of the currently processed variable as context. - $where->push_context ("while processing '$one_name'"); - - # The variable containing all files to distribute. - my $distvar = "\$($one_name)"; - $distvar = shadow_unconditionally ($one_name, $where) - if ($dist_p && $one_var->has_conditional_contents); - - # Singular form of $PRIMARY. - (my $one_primary = $primary) =~ s/S$//; - $output_rules .= file_contents ($file, $where, - PRIMARY => $primary, - ONE_PRIMARY => $one_primary, - DIR => $X, - NDIR => $nodir_name, - BASE => $strip_subdir, - EXEC => $exec_p, - INSTALL => $install_p, - DIST => $dist_p, - DISTVAR => $distvar, - 'CK-OPTS' => $check_options_p); - } - - # The JAVA variable is used as the name of the Java interpreter. - # The PYTHON variable is used as the name of the Python interpreter. - if (@used && $primary ne 'JAVA' && $primary ne 'PYTHON') - { - # Define it. - define_pretty_variable ($primary, TRUE, INTERNAL, @used); - $output_vars .= "\n"; - } - - err_var ($require_extra, - "'$require_extra' contains configure substitution,\n" - . "but 'EXTRA_$primary' not defined") - if ($require_extra && ! var ('EXTRA_' . $primary)); - - # Push here because PRIMARY might be configure time determined. - push (@all, '$(' . $primary . ')') - if @used && $primary ne 'JAVA' && $primary ne 'PYTHON'; - - # Make the result unique. This lets the user use conditionals in - # a natural way, but still lets us program lazily -- we don't have - # to worry about handling a particular object more than once. - # We will keep only one location per object. - my %result = (); - for my $pair (@result) - { - my ($loc, $val) = @$pair; - $result{$val} = $loc; - } - my @l = sort keys %result; - return map { [$result{$_}->clone, $_] } @l; -} - ################################################################ # generate_makefile ($MAKEFILE_AM, $MAKEFILE_IN) diff --git a/lib/Automake/LangHandling.pm b/lib/Automake/LangHandling.pm index 64779cfb0..04062692c 100644 --- a/lib/Automake/LangHandling.pm +++ b/lib/Automake/LangHandling.pm @@ -15,6 +15,7 @@ package Automake::LangHandling; +use Automake::TmpModule; use Automake::Condition qw (TRUE FALSE); use Automake::ChannelDefs; use Automake::Global; @@ -35,14 +36,13 @@ use File::Basename; use vars qw (@EXPORT); @EXPORT = qw (check_user_variables lang_sub_obj lang_header_rewrite - lang_vala_rewrite lang_yacc_rewrite lang_yaccxx_rewrite - lang_lex_rewrite lang_lexxx_rewrite lang_java_rewrite - lang_vala_finish_target lang_vala_finish - lang_vala_target_hook lang_yacc_target_hook - lang_lex_target_hook yacc_lex_finish_helper - lang_yacc_finish lang_lex_finish resolve_linker - saw_extension register_language derive_suffix - pretty_print_rule); + lang_vala_rewrite lang_yacc_rewrite lang_yaccxx_rewrite lang_lex_rewrite + lang_lexxx_rewrite lang_java_rewrite lang_vala_finish_target + lang_vala_finish lang_vala_target_hook lang_yacc_target_hook + lang_lex_target_hook yacc_lex_finish_helper lang_yacc_finish + lang_lex_finish resolve_linker saw_extension register_language + derive_suffix pretty_print_rule handle_emacs_lisp handle_python + handle_java); # check_user_variables (@LIST) # ---------------------------- @@ -480,4 +480,80 @@ sub pretty_print_rule $output_rules .= makefile_wrap (shift, shift, @_); } + +sub handle_emacs_lisp () +{ + my @elfiles = am_install_var ('-candist', 'lisp', 'LISP', + 'lisp', 'noinst'); + + return if ! @elfiles; + + define_pretty_variable ('am__ELFILES', TRUE, INTERNAL, + map { $_->[1] } @elfiles); + define_pretty_variable ('am__ELCFILES', TRUE, INTERNAL, + '$(am__ELFILES:.el=.elc)'); + # This one can be overridden by users. + define_pretty_variable ('ELCFILES', TRUE, INTERNAL, '$(LISP:.el=.elc)'); + + push @all, '$(ELCFILES)'; + + require_variables ($elfiles[0][0], "Emacs Lisp sources seen", TRUE, + 'EMACS', 'lispdir'); +} + +sub handle_python () +{ + my @pyfiles = am_install_var ('-defaultdist', 'python', 'PYTHON', + 'noinst'); + return if ! @pyfiles; + + require_variables ($pyfiles[0][0], "Python sources seen", TRUE, 'PYTHON'); + require_conf_file ($pyfiles[0][0], FOREIGN, 'py-compile'); + define_variable ('py_compile', "$am_config_aux_dir/py-compile", INTERNAL); +} + +sub handle_java () +{ + my @sourcelist = am_install_var ('-candist', + 'java', 'JAVA', + 'noinst', 'check'); + return if ! @sourcelist; + + my @prefixes = am_primary_prefixes ('JAVA', 1, + 'noinst', 'check'); + + my $dir; + my @java_sources = (); + foreach my $prefix (@prefixes) + { + (my $curs = $prefix) =~ s/^(?:nobase_)?(?:dist_|nodist_)?//; + + next + if $curs eq 'EXTRA'; + + push @java_sources, '$(' . $prefix . '_JAVA' . ')'; + + if (defined $dir) + { + err_var "${curs}_JAVA", "multiple _JAVA primaries in use" + unless $curs eq $dir; + } + + $dir = $curs; + } + + define_pretty_variable ('am__java_sources', TRUE, INTERNAL, + "@java_sources"); + + if ($dir eq 'check') + { + push (@check, "class$dir.stamp"); + } + else + { + push (@all, "class$dir.stamp"); + } +} + + 1; diff --git a/lib/Automake/TmpModule.pm b/lib/Automake/TmpModule.pm new file mode 100644 index 000000000..b98aab27d --- /dev/null +++ b/lib/Automake/TmpModule.pm @@ -0,0 +1,379 @@ +# Copyright (C) 2018 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 +# 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 . + +# FIXME: This is a temporary package. The functions it holds should be moved +# elsewhere +package Automake::TmpModule; + +use 5.006; +use strict; + +use Automake::ChannelDefs; +use Automake::Condition qw /TRUE FALSE/; +use Automake::ConfVars; +use Automake::File; +use Automake::General; +use Automake::Global; +use Automake::Location; +use Automake::Options; +use Automake::Utils; +use Automake::VarDef; +use Automake::Variable; +use Exporter 'import'; + +use vars qw (@EXPORT); + +@EXPORT = qw (append_exeext am_install_var am_primary_prefixes + shadow_unconditionally); + + +# append_exeext { PREDICATE } $MACRO +# ---------------------------------- +# Append $(EXEEXT) to each filename in $F appearing in the Makefile +# variable $MACRO if &PREDICATE($F) is true. @substitutions@ are +# ignored. +# +# This is typically used on all filenames of *_PROGRAMS, and filenames +# of TESTS that are programs. +sub append_exeext (&$) +{ + my ($pred, $macro) = @_; + + transform_variable_recursively + ($macro, $macro, 'am__EXEEXT', 0, INTERNAL, + sub { + my ($subvar, $val, $cond, $full_cond) = @_; + # Append $(EXEEXT) unless the user did it already, or it's a + # @substitution@. + $val .= '$(EXEEXT)' + if $val !~ /(?:\$\(EXEEXT\)$|^[@]\w+[@]$)/ && &$pred ($val); + return $val; + }); +} + + +# shadow_unconditionally ($varname, $where) +# ----------------------------------------- +# Return a $(variable) that contains all possible values +# $varname can take. +# If the VAR wasn't defined conditionally, return $(VAR). +# Otherwise we create an am__VAR_DIST variable which contains +# all possible values, and return $(am__VAR_DIST). +sub shadow_unconditionally +{ + my ($varname, $where) = @_; + my $var = var $varname; + if ($var->has_conditional_contents) + { + $varname = "am__${varname}_DIST"; + my @files = uniq ($var->value_as_list_recursive); + define_pretty_variable ($varname, TRUE, $where, @files); + } + return "\$($varname)" +} + + +# am_install_var (-OPTION..., file, HOW, where...) +# ------------------------------------------------ +# +# Handle 'where_HOW' variable magic. Does all lookups, generates +# install code, and possibly generates code to define the primary +# variable. The first argument is the name of the .am file to munge, +# the second argument is the primary variable (e.g. HEADERS), and all +# subsequent arguments are possible installation locations. +# +# Returns list of [$location, $value] pairs, where +# $value's are the values in all where_HOW variable, and $location +# there associated location (the place here their parent variables were +# defined). +# +# FIXME: this should be rewritten to be cleaner. It should be broken +# up into multiple functions. +sub am_install_var +{ + my (@args) = @_; + + my $do_require = 1; + my $can_dist = 0; + my $default_dist = 0; + while (@args) + { + if ($args[0] eq '-noextra') + { + $do_require = 0; + } + elsif ($args[0] eq '-candist') + { + $can_dist = 1; + } + elsif ($args[0] eq '-defaultdist') + { + $default_dist = 1; + $can_dist = 1; + } + elsif ($args[0] !~ /^-/) + { + last; + } + shift (@args); + } + + my ($file, $primary, @prefix) = @args; + + # Now that configure substitutions are allowed in where_HOW + # variables, it is an error to actually define the primary. We + # allow 'JAVA', as it is customarily used to mean the Java + # interpreter. This is but one of several Java hacks. Similarly, + # 'PYTHON' is customarily used to mean the Python interpreter. + reject_var $primary, "'$primary' is an anachronism" + unless $primary eq 'JAVA' || $primary eq 'PYTHON'; + + # Get the prefixes which are valid and actually used. + @prefix = am_primary_prefixes ($primary, $can_dist, @prefix); + + # If a primary includes a configure substitution, then the EXTRA_ + # form is required. Otherwise we can't properly do our job. + my $require_extra; + + my @used = (); + my @result = (); + + foreach my $X (@prefix) + { + my $nodir_name = $X; + my $one_name = $X . '_' . $primary; + my $one_var = var $one_name; + + my $strip_subdir = 1; + # If subdir prefix should be preserved, do so. + if ($nodir_name =~ /^nobase_/) + { + $strip_subdir = 0; + $nodir_name =~ s/^nobase_//; + } + + # If files should be distributed, do so. + my $dist_p = 0; + if ($can_dist) + { + $dist_p = (($default_dist && $nodir_name !~ /^nodist_/) + || (! $default_dist && $nodir_name =~ /^dist_/)); + $nodir_name =~ s/^(dist|nodist)_//; + } + + + # Use the location of the currently processed variable. + # We are not processing a particular condition, so pick the first + # available. + my $tmpcond = $one_var->conditions->one_cond; + my $where = $one_var->rdef ($tmpcond)->location->clone; + + # Append actual contents of where_PRIMARY variable to + # @result, skipping @substitutions@. + foreach my $locvals ($one_var->value_as_list_recursive (location => 1)) + { + my ($loc, $value) = @$locvals; + # Skip configure substitutions. + if ($value =~ /^\@.*\@$/) + { + if ($nodir_name eq 'EXTRA') + { + error ($where, + "'$one_name' contains configure substitution, " + . "but shouldn't"); + } + # Check here to make sure variables defined in + # configure.ac do not imply that EXTRA_PRIMARY + # must be defined. + elsif (! defined $configure_vars{$one_name}) + { + $require_extra = $one_name + if $do_require; + } + } + else + { + # Strip any $(EXEEXT) suffix the user might have added, + # or this will confuse handle_source_transform() and + # check_canonical_spelling(). + # We'll add $(EXEEXT) back later anyway. + # Do it here rather than in handle_programs so the + # uniquifying at the end of this function works. + ${$locvals}[1] =~ s/\$\(EXEEXT\)$// + if $primary eq 'PROGRAMS'; + + push (@result, $locvals); + } + } + # A blatant hack: we rewrite each _PROGRAMS primary to include + # EXEEXT. + append_exeext { 1 } $one_name + if $primary eq 'PROGRAMS'; + # "EXTRA" shouldn't be used when generating clean targets, + # all, or install targets. We used to warn if EXTRA_FOO was + # defined uselessly, but this was annoying. + next + if $nodir_name eq 'EXTRA'; + + if ($nodir_name eq 'check') + { + push (@check, '$(' . $one_name . ')'); + } + else + { + push (@used, '$(' . $one_name . ')'); + } + + # Is this to be installed? + my $install_p = $nodir_name ne 'noinst' && $nodir_name ne 'check'; + + # If so, with install-exec? (or install-data?). + my $exec_p = ($nodir_name =~ /$EXEC_DIR_PATTERN/o); + + my $check_options_p = $install_p && !! option 'std-options'; + + # Use the location of the currently processed variable as context. + $where->push_context ("while processing '$one_name'"); + + # The variable containing all files to distribute. + my $distvar = "\$($one_name)"; + $distvar = shadow_unconditionally ($one_name, $where) + if ($dist_p && $one_var->has_conditional_contents); + + # Singular form of $PRIMARY. + (my $one_primary = $primary) =~ s/S$//; + $output_rules .= file_contents ($file, $where, + PRIMARY => $primary, + ONE_PRIMARY => $one_primary, + DIR => $X, + NDIR => $nodir_name, + BASE => $strip_subdir, + EXEC => $exec_p, + INSTALL => $install_p, + DIST => $dist_p, + DISTVAR => $distvar, + 'CK-OPTS' => $check_options_p); + } + + # The JAVA variable is used as the name of the Java interpreter. + # The PYTHON variable is used as the name of the Python interpreter. + if (@used && $primary ne 'JAVA' && $primary ne 'PYTHON') + { + # Define it. + define_pretty_variable ($primary, TRUE, INTERNAL, @used); + $output_vars .= "\n"; + } + + err_var ($require_extra, + "'$require_extra' contains configure substitution,\n" + . "but 'EXTRA_$primary' not defined") + if ($require_extra && ! var ('EXTRA_' . $primary)); + + # Push here because PRIMARY might be configure time determined. + push (@all, '$(' . $primary . ')') + if @used && $primary ne 'JAVA' && $primary ne 'PYTHON'; + + # Make the result unique. This lets the user use conditionals in + # a natural way, but still lets us program lazily -- we don't have + # to worry about handling a particular object more than once. + # We will keep only one location per object. + my %result = (); + for my $pair (@result) + { + my ($loc, $val) = @$pair; + $result{$val} = $loc; + } + my @l = sort keys %result; + return map { [$result{$_}->clone, $_] } @l; +} + + +# @PREFIX +# am_primary_prefixes ($PRIMARY, $CAN_DIST, @PREFIXES) +# ---------------------------------------------------- +# Find all variable prefixes that are used for install directories. A +# prefix 'zar' qualifies iff: +# +# * 'zardir' is a variable. +# * 'zar_PRIMARY' is a variable. +# +# As a side effect, it looks for misspellings. It is an error to have +# a variable ending in a "reserved" suffix whose prefix is unknown, e.g. +# "bni_PROGRAMS". However, unusual prefixes are allowed if a variable +# of the same name (with "dir" appended) exists. For instance, if the +# variable "zardir" is defined, then "zar_PROGRAMS" becomes valid. +# This is to provide a little extra flexibility in those cases which +# need it. +sub am_primary_prefixes +{ + my ($primary, $can_dist, @prefixes) = @_; + + local $_; + my %valid = map { $_ => 0 } @prefixes; + $valid{'EXTRA'} = 0; + foreach my $var (variables $primary) + { + # Automake is allowed to define variables that look like primaries + # but which aren't. E.g. INSTALL_sh_DATA. + # Autoconf can also define variables like INSTALL_DATA, so + # ignore all configure variables (at least those which are not + # redefined in Makefile.am). + # FIXME: We should make sure that these variables are not + # conditionally defined (or else adjust the condition below). + my $def = $var->def (TRUE); + next if $def && $def->owner != VAR_MAKEFILE; + + my $varname = $var->name; + + if ($varname =~ /^(nobase_)?(dist_|nodist_)?(.*)_[[:alnum:]]+$/) + { + my ($base, $dist, $X) = ($1 || '', $2 || '', $3 || ''); + if ($dist ne '' && ! $can_dist) + { + err_var ($var, + "invalid variable '$varname': 'dist' is forbidden"); + } + # Standard directories must be explicitly allowed. + elsif (! defined $valid{$X} && exists $standard_prefix{$X}) + { + err_var ($var, + "'${X}dir' is not a legitimate directory " . + "for '$primary'"); + } + # A not explicitly valid directory is allowed if Xdir is defined. + elsif (! defined $valid{$X} && + $var->requires_variables ("'$varname' is used", "${X}dir")) + { + # Nothing to do. Any error message has been output + # by $var->requires_variables. + } + else + { + # Ensure all extended prefixes are actually used. + $valid{"$base$dist$X"} = 1; + } + } + else + { + prog_error "unexpected variable name: $varname"; + } + } + + # Return only those which are actually defined. + return sort grep { var ($_ . '_' . $primary) } keys %valid; +} + + +1; diff --git a/lib/Automake/Utils.pm b/lib/Automake/Utils.pm index 98c84e42b..a9009555a 100644 --- a/lib/Automake/Utils.pm +++ b/lib/Automake/Utils.pm @@ -19,6 +19,7 @@ use 5.006; use strict; use Automake::Channels; +use Automake::ConfVars; use Automake::Global; use Automake::Location; use Automake::Options; diff --git a/lib/Automake/local.mk b/lib/Automake/local.mk index c2e03cbe1..6a5a7101d 100644 --- a/lib/Automake/local.mk +++ b/lib/Automake/local.mk @@ -21,6 +21,7 @@ perllibdir = $(pkgvdatadir)/Automake dist_perllib_DATA = \ + %D%/TmpModule.pm \ %D%/ChannelDefs.pm \ %D%/Channels.pm \ %D%/Condition.pm \ -- cgit v1.2.1