automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: automake/370: Option ansi2knr mishandles sources in different direct


From: Alexandre Duret-Lutz
Subject: Re: automake/370: Option ansi2knr mishandles sources in different directories
Date: Wed, 27 Nov 2002 23:37:35 +0100
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/20.7 (i386-debian-linux-gnu)

>>> "Kevin" == Kevin Ryde <address@hidden> writes:

[...]

 Kevin> An alternative perhaps would be to lose the separate _.c
 Kevin> altogether and instead have a script to de-ansi then run
 Kevin> the compiler,

 Kevin> if ANSI2KNR
 Kevin> COMPILE = $(SHELL) run-ansi2knr "$(CPP)" "$(CPPFLAGS)" "$(CC)" $(CFLAGS)
 Kevin> else
 Kevin> COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS)
 Kevin> endif

 Kevin> Which if it worked would let everything happen through
 Kevin> the normal .c.o inference.

I like the idea.  This would remove many ansi2knr stuff from
Automake, and solve PR/374 at the same time.

I'm both eager and leery of getting rid of $U, though.  Maybe
this should be discussed on the main list first (in case people
depend on these _.c or _.o files, or other similar issues).

Anyway, as far Automake 1.7.2 is concerned, it seems safer to
stay with the current "technology".

 Kevin> But perhaps all this was considered and rejected when ansi2knr was
 Kevin> first introduced.

No idea.  The ansi2knr stuff predates the first ChangeLog entry,
and at this time I think I had never heard the word "Unix" :)

