[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: more locations (PR/360) + question
From: |
Alexandre Duret-Lutz |
Subject: |
FYI: more locations (PR/360) + question |
Date: |
29 Sep 2002 14:48:15 +0200 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 |
I'm installing this (on HEAD).
The main change is that errors occuring during &handle_programs,
&handle_libraries, or &handle_ltlibaries will display context
such as
Makefile.am:4: while processing program `foo'
with `Makefile.am:4:' being the location of the *_PROGRAMS variable
that contains foo.
This is possible because am_install_var now returns a list of
[$location, $value] pairs. (I have resisted the temptation to
have a global %value_to_location hash and continue to return a
list of values. Enventually I'd like the
`[$location, $value]' pair to be an object, so it's better to
not introduce globals.)
This change to am_install_var also allow us to point to the
ligne in Makefile.am that cause programs like elisp-comp or
py-compile to be installed.
location.test is a good example to illustrate the changes. Makefile.am
contains the following horror:
bin_PROGRAMS = libfoo.a
if COND2
lib_LIBRARIES = libfoo.a
endif
if COND1
bin_PROGRAMS += ctags
endif
automake-1.7 says
----------
automake-1.7: libfoo_a_OBJECTS should not be defined
automake-1.7: use `libfoo_a_LDADD', not `libfoo_a_LIBADD'
libfoo.a: deprecated feature: `libfoo.a' overrides `libfoo.a$(EXEEXT)'
libfoo.a: change your target to read `libfoo.a$(EXEEXT)'
/home/adl/usr/share/automake-1.7/am/tags.am: redefinition of `ctags'...
/home/adl/usr/share/automake-1.7/am/program.am: ... `ctags' previously defined
here.
----------
After the patch you get some context (plus a warning about the
redefinition of libfoo.a).
----------
internal: libfoo_a_OBJECTS should not be defined
Makefile.am:3: while processing library `libfoo.a'
internal: use `libfoo_a_LDADD', not `libfoo_a_LIBADD'
Makefile.am:3: while processing library `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/library.am: deprecated
feature: target `libfoo.a' overrides `libfoo.a$(EXEEXT)'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/library.am: change your
target to read `libfoo.a$(EXEEXT)'
Makefile.am:3: while processing library `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/program.am: target
`libfoo.a$(EXEEXT)' was defined here
Makefile.am:1: while processing program `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/program.am: redefinition of
`libfoo.a'...
Makefile.am:1: while processing program `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/library.am: ... `libfoo.a'
previously defined here
Makefile.am:3: while processing library `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/tags.am: redefinition of
`ctags'...
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/program.am: ... `ctags'
previously defined here
Makefile.am:6: while processing program `ctags'
----------
Now I'm open to suggestions about how these diagnostics could be
output in a way which is more readable. Would it be better to
add a new line between each diagnostic, as follow?
----------
internal: libfoo_a_OBJECTS should not be defined
Makefile.am:3: while processing library `libfoo.a'
internal: use `libfoo_a_LDADD', not `libfoo_a_LIBADD'
Makefile.am:3: while processing library `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/library.am: deprecated
feature: target `libfoo.a' overrides `libfoo.a$(EXEEXT)'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/library.am: change your
target to read `libfoo.a$(EXEEXT)'
Makefile.am:3: while processing library `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/program.am: target
`libfoo.a$(EXEEXT)' was defined here
Makefile.am:1: while processing program `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/program.am: redefinition of
`libfoo.a'...
Makefile.am:1: while processing program `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/library.am: ... `libfoo.a'
previously defined here
Makefile.am:3: while processing library `libfoo.a'
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/tags.am: redefinition of
`ctags'...
/home/adl/projs/cvs/automake/HEAD2/tests/../lib/am/program.am: ... `ctags'
previously defined here
Makefile.am:6: while processing program `ctags'
----------
Note, the patch is in `diff -b' format because I've reindented a
couple of large functions.
2002-09-29 Alexandre Duret-Lutz <address@hidden>
For PR automake/360: Propagate more locations.
* automake.in (handle_programs): Adjust usage of am_install_var's
return value. Pass on locations as context to file_contents.
(handle_libraries, handle_ltlibraries): Likewise. Use locations
in the 'not a standard library name' diagnostic.
(handle_emacs_lisp, handle_python): Adjust usage of am_install_var's
return value. Pass on locations to require_variables and
require_conf_file.
(check_ambiguous_conditional): Strip trailing dot in message.
(value_to_list): Add the $WHERE and $LOC_WANTED arguments.
(variable_value_as_list_recursive_worker): Add the $LOC_WANTED
argument. Adjust calls to value_to_list.
(variable_value_as_list_recursive): Call
variable_value_as_list_recursive_worker with $LOC_WANTED = 0.
(variable_loc_and_value_as_list_recursive): New function,
variable_value_as_list_recursive_worker with $LOC_WANTED = 1.
(am_install_var): Use variable_loc_and_value_as_list_recursive,
and return a list of [$location, $value] pairs.
(rule_define): Use better locations in EXEEXT diagnostic.
(handle_source_transform, define_objects_from_sources): Add and use
a $WHERE argument. Adjust callers.
* tests/stdlib.test: Grep the location in error message.
* tests/location.test: New file.
* tests/Makefile.am (TESTS): Add location.test.
Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1367
diff -u -b -r1.1367 automake.in
--- automake.in 29 Sep 2002 10:35:03 -0000 1.1367
+++ automake.in 29 Sep 2002 12:45:16 -0000
@@ -704,7 +704,7 @@
## --------------------------------- ##
sub register_language (%);
sub file_contents_internal ($$$%);
-sub define_objects_from_sources ($$$$$$$);
+sub define_objects_from_sources ($$$$$$$$);
# &initialize_per_input ()
@@ -2596,7 +2596,7 @@
# ($LINKER, $OBJVAR)
# define_objects_from_sources ($VAR, $OBJVAR, $NODEFINE, $ONE_FILE,
-# $OBJ, $PARENT, $TOPPARENT)
+# $OBJ, $PARENT, $TOPPARENT, $WHERE)
# ---------------------------------------------------------------------
# Define an _OBJECTS variable for a _SOURCES variable (or subvariable)
#
@@ -2610,6 +2610,7 @@
# $OBJ is the object extension (ie either `.o' or `.lo').
# $PARENT is the variable in which $VAR is used, or $VAR if not applicable.
# $TOPPARENT is the _SOURCES variable being processed.
+# $WHERE context into which this definition is done
#
# Result is a pair ($LINKER, $OBJVAR):
# $LINKER is a boolean, true if a linker is needed to deal with the objects,
@@ -2622,9 +2623,10 @@
# @substfroms and @substtos will be used to keep a stack of variable
# substitutions to be applied.
#
-sub define_objects_from_sources ($$$$$$$)
+sub define_objects_from_sources ($$$$$$$$)
{
- my ($var, $objvar, $nodefine, $one_file, $obj, $parent, $topparent) = @_;
+ my ($var, $objvar, $nodefine, $one_file, $obj,
+ $parent, $topparent, $where) = @_;
if (defined $vars_scanned{$var})
{
@@ -2665,7 +2667,8 @@
my ($temp, $varname)
= define_objects_from_sources ($subvar, undef,
$nodefine, $one_file,
- $obj, $var, $topparent);
+ $obj, $var, $topparent,
+ $where);
push (@result, '$('. $varname . ')');
$needlinker ||= $temp;
@@ -2699,7 +2702,7 @@
foreach my $pair (@allresults)
{
my ($cond, @result) = @$pair;
- define_pretty_variable ($objvar, $cond, INTERNAL, @result);
+ define_pretty_variable ($objvar, $cond, $where, @result);
}
}
@@ -2771,7 +2774,7 @@
{
# one_file is canonical name. unxformed is given name. obj is
# object extension.
- my ($one_file, $unxformed, $obj) = @_;
+ my ($one_file, $unxformed, $obj, $where) = @_;
my ($linker) = '';
@@ -2809,7 +2812,7 @@
define_objects_from_sources ($var,
$xpfx . $one_file . '_OBJECTS',
$prefix =~ /EXTRA_/,
- $one_file, $obj, $var, $var);
+ $one_file, $obj, $var, $var, $where);
$needlinker ||= $temp;
}
if ($needlinker)
@@ -2820,7 +2823,7 @@
my @keys = sort keys %used_pfx;
if (scalar @keys == 0)
{
- &define_variable ($one_file . "_SOURCES", $unxformed . ".c", INTERNAL);
+ &define_variable ($one_file . "_SOURCES", $unxformed . ".c", $where);
push (@sources, $unxformed . '.c');
push (@dist_sources, $unxformed . '.c');
@@ -2831,12 +2834,12 @@
$one_file, $obj,
"$unxformed.c");
$linker ||= &resolve_linker (%linkers_used);
- define_pretty_variable ($one_file . '_OBJECTS', '', INTERNAL, @result)
+ define_pretty_variable ($one_file . '_OBJECTS', '', $where, @result)
}
else
{
grep ($_ = '$(' . $_ . $one_file . '_OBJECTS)', @keys);
- define_pretty_variable ($one_file . '_OBJECTS', '', INTERNAL, @keys);
+ define_pretty_variable ($one_file . '_OBJECTS', '', $where, @keys);
}
# If we want to use `LINK' we must make sure it is defined.
@@ -3143,8 +3146,10 @@
my $seen_global_libobjs =
variable_defined ('LDADD') && &handle_lib_objects ('', 'LDADD');
- foreach my $one_file (@proglist)
+ foreach my $pair (@proglist)
{
+ my ($where, $one_file) = @$pair;
+
my $seen_libobjs = 0;
my $obj = &get_object_extension ($one_file);
@@ -3153,7 +3158,10 @@
'_SOURCES', '_OBJECTS',
'_DEPENDENCIES');
- my $linker = &handle_source_transform ($xname, $one_file, $obj);
+ $where->push_context ("while processing program `$one_file'");
+ $where->set (INTERNAL->get);
+
+ my $linker = &handle_source_transform ($xname, $one_file, $obj, $where);
my $xt = '';
if (variable_defined ($xname . "_LDADD"))
@@ -3164,7 +3172,7 @@
else
{
# User didn't define prog_LDADD override. So do it.
- &define_variable ($xname . '_LDADD', '$(LDADD)', INTERNAL);
+ &define_variable ($xname . '_LDADD', '$(LDADD)', $where);
# This does a bit too much work. But we need it to
# generate _DEPENDENCIES when appropriate.
@@ -3174,7 +3182,7 @@
}
elsif (! variable_defined ($xname . '_DEPENDENCIES'))
{
- &define_variable ($xname . '_DEPENDENCIES', '', INTERNAL);
+ &define_variable ($xname . '_DEPENDENCIES', '', $where);
}
$xt = '_SOURCES';
}
@@ -3185,7 +3193,7 @@
if (! variable_defined ($xname . '_LDFLAGS'))
{
# Define the prog_LDFLAGS variable.
- &define_variable ($xname . '_LDFLAGS', '', INTERNAL);
+ &define_variable ($xname . '_LDFLAGS', '', $where);
}
# Determine program to use for link.
@@ -3209,7 +3217,7 @@
: '');
$output_rules .= &file_contents ('program',
- new Automake::Location,
+ $where,
PROGRAM => $one_file,
XPROGRAM => $xname,
XLINK => $xlink,
@@ -3247,17 +3255,20 @@
'library used', 'RANLIB')
if (@prefix);
- foreach my $onelib (@liblist)
+ foreach my $pair (@liblist)
{
+ my ($where, $onelib) = @$pair;
+
my $seen_libobjs = 0;
# Check that the library fits the standard naming convention.
if (basename ($onelib) !~ /^lib.*\.a/)
{
- # FIXME should put line number here. That means mapping
- # from library name back to variable name.
- err_am "`$onelib' is not a standard library name";
+ err $where, "`$onelib' is not a standard library name";
}
+ $where->push_context ("while processing library `$onelib'");
+ $where->set (INTERNAL->get);
+
my $obj = &get_object_extension ($onelib);
# Canonicalize names and check for misspellings.
@@ -3267,7 +3278,7 @@
if (! variable_defined ($xlib . '_AR'))
{
- &define_variable ($xlib . '_AR', '$(AR) cru', INTERNAL);
+ &define_variable ($xlib . '_AR', '$(AR) cru', $where);
}
if (variable_defined ($xlib . '_LIBADD'))
@@ -3281,7 +3292,7 @@
{
# Generate support for conditional object inclusion in
# libraries.
- &define_variable ($xlib . "_LIBADD", '', INTERNAL);
+ &define_variable ($xlib . "_LIBADD", '', $where);
}
reject_var ($xlib . '_LDADD',
@@ -3290,14 +3301,14 @@
# Make sure we at look at this.
&examine_variable ($xlib . '_DEPENDENCIES');
- &handle_source_transform ($xlib, $onelib, $obj);
+ &handle_source_transform ($xlib, $onelib, $obj, $where);
# If the resulting library lies into a subdirectory,
# make sure this directory will exist.
my $dirstamp = require_build_directory_maybe ($onelib);
$output_rules .= &file_contents ('library',
- new Automake::Location,
+ $where,
LIBRARY => $onelib,
XLIBRARY => $xlib,
DIRSTAMP => $dirstamp);
@@ -3366,8 +3377,10 @@
}
}
- foreach my $onelib (@liblist)
+ foreach my $pair (@liblist)
{
+ my ($where, $onelib) = @$pair;
+
my $seen_libobjs = 0;
my $obj = &get_object_extension ($onelib);
@@ -3376,12 +3389,6 @@
'_SOURCES', '_OBJECTS',
'_DEPENDENCIES');
- if (! variable_defined ($xlib . '_LDFLAGS'))
- {
- # Define the lib_LDFLAGS variable.
- &define_variable ($xlib . '_LDFLAGS', '', INTERNAL);
- }
-
# Check that the library fits the standard naming convention.
my $libname_rx = "^lib.*\.la";
if ((variable_defined ($xlib . '_LDFLAGS')
@@ -3397,12 +3404,19 @@
}
if (basename ($onelib) !~ /$libname_rx$/)
{
- # FIXME should put line number here. That means mapping
- # from library name back to variable name.
- msg_am ('error-gnu/warn',
+ msg ($where, 'error-gnu/warn',
"`$onelib' is not a standard libtool library name");
}
+ $where->push_context ("while processing Libtool library `$onelib'");
+ $where->set (INTERNAL->get);
+
+ if (! variable_defined ($xlib . '_LDFLAGS'))
+ {
+ # Define the lib_LDFLAGS variable.
+ &define_variable ($xlib . '_LDFLAGS', '', $where);
+ }
+
if (variable_defined ($xlib . '_LIBADD'))
{
if (&handle_lib_objects ($xlib, $xlib . '_LIBADD'))
@@ -3414,7 +3428,7 @@
{
# Generate support for conditional object inclusion in
# libraries.
- &define_variable ($xlib . "_LIBADD", '', INTERNAL);
+ &define_variable ($xlib . "_LIBADD", '', $where);
}
reject_var ("${xlib}_LDADD",
@@ -3423,7 +3437,7 @@
# Make sure we at look at this.
&examine_variable ($xlib . '_DEPENDENCIES');
- my $linker = &handle_source_transform ($xlib, $onelib, $obj);
+ my $linker = &handle_source_transform ($xlib, $onelib, $obj, $where);
# Determine program to use for link.
my $xlink;
@@ -3462,7 +3476,7 @@
$libtool_clean_directories{$dirname} = 1;
$output_rules .= &file_contents ('ltlibrary',
- new Automake::Location,
+ $where,
LTLIBRARY => $onelib,
XLTLIBRARY => $xlib,
RPATH => $rpath,
@@ -4605,7 +4619,7 @@
'noinst', 'check');
foreach (@r)
{
- next unless /\..*$/;
+ next unless $_->[1] =~ /\..*$/;
&saw_extension ($&);
}
}
@@ -4969,14 +4983,14 @@
return if ! @elfiles;
# Generate .elc files.
- my @elcfiles = map { $_ . 'c' } @elfiles;
+ my @elcfiles = map { $_->[1] . 'c' } @elfiles;
define_pretty_variable ('ELCFILES', '', INTERNAL, @elcfiles);
push (@all, '$(ELCFILES)');
- require_variables ("$am_file.am", "Emacs Lisp sources seen", 'TRUE',
+ require_variables ($elfiles[0][0], "Emacs Lisp sources seen", 'TRUE',
'EMACS', 'lispdir');
- require_conf_file ("$am_file.am", FOREIGN, 'elisp-comp');
+ require_conf_file ($elfiles[0][0], FOREIGN, 'elisp-comp');
&define_variable ('elisp_comp', $config_aux_dir . '/elisp-comp', INTERNAL);
}
@@ -4987,9 +5001,8 @@
'noinst');
return if ! @pyfiles;
- require_variables ("$am_file.am", "Python sources seen", 'TRUE',
- 'PYTHON');
- require_conf_file ("$am_file.am", FOREIGN, 'py-compile');
+ require_variables ($pyfiles[0][0], "Python sources seen", 'TRUE', 'PYTHON');
+ require_conf_file ($pyfiles[0][0], FOREIGN, 'py-compile');
&define_variable ('py_compile', $config_aux_dir . '/py-compile', INTERNAL);
}
@@ -6126,7 +6139,7 @@
if ($message)
{
msg 'syntax', $where, "$message ...";
- msg_var ('syntax', $var, "... `$var' previously defined here.");
+ msg_var ('syntax', $var, "... `$var' previously defined here");
verb (macro_dump ($var));
}
}
@@ -7022,8 +7035,8 @@
# @VALUES
-# &value_to_list ($VAR, $VAL, $COND)
-# ----------------------------------
+# &value_to_list ($VAR, $VAL, $COND, $WHERE, $LOC_WANTED)
+# -------------------------------------------------------
# Convert a variable value to a list, split as whitespace. This will
# recursively follow $(...) and ${...} inclusions. It preserves @...@
# substitutions.
@@ -7032,23 +7045,25 @@
# returned; if COND is a particular condition (all conditions are
# surrounded by @...@) then only the value for that condition should
# be returned; otherwise, warn if VAR is conditionally defined.
-# SCANNED is a global hash listing whose keys are all the variables
-# already scanned; it is an error to rescan a variable.
-sub value_to_list ($$$)
+# WHERE is the location where VAR=VAL.
+# If LOC_WANTED is set, return a list of [$location, @values] instead
+# of a list of @values.
+sub value_to_list ($$$$$)
{
- my ($var, $val, $cond) = @_;
+ my ($var, $val, $cond, $where, $loc_wanted) = @_;
my @result;
# Strip backslashes
- $val =~ s/\\(\n|$)/ /g;
+ $val =~ s/\\$/ /gm;
foreach (split (' ', $val))
{
# If a comment seen, just leave.
last if /^#/;
- # Handle variable substitutions.
- if (/^\$\{([^}]*)\}$/ || /^\$\(([^)]*)\)$/)
+ # Handle variable substitutions. (The backslash in [^\}] and [^\)]
+ # is here to help Emacs indenting correctly.)
+ if (/^\$\{([^\}]*)\}$/ || /^\$\(([^\)]*)\)$/)
{
my $varname = $1;
@@ -7067,18 +7082,30 @@
# Find the value.
@temp_list =
- variable_value_as_list_recursive_worker ($1, $cond, $var);
+ variable_value_as_list_recursive_worker ($1, $cond, $var,
+ $loc_wanted);
- # Now rewrite the value if appropriate.
+ # Now rewrite the values if appropriate.
if (defined $from)
{
- grep (s/$from$/$to/, @temp_list);
+ for my $val (@temp_list)
+ {
+ if ($loc_wanted)
+ {
+ $val->[0] =~ s/$from$/$to/;
+ }
+ else
+ {
+ $val =~ s/$from$/$to/;
+ }
+ }
}
push (@result, @temp_list);
}
else
{
+ $_ = [$where->clone, $_] if $loc_wanted;
push (@result, $_);
}
}
@@ -7143,8 +7170,8 @@
# @VALUE
-# &variable_value_as_list_recursive_worker ($VAR, $COND, $PARENT)
-# ---------------------------------------------------------------
+# &variable_value_as_list_recursive_worker ($VAR, $COND, $PARENT, $LOC_WANTED)
+# ----------------------------------------------------------------------------
# Return contents of VAR as a list, split on whitespace. This will
# recursively follow $(...) and ${...} inclusions. It preserves @...@
# substitutions. If COND is 'all', then all values under all
@@ -7153,9 +7180,11 @@
# that condition should be returned; otherwise, warn if VAR is
# conditionally defined. If PARENT is specified, it is the name of
# the including variable; this is only used for error reports.
-sub variable_value_as_list_recursive_worker ($$$)
+# If $LOC_WANTED is set, return a list of [$location, @values] instead
+# of a list of @values.
+sub variable_value_as_list_recursive_worker ($$$$)
{
- my ($var, $cond, $parent) = @_;
+ my ($var, $cond, $parent, $loc_wanted) = @_;
my @result = ();
return
@@ -7172,8 +7201,11 @@
$vars_scanned{$var} = 1;
foreach my $vcond (keys %{$var_value{$var}})
{
- my $val = $var_value{$var}{$vcond};
- push (@result, &value_to_list ($var, $val, $cond));
+ push (@result, &value_to_list ($var,
+ $var_value{$var}{$vcond},
+ $cond,
+ $var_location{$var}{$vcond},
+ $loc_wanted));
}
}
else
@@ -7184,6 +7216,7 @@
foreach my $vcond (keys %{$var_value{$var}})
{
my $val = $var_value{$var}{$vcond};
+ my $where = $var_location{$var}{$vcond};
if (&conditional_true_when ($vcond, $cond))
{
# Warn if we have an ambiguity. It's hard to know how
@@ -7191,7 +7224,8 @@
&check_variable_defined_unconditionally ($var, $parent)
if $onceflag;
$onceflag = 1;
- push (@result, &value_to_list ($var, $val, $cond));
+ push (@result, &value_to_list ($var, $val, $cond, $where,
+ $loc_wanted));
}
}
}
@@ -7265,16 +7299,31 @@
}
-# &variable_value_as_list_recursive ($VAR, $COND, $PARENT)
-# --------------------------------------------------------
-# This is just a wrapper for variable_value_as_list_recursive_worker that
-# initializes the global hash `vars_scanned'. This hash is used to
-# avoid infinite recursion.
-sub variable_value_as_list_recursive ($$@)
+# &variable_value_as_list_recursive ($VAR, $COND, [$PARENT])
+# ----------------------------------------------------------
+# Return the list of values of $VAR in condition $COND.
+# $PARENT (if known) is the variable where this variable occurs,
+# in case we need to print an error message.
+sub variable_value_as_list_recursive ($$;$)
+{
+ my ($var, $cond, $parent) = @_;
+ # This global hash is used to avoid infinite recursion in
+ # &variable_value_as_list_recursive_worker.
+ %vars_scanned = ();
+ return &variable_value_as_list_recursive_worker ($var, $cond, $parent, 0);
+}
+
+# &variable_loc_and_value_as_list_recursive ($VAR, $COND, [$PARENT])
+# ----------------------------------------------------------------
+# Return the values of $VAR in condition $COND as a list of
+# [$location, @values] pairs.
+# $PARENT (if known) is the variable where this variable occurs,
+# in case we need to print an error message.
+sub variable_loc_and_value_as_list_recursive ($$;$)
{
my ($var, $cond, $parent) = @_;
%vars_scanned = ();
- return &variable_value_as_list_recursive_worker ($var, $cond, $parent);
+ return &variable_value_as_list_recursive_worker ($var, $cond, $parent, 1);
}
@@ -7450,7 +7499,7 @@
# is the filename the rule comes from. $OWNER is the
# owener of the rule (TARGET_AUTOMAKE or TARGET_USER).
# $COND is the condition string under which the rule is defined.
-# $WHERE is where the rule is defined (file name and/or line number).
+# $WHERE is the location where the rule is defined.
# Returns a (possibly empty) list of conditions where the rule
# should be defined.
sub rule_define ($$$$$)
@@ -7474,12 +7523,14 @@
# The no-exeext option enables this feature.
if (! defined $options{'no-exeext'})
{
- msg ('obsolete', $noexe,
- "deprecated feature: `$noexe' overrides `$noexe\$(EXEEXT)'\n"
+ msg ('obsolete', $targets{$noexe}{$cond},
+ "deprecated feature: target `$noexe' overrides "
+ . "`$noexe\$(EXEEXT)'\n"
. "change your target to read `$noexe\$(EXEEXT)'");
+ msg ('obsolete', $where, "target `$target' was defined here");
}
- # Don't define.
- return ();
+ # Don't `return ()' now, as this might hide target clashes
+ # detected below.
}
# For now on, strip off $(EXEEXT) from $target, so we can diagnose
@@ -7530,7 +7581,7 @@
# msg ('syntax', $where,
# "redefinition of `$target'$condmsg...");
# msg_cond_target ('syntax', $cond, $target,
- # "... `$target' previously defined here.");
+ # "... `$target' previously defined here");
}
# Return so we don't redefine the rule in our tables,
# don't check for ambiguous conditional, etc. The rule
@@ -7569,7 +7620,7 @@
msg ('syntax', $where, "redefinition of `$target'$condmsg...");
msg_cond_target ('syntax', $cond, $target,
- "... `$target' previously defined here.");
+ "... `$target' previously defined here");
return ();
}
}
@@ -7590,7 +7641,7 @@
# For user rules, just diagnose the ambiguity.
msg 'syntax', $where, "$message ...";
msg_cond_target ('syntax', $ambig_cond, $target,
- "... `$target' previously defined here.");
+ "... `$target' previously defined here");
return ();
}
else
@@ -7626,7 +7677,7 @@
{
msg 'syntax', $where, "$message ...";
msg_cond_target ('syntax', $ambig_cond, $target,
- "... `$target' previously defined here.");
+ "... `$target' previously defined here");
return ();
}
}
@@ -8510,8 +8561,12 @@
# 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 (eg HEADERS), and all
-# subsequent arguments are possible installation locations. Returns
-# list of all values of all _HOW targets.
+# 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.
@@ -8591,16 +8646,28 @@
$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 = (keys %{$var_value{$one_name}})[0];
+ my $where = $var_location{$one_name}{$tmpcond}->clone;
+
# Append actual contents of where_PRIMARY variable to
# result.
- foreach my $rcurs (&variable_value_as_list_recursive ($one_name, 'all'))
+ foreach my $locvals (&variable_loc_and_value_as_list_recursive
+ ($one_name, 'all'))
+ {
+ my ($loc, @values) = @$locvals;
+ my @nosubst = (); # @values without substitutions.
+ for my $rcurs (@values)
{
# Skip configure substitutions. Possibly bogus.
if ($rcurs =~ /address@hidden@$/)
{
if ($nodir_name eq 'EXTRA')
{
- err_var ($one_name,
+ err ($where,
"`$one_name' contains configure substitution, "
. "but shouldn't");
}
@@ -8612,11 +8679,11 @@
$require_extra = $one_name
if $do_require;
}
-
next;
}
-
- push (@result, $rcurs);
+ push @nosubst, $rcurs;
+ }
+ push (@result, [$loc, @nosubst]) if @nosubst;
}
# A blatant hack: we rewrite each _PROGRAMS primary to include
# EXEEXT.
@@ -8647,10 +8714,6 @@
&& defined $options{'std-options'};
# Use the location of the currently processed variable as context.
- # We are not processing a particular condition, so pick the first
- # available.
- my $cond = (keys %{$var_value{$one_name}})[0];
- my $where = $var_location{$one_name}{$cond}->clone;
$where->push_context ("while processing `$one_name'");
# Singular form of $PRIMARY.
@@ -8693,7 +8756,18 @@
# 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.
- return uniq (sort @result);
+ # We will keep only one location per object.
+ my %result = ();
+ for my $pair (@result)
+ {
+ my ($loc, @values) = @$pair;
+ for my $val (@values)
+ {
+ $result{$val} = $loc;
+ }
+ }
+ my @l = sort keys %result;
+ return map { [$result{$_}->clone, $_] } @l;
}
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.am,v
retrieving revision 1.444
diff -u -b -r1.444 Makefile.am
--- tests/Makefile.am 29 Sep 2002 10:35:03 -0000 1.444
+++ tests/Makefile.am 29 Sep 2002 12:45:17 -0000
@@ -240,6 +240,7 @@
lisp.test \
lisp2.test \
listval.test \
+location.test \
ltdeps.test \
ltlibobjs.test \
maintclean.test \
Index: tests/location.test
===================================================================
RCS file: tests/location.test
diff -N tests/location.test
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/location.test 29 Sep 2002 12:45:18 -0000
@@ -0,0 +1,51 @@
+#! /bin/sh
+# Copyright (C) 2002 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 autoconf; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Test for locations in error messages.
+
+. ./defs || exit 1
+
+set -e
+
+cat >> configure.in << 'END'
+AM_CONDITIONAL([COND1], [true])
+AM_CONDITIONAL([COND2], [true])
+AC_PROG_CC
+AC_PROG_RANLIB
+END
+
+cat > Makefile.am << 'END'
+bin_PROGRAMS = libfoo.a
+if COND2
+ lib_LIBRARIES = libfoo.a
+endif
+if COND1
+ bin_PROGRAMS += ctags
+endif
+END
+
+$ACLOCAL
+$AUTOMAKE 2>stderr && exit 1
+cat stderr
+grep 'Makefile\.am:1:.*program.*libfoo\.a' stderr
+grep 'Makefile\.am:3:.*library.*libfoo\.a' stderr
+grep 'Makefile\.am:6:.*program.*ctags' stderr
+grep 'redefinition of.*libfoo\.a' stderr
+grep 'redefinition of.*ctags' stderr
Index: tests/stdlib.test
===================================================================
RCS file: /cvs/automake/automake/tests/stdlib.test,v
retrieving revision 1.3
diff -u -b -r1.3 stdlib.test
--- tests/stdlib.test 8 Sep 2002 13:07:56 -0000 1.3
+++ tests/stdlib.test 29 Sep 2002 12:45:18 -0000
@@ -22,6 +22,8 @@
. ./defs || exit 1
+set -e
+
cat >> configure.in << 'END'
AC_PROG_CC
AC_PROG_RANLIB
@@ -31,9 +33,8 @@
noinst_LIBRARIES = foo
END
-$ACLOCAL || exit 1
+$ACLOCAL
$AUTOMAKE 2> output.log && exit 1
+cat output.log
# We're specifically testing for line-number information.
-# Well, when it is implemented.
-# grep 1 output.log
-exit 0
+grep 'Makefile.am:1:.*foo.*standard library name' output.log
--
Alexandre Duret-Lutz
- FYI: more locations (PR/360) + question,
Alexandre Duret-Lutz <=