<aside>
 Kevin> Another advantage would be that objects selected by configure and
 Kevin> merely AC_SUBST'ed into an LDADD would get compiled correctly.
 Kevin> (Currently you have to make sure any potential source is mentioned in
 Kevin> a libdummy to ensure there's a .c->_.c rule for it.)

Instead of libdummy_SOURCES, can't you use EXTRA_foo_SOURCES?
Creating the .c->_.c rule is not the only reason why you must
tell Automake these sources exist.  They need to be known in
order to be distributed, and so that dependency tracking works.
You'd still need EXTRA_foo_SOURCES, would the _.c files
disappear.
</aside>

Here is my proposal.  The following patch puts the _.c files back
in the current directory, so your setup works again.  It also
fixes the dependencies-put-in-the-wrong-file issue I mentioned.

It doesn't fix PR/374, and it will still leave _.c in
subdirectories after distclean if subdir-objects is used.
(I'll try to address the latter issue -- not PR/374 -- 
before 1.7.2.)

The diff is against branch-1-7.  On HEAD you have to pass
a Location to file_contents.  I.e., change

|                  file_contents ($rule_file,
|                                 %transform,

into

|                  file_contents ($rule_file,
|                                 new Automake::Location,
|                                 %transform,

2002-11-27  Alexandre Duret-Lutz  <address@hidden>

        For PR automake/370:
        * automake.in (handle_languages): Don't prepend $U to $myext
        since handle_single_transform_list now appends it to $obj.
        Process the rule twice to handle deansified files in subdirectories.
        (handle_single_transform_list): Append $U to $obj_sans_ext if
        needed: before this dependencies were output foo.Po instead
        of foo$U.Po.  Don't output explicit dependencies for renamed
        objects or sources in sub-directories: we already output
        a full compile rule for them.
        (lang_c_finish): Don't always use the full filename in the
        .c -> _.c rule.  This reverts part of my change of 2002-11-21.
        * tests/ansi6.test: Make sure deansified files are created
        in the current directory.
        Reported by Kevin Ryde.

Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1365.2.11
diff -u -r1.1365.2.11 automake.in
--- automake.in 21 Nov 2002 11:53:24 -0000      1.1365.2.11
+++ automake.in 27 Nov 2002 21:20:09 -0000
@@ -2098,14 +2098,6 @@
        {
            my ($derived, $source, $obj, $myext) = split (' ', $file);
 
-           # For any specially-generated object, we must respect the
-           # ansi2knr setting so that we don't inadvertently try to
-           # use the default rule.
-           if ($lang->ansi && defined $options{'ansi2knr'})
-           {
-               $myext = '$U' . $myext;
-           }
-
            # We might see a given object twice, for instance if it is
            # used under different conditions.
            next if defined $seen_files{$obj};
@@ -2138,9 +2130,85 @@
                unless $depbase eq '';
            $depbase .= '$(DEPDIR)/' . basename ($obj);
 
-           # Generate a transform which will turn suffix targets in
-           # depend2.am into real targets for the particular objects we
-           # are building.
+           # Support for deansified files in subdirectories is ugly
+           # enough to deserve an explanation.
+           #
+           # A Note about normal ansi2knr processing first.  On
+           #
+           #   AUTOMAKE_OPTIONS = ansi2knr
+           #   bin_PROGRAMS = foo
+           #   foo_SOURCES = foo.c
+           #
+           # we generate rules similar to:
+           #
+           #   foo: foo$U.o; link ...
+           #   foo$U.o: foo$U.c; compile ...
+           #   foo_.c: foo.c; ansi2knr ...
+           #
+           # this is fairly compact, and will call ansi2knr depending
+           # on the value of $U (`' or `_').
+           #
+           # It's harder with subdir sources. On
+           #
+           #   AUTOMAKE_OPTIONS = ansi2knr
+           #   bin_PROGRAMS = foo
+           #   foo_SOURCES = sub/foo.c
+           #
+           # we have to create foo_.c in the current directory.
+           # (Unless the user asks 'subdir-objects'.)  This is important
+           # in case the same file (`foo.c') is compiled from other
+           # directories with different cpp options: foo_.c file would
+           # be preprocessed for only once set of options if it were
+           # but in the subdirectory.
+           #
+           # Because foo$U.o must be build from either foo_.c or
+           # sub/foo.c we can't be as concise as in the first example.
+           # Instead we output
+           #
+           #   foo: foo$U.o; link ...
+           #   foo_.o: foo_.c; compile ...
+           #   foo.o: sub/foo.c; compile ...
+           #   foo_.c: foo.c; ansi2knr ...
+           #
+           # This is why we'll now transform $rule_file twice
+           # if we detect this case.
+           # A first time we output the compile rule with `$U'
+           # replaced by `_' and the source directory removed,
+           # and another time we simply remove `$U'.
+           #
+           # Note that at this point $source (as computed by
+           # &handle_single_transform_list) is `sub/foo$U.c'.
+           # This can be confusing: it can be used as-is when
+           # subdir-objects is set, otherwise you have to know
+           # it really means `foo_.c' or `sub/foo.c'.
+           my $objdir = dirname ($obj);
+           my $srcdir = dirname ($source);
+           if ($lang->ansi && $obj =~ /\$U/ && $objdir ne $srcdir)
+             {
+               (my $obj_ = $obj) =~ s/\$U/_/g;
+               (my $depbase_ = $depbase) =~ s/\$U/_/g;
+               (my $source_ = basename ($source)) =~ s/\$U/_/g;
+
+               $output_rules .=
+                 file_contents ($rule_file,
+                                %transform,
+                                GENERIC   => 0,
+
+                                DEPBASE   => $depbase_,
+                                BASE      => $obj_,
+                                SOURCE    => $source_,
+                                OBJ       => "$obj_$myext",
+                                OBJOBJ    => "$obj_.obj",
+                                LTOBJ     => "$obj_.lo",
+
+                                COMPILE   => $obj_compile,
+                                LTCOMPILE => $obj_ltcompile,
+                                -o        => $output_flag);
+               $obj =~ s/\$U//g;
+               $depbase =~ s/\$U//g;
+               $source =~ s/\$U//g;
+             }
+
            $output_rules .=
              file_contents ($rule_file,
                             (%transform,
@@ -2312,7 +2380,6 @@
         my $directory = $1 || '';
         my $base = $2;
         my $extension = $3;
-       my $full_ansi = $full;  # We'll add `$U' if needed.
 
         # We must generate a rule for the object if it requires its own flags.
         my $renamed = 0;
@@ -2432,9 +2499,11 @@
             {
                 my $obj_sans_ext = substr ($object, 0,
                                           - length ($this_obj_ext));
+               my $full_ansi = $full;
                if ($lang->ansi && defined $options{'ansi2knr'})
                  {
                    $full_ansi =~ s/$KNOWN_EXTENSIONS_PATTERN$/\$U$&/;
+                   $obj_sans_ext .= '$U';
                  }
 
                my $val = ("$full_ansi $obj_sans_ext "
@@ -2530,13 +2599,6 @@
             my @dep_list = ();
             $object_map{$object} = $full;
 
-            # If file is in subdirectory, we need explicit
-            # dependency.
-            if ($directory ne '' || $renamed)
-            {
-                push (@dep_list, $full_ansi);
-            }
-
             # If resulting object is in subdir, we need to make
             # sure the subdir exists at build time.
             if ($object =~ /\//)
@@ -5541,8 +5603,7 @@
            # we can't use $< -- some makes only define $< during a
            # suffix rule.
            my $ansfile = $de_ansi_files{$base} . $base . '.c';
-           my $root = $de_ansi_files{$base} . $base;
-           $output_rules .= ($root . "_.c: $ansfile \$(ANSI2KNR)\n\t"
+           $output_rules .= ($base . "_.c: $ansfile \$(ANSI2KNR)\n\t"
                              . '$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) '
                              . '`if test -f $(srcdir)/' . $ansfile
                              . '; then echo $(srcdir)/' . $ansfile
Index: tests/ansi6.test
===================================================================
RCS file: /cvs/automake/automake/tests/ansi6.test,v
retrieving revision 1.2.2.1
diff -u -r1.2.2.1 ansi6.test
--- tests/ansi6.test    20 Nov 2002 23:29:17 -0000      1.2.2.1
+++ tests/ansi6.test    27 Nov 2002 21:20:10 -0000
@@ -72,9 +72,16 @@
 ./configure am_cv_prog_cc_stdc=no
 $MAKE
 
+test -f hello_.c
+test -f dir_.c                 # Must be in current directory.
+test ! -f sub/dir_.c
+$MAKE distclean
+test ! -f hello_.c
+test ! -f dir_.c
+
 # Also run without forcing ansi2knr, so we make sure the
 # rules work with ANSI compilers.
 # Report from Andreas Schwab.
-$MAKE distclean
+
 ./configure
 $MAKE

-- 
Alexandre Duret-Lutz





reply via email to

[Prev in Thread] Current Thread [Next in Thread]