[bug #42270] Make needs to canonicalise paths

2023-08-31 Thread Kaz Kylheku
Follow-up Comment #2, bug #42270 (project make):

The bug wasn't opened by someone looking to have symlinks resolved, but that's
what will happen if you canonicalize paths.

Applications must assume that symbolic links belong to the user and not expand
them, unless somehow explicitly requested.

Applications that canonicalize path names and expand symbolic links do wrong,
annoying things, such as put files into the wrong directories.

Suppose we have a file

  src/parser.c -> ../../foo-project/src/parser.c

When we build parser.c we want parser.o to be right here based on editing
src/parser.c to src/parser.o.

Suppose the build system canonicalizes the path, turning src/parser.c into
/home/bob/foo-project/src/parser.c. And then calculates the .o file from that?
We end up with the object file going to  ../../foo-project/src/parser.o where
we don't want it.

Symbolic links are something **the user set up to fool the application**.

Applications should cooperate and **stay fooled**.

I think the right position in Make is that if the user has used symbolic links
(or any other path mechanism like ".." and "." links or absolute versus
relative) such that they refer to the same file using two different paths,
that's their problem; it's pretty easy to avoid, and avoiding that will almost
certainly improve the clarity of the Makefile.

GNU Make has all the tools: it has $(realpath ...) and $(abspath ...); it's up
to the Makefile programmer to decide whether either of these should be used
and how, and avoid situations when accessing the same thing using two or more
paths causes a problem.



___

Reply to this item at:

  

___
Message sent via Savannah
https://savannah.gnu.org/




[bug #10593] $(shell) doesn't honor export but this is undocumented?

2022-07-09 Thread Kaz Kylheku
Follow-up Comment #8, bug #10593 (project make):

This solution works for me, thanks to $(shell var=val  command arg ...)
working fine:

  # put desired env vars into "shell_env" variable
  shell_exports := foo000=bar000 foo001=bar001
  
  # interpolate variable as a prefix of shell command
  $(info $(shell $(shell_exports) env | grep bar))

The Makefile can maintain a shell_exports variable as it sees fit, adding to
it with +=, removing using filter/filter-out and whatnot.





___

Reply to this item at:

  

___
Message sent via Savannah
https://savannah.gnu.org/




[bug #8297] Allow multiple targets to be built from a single explicit rule recipe invocation

2019-03-14 Thread Kaz Kylheku
Additional Item Attachment, bug #8297 (project make):

File name: 0001-Implement-grouped-targets-in-ordinary-rules.patch Size:23 KB
   




___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #8297] Allow multiple targets to be built from a single explicit rule recipe invocation

2019-03-14 Thread Kaz Kylheku
Follow-up Comment #9, bug #8297 (project make):

Regarding the past discussion, this comment by Henning Makholm:

https://lists.gnu.org/archive/html/make-alpha/2002-12/msg7.html

provides an accurate synopsis of what I have also done.

>From the GNU Make manual, I realized that the semantics is already present in
pattern rules. Then in the code I found the also_make member of struct file
and so it went.


___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #8297] Allow multiple targets to be built from a single explicit rule recipe invocation

2019-03-14 Thread Kaz Kylheku
Additional Item Attachment, bug #8297 (project make):

File name: 0001-Implement-grouped-targets-in-ordinary-rules.patch Size:20 KB
   




___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #8297] Allow multiple targets to be built from a single explicit rule recipe invocation

2019-03-14 Thread Kaz Kylheku
Additional Item Attachment, bug #8297 (project make):

File name: 0001-Implement-grouped-targets-in-ordinary-rules.patch Size:20 KB
   




___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #8297] Allow multiple targets to be built from a single explicit rule recipe invocation

2019-03-13 Thread Kaz Kylheku
Follow-up Comment #8, bug #8297 (project make):

The patch I uploaded just now is almost the same as what I posted to the
mailing list, modulo fixing a memory leak (not freeing the also_make dep list
built up in the register_files function).

Paul Smith pointed to this bug and suggested the &: syntax instead; I will be
reworking the change to use that syntax.


___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #8297] Allow multiple targets to be built from a single explicit rule recipe invocation

2019-03-13 Thread Kaz Kylheku
Additional Item Attachment, bug #8297 (project make):

File name: 0001-Implement-grouped-targets-in-ordinary-rules.patch Size:10 KB
   




___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #10593] $(shell) doesn't honor export but this is undocumented?

2016-05-10 Thread Kaz Kylheku
Follow-up Comment #5, bug #10593 (project make):

Of course this creates a backward compatibility problem if it is fixed. It is
a change to existing behavior. For any such change, we can contrive code which
depends on the old behavior.

For instance, when ISO C added // comments in 1999, it broke code such as
a//*comment*/b which denotes the division a/b.

If any such a change is forbidden, then it leaves the language development
hamstrung against fixing certain kinds of bugs and improvements.

The improvements still happen, but in kludgy ways which are like legs growing
out of a forehead. You always have to think: if I started with a clean slate,
not saddled by backward compatibility, could I still justify doing it this
way?

The way to address this is to have some controls over the language dialect.
For instance, GNU Make could have a command line option for emulating a prior
version. As well as a special variable that cold be deposited into a Makefile.
Say, --emulate=3.81 or __GMAKE_EMULATE := 3.81.

Someone whose code breaks because of a fix like this can use the mechanism as
a quick workaround.


___

Reply to this item at:

  

___
  Message sent via/by Savannah
  http://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #43757] Target-specific assigments influencing whether target considered intermediate.

2015-07-13 Thread Kaz Kylheku
Follow-up Comment #2, bug #43757 (project make):

I must say I cannot agree with the analysis of the previous comment.

A target listed in a target-specific variable assignment is, at best,
*syntactically* a target, not semantically.  Obviously, it cannot be
semantically because the variable assignment isn't a prerequisite, and doesn't
declare a rule. Target is the name for a semantic role of an object with
respect to an update rule, and possibly some prerequisites.

A target-specific variable assignment only scopes some variables around a
target, if that target happens to be updated.

It is buggy behavior to have some targets be considered permanent, just
because I want to customize their update recipe with some target-specific
variables.

The mention concept should depend on semantics, not syntax.

Of course, I read that line in the manual, but I wouldn't guess that an
assignment means mentioned as a target.

Lastly, here is something else. Suppose I take a Makefile whose default target
is all, and add this line at the very top:

   foo: BAR := xyzzy

If I run make now with no arguments, it still says nothing to be done for
`all'.

Clearly, Make is not considering foo to be mentioned as a target, otherwise
it would have to consider foo to be the first target in the Makefile, and
hence the default target.

___

Reply to this item at:

  http://savannah.gnu.org/bugs/?43757

___
  Message sent via/by Savannah
  http://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #43757] Target-specific assigments influencing whether target considered intermediate.

2014-12-04 Thread Kaz Kylheku
URL:
  http://savannah.gnu.org/bugs/?43757

 Summary: Target-specific assigments influencing whether
target considered intermediate.
 Project: make
Submitted by: kkylheku
Submitted on: Thu 04 Dec 2014 05:20:14 PM PST
Severity: 3 - Normal
  Item Group: Bug
  Status: None
 Privacy: Public
 Assigned to: None
 Open/Closed: Open
 Discussion Lock: Any
   Component Version: 3.81
Operating System: POSIX-Based
   Fixed Release: None
   Triage Status: None

___

Details:

Background:

I have a Makefile in which tests are executed by running a make tests
target.

The test rules work with files having several suffixes: .ok, .out, .expected
and .txr

The foo.ok file is a timestamp, which is updated by a rule that only succeeds
if foo.out matches foo.expected.

%.ok depends on %.out, and %.out depends on %.txr: a foo.txr script is run
with some arguments to produce foo.out.

Now some of the %.out targets have target specific assignments to set up some
command line arguments and whatnot for the test.

STRANGE BEHAVIOR: it seems that those %.out targets which do not have
target-specific assignments are not considered to be intermediate files.  They
are not deleted.  Those %.out targets which have no target-specific
assignments are deleted.

Example run:

# this .out file has a target-specific assignment
$ rm tests/009/json.out
$ make tests/009/json.ok
mkdir -p tests/009/
./txr --gc-debug  tests/009/json.txr /home/kaz/txr/tests /009/webapp.json
/home/kaz/txr/tests/009/pass1.json  tests/009/json.out
diff -u tests/009/json.expected tests/009/json.out

Notice there is no removal of the intermediate .out file here! If I remove the
target-specific assignment then the behavior is different:

$ make tests/009/json.ok
mkdir -p tests/009/
./txr --gc-debug  tests/009/json.txr   tests/009/json.out
diff -u tests/009/json.expected tests/009/json.out
rm tests/009/json.out

Note the rm command at the end, issued by GNU Make.

Now for the following different .out file, there is a target-specific
assignment, but of a slightly different form.

$ make tests/011/txr-case.ok
mkdir -p tests/011/
./txr   tests/011/txr-case.txr   tests/011/txr-case.out
diff -u tests/011/txr-case.expected tests/011/txr-case.out
rm tests/011/txr-case.out

Note the rm command here, eliminating the intermediate file.

In the non-removal case (tests/009/json.out) even interrupting make does not
ensure that the .out file is gone.

The target specific assignments are:

tests/009/json.out: TXR_ARGS := $(addprefix
$(top_srcdir)/tests/009/,webapp.json pass1.json)

tests/011/%: TXR_DBG_OPTS :=

One is a concrete, one is a pattern.

The relevant rules are just:

%.out: %.txr
   mkdir -p $(dir $@)
   $(if $(TXR_SCRIPT_ON_CMDLINE),\
 $(TXR) $(TXR_DBG_OPTS) $(TXR_OPTS) -c $$(cat $) \
   $(TXR_ARGS)  $@,\
 $(TXR) $(TXR_DBG_OPTS) $(TXR_OPTS) $ $(TXR_ARGS)  $@)

%.ok: %.out
   diff -u $(:.out=.expected) $
   @touch $@

%.expected: %.out
   cp $ $@


Am I running into a documented behavior?




___

Reply to this item at:

  http://savannah.gnu.org/bugs/?43757

___
  Message sent via/by Savannah
  http://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #43432] Two flavors of variable: describe more aptly, in line with other languages.

2014-10-17 Thread Kaz Kylheku
URL:
  http://savannah.gnu.org/bugs/?43432

 Summary: Two flavors of variable: describe more aptly, in
line with other languages.
 Project: make
Submitted by: kkylheku
Submitted on: Fri 17 Oct 2014 11:50:57 AM PDT
Severity: 3 - Normal
  Item Group: Documentation
  Status: None
 Privacy: Public
 Assigned to: None
 Open/Closed: Open
 Discussion Lock: Any
   Component Version: None
Operating System: None
   Fixed Release: None
   Triage Status: None

___

Details:

The GNU Make manual describes two flavors of variable, at length. The
flavors are called recursively expanded and simply expanded.

In fact, the situation is that the := and ::= variables are more or less what
people understand as variables in programming languages like the POSIX shell,
Lisp or C.  When the name of such a variable appears somewhere (perhaps with
some special sygil syntax like $FOO, $(FOO) or ${FOO} or whatever), it behaves
as an expression which is reduced to the value of the variable: what it
contains.

The traditional make variables pretty much correspond to unparametrized
macros: they are like preprocessor macros in the C language, or
define-symbol-macro macros in Common Lisp.  When an expression is evaluated
which names a macro, that macro is understood to contain syntax which is
substituted into that expression. That syntax is then evaluated in its place,
which means that it is scanned for occurrences of more macros. This seems to
be more or less exactly what happens with the classic make variables defined
with the simple equal sign.

So the two flavors are simply variable versus macro, and the = operator is
not a variable assignment but in fact a macro definition like #define. The
right hand side is not evaluated, but its syntax is stored into the left hand
side symbol verbatim. When the symbol is later referenced, then that material
is expanded: looks like a macro, walks like a macro, quacks like a macro, ...

When its left operand is a macro, the += operator behaves as a macro append
(appending to a macro is found in some languages, like for instance in the
troff typesetting language).

When its left operand is a variable, the += operator behaves as an append to a
string.

Speaking of troff, it has parallel features: in troff you can define a string
(.ds) and append to a string (.as). You can also define a macro (.de) and
append to a macro (.am). Macros resemble strings, except that invoking a macro
recursively expands (and can have arguments), whereas a string is just
substituted verbatim and that is that. It is very similar to the two flavors
of variable in GNU Make.

Troff also has something similar to $(call): a way of interpolating arguments
into a variable, namely the \*[name arg1 arg2 ...] syntax where name is a
string. This doesn't mean that name is a macro, just that this way of
referencing it treats it as one.




___

Reply to this item at:

  http://savannah.gnu.org/bugs/?43432

___
  Message sent via/by Savannah
  http://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


[bug #27609] Stupid inference rule for yacc files can clobber C sources!

2009-10-13 Thread Kaz Kylheku

Follow-up Comment #6, bug #27609 (project make):

I've thought about this a little bit more. Basically, here is what may be the
real issue: the rule interferes with objects which are already entangle din
other rules.

Be it as it may that it's required by POSIX and let's take it for granted
that we want that rule because people find it useful, existing projects depend
on it, et cetera.

The problem is that if I have a makefile in which the file ``y.tab.c'' is
already involved in an explicit rule.

If the makefile has this rule:

   y.tab.c: foo.y
$(YACC) ...

make should not be interfering with this makefile by launching a ``mv
y.tab.c. xxx'' command!

This problem would mostly go away if make was smart enough to know that
target X appears on the left hand side of a rule, then it must suppress any
hidden rules which use X as a temporary file.

Surely, it's okay not to try to conform to the POSIX rule, when the makefile
explicitly /wants/ to make a target called y.tab.c.

Remmeber, the rule which makes y.tab.c could be making that y.tab.c from any
one of several Yacc files, not necessarily the same Yacc file which the
implicit rule wants to use.

In my case, it was my custom rule which made the y.tab.c, but then the
implicit rule moved it to the target (my C source which got clobbered).
Neither the source file y.tab.c, nor the target, were appropriate to the
implicit rule.

And what about parallelized builds? What if the implicit rule applies more
than one way; will it work correctly under parallel make?  Suppose that a
foo.c is to be implicitly made from a foo.y, and a bar.c is to be impliclitly
made from a bar.y. Both actions will use y.tab.c as an intermediate file.  Are
there some hidden dependencies established which serialize the execution of
the actions?

See, this is why Stallman came up with ``posix me harder''.


___

Reply to this item at:

  http://savannah.gnu.org/bugs/?27609

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #27609] Stupid inference rule for yacc files can clobber C sources!

2009-10-13 Thread Kaz Kylheku

Follow-up Comment #7, bug #27609 (project make):

Also, another consideration is that the prerequisite .y is involved in an
explicit rule.   If an implicit rule matches some file as a prerequisite, but
that file is already used as a prerequisite in some rule, then those rules are
competing. Maybe make should assume that the explicit rule takes precedence.

I'm not so confident about this because there are situations where something
is a prerequisite to more than one rule. (Like the obvious case of a header
file being a dependency for many objects).

Nevertheless, there are situations where prerequisites are typically
understood to be processed by just one rule. You probably would not want to
pass a .y file through yacc twice in two different rules. If such a situation
exists, and one of the rules is generated from an implicit template, but the
other one is explicit, somehow the explicit one should win.

Or some syntax could denote ``weak'' rules. 

You know how there are order-only prerequisites; there could be a similar
extension to denote weak-exclusive prerequisites, and another extension to
denote clobbers.

For the sake of concrete discussion, let's use the characters @ and  for
clobbers and exclusive prerequisites. The rule could then look like:

  %.c:  %.y @ y.tab.c
 $(YACC) ...
 mv ...


So now, if the rule matches some ``foo'' stem, we have a target foo.c, a
exclusive prerequisite foo.y, and a clobber y.tab.c.

The exclusive prerequisite tells make that this rule must be exclusive for
that prerequisite. If two explicit rules are exlusive for the same
prerequisite, then the situation is erroneous: a diagnostic is emitted and the
make fails. If the exclusivity conflict is between an implicit and explicit
rule (like the above case), then the implicit rule is treated as weak: it is
resolved in favor of the explicit rule.

The clobber element y.tab.c informs make that the rule body destroys the file
y.tab.c, which is neither a target nor prerequisite.  Make will suppress this
rule if y.tab.c appears as a target or prerequisite in any other rule
(possibly with some warning diagnostic?). Moreover, if two or more rules both
specify y.tab.c as a clobber, the execution of those rules will be serialized
(in either order, just not parallel).

Note that this allows phony clobber files to be used as mutexes for
serializing rules, which could be handy! Suppose that two rules exist which,
say, do something destructive in the same CVS sandbox (like an update) which
can modify the CVS/Entries and whatnot. They could have a clobber called
``cvs-mutex'', and make would thus not run those rules in parallel. This may
be easier than inserting fake dependencies to enforce an order. I know there
is .NOTPARALLEL, but that's a big hammer.




___

Reply to this item at:

  http://savannah.gnu.org/bugs/?27609

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #27609] Stupid inference rule for yacc files can clobber C sources!

2009-10-05 Thread Kaz Kylheku

URL:
  http://savannah.gnu.org/bugs/?27609

 Summary: Stupid inference rule for yacc files can clobber C
sources!
 Project: make
Submitted by: kkylheku
Submitted on: Mon 05 Oct 2009 12:36:09 PM PDT
Severity: 3 - Normal
  Item Group: Bug
  Status: None
 Privacy: Public
 Assigned to: None
 Open/Closed: Open
 Discussion Lock: Any
   Component Version: 3.80
Operating System: Any
   Fixed Release: None
   Triage Status: None

___

Details:

I have a project in which there is a lex grammar and yacc grammar. Let's call
them foo.l and foo.y.   It's somewhat of a tradition to use the same name for
both. There is no interference because one is translated to a lex.yy.c, and
the other to y.tab.c.

So, silly me, I decided to add a third file, a main driver program, which I
called foo.c, thinking that all three files foo.l, foo.y and foo.c would be
independent.

In my Makefile, I added the dependency, by naming foo.o as a prerequisite of
the main program. But I did not add a rule for how foo.o is obtained; all my
other .o files have implicitly deduced .c prerequisites.

Lo and behold, when I ran make, this happened:

  mv -f y.tab.c foo.c

There goes my foo.c file! Apparently, foo.c is connected to foo.y by
prerequisite inference.

What kind of moron writes implicit rules, to be shipped in the default rule
set of a make program, which guess up .c file names and proceed to clobber
them?

And since when has foo foo.c ever been related to foo.y as a derived object?

If I want my y.tab.c to be called something else, I will write the rule for
it.

Luckily the contents of foo.c came from another file which is under version
control. I lost only two very minor edits.





___

Reply to this item at:

  http://savannah.gnu.org/bugs/?27609

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #18335] Addition of $(math ...) functions

2009-10-05 Thread Kaz Kylheku

Follow-up Comment #4, bug #18335 (project make):

The make program does a lot of work by generating shell script fragments and
running them. Not only are the lines of rule bodies shell scripts, but GNU
makefiles make other uses of shell features. For instance, calling the find
utility to locate targets and such.

Adding math functions to make is a false optimization, and a self-indulgent
hack.

You can easily generate $(( expr )) shell syntax and have the shell evaluate
it.

Look. Makefile to print two plus two:

.PHONY: all

FOUR := $(shell echo $$(( 2 + 2)) )

all:
echo $(FOUR)


And yes, it's clumsy to type $(shell echo $$(( expr )))
instead of just $(expr expr).

That's what GNU make macros are for. With macros, you can get it down to
$(call expr, expr).

If that's too inconvenient, maybe you're stuffing way too much math into the
Makefile and not enough of the normal stuff to make things.

.PHONY: all

define expr
$(shell echo $$(( $1 )) )
endef

X := 10
Y := 30

all:
echo $(call expr, $(X) + $(Y))

$ make
echo 40
40


If you want to optimize make by moving computation out of sub-shells into the
make process, this is a poor place to start, because it's not the common
case.

You idiots want to put a Scheme interpreter into make?

Given that half of the make syntax is really shell syntax, which is farmed
out to a sub-process, it would be a much better idea to combine make with a
shell implementation.

That way, when make processes something like:

  target:
   case $@ in ) *.blah ... complicateed shell script 
 spanning dozens of lines 
 with lots of nested if and while, and for 
   esac

it could be interpreted without forking off a process. This would actually
benefit the reams of makefiles which are already written.

Then $(shell ...) could be entirely built in, and, therefore so would the $((
expr )) syntax. At that point, you could implement a shortcut to access that
syntax, like $(expr expr). It would be icing on the cake.


___

Reply to this item at:

  http://savannah.gnu.org/bugs/?18335

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #27609] Stupid inference rule for yacc files can clobber C sources!

2009-10-05 Thread Kaz Kylheku

Follow-up Comment #2, bug #27609 (project make):

If I have two different yacc files that generate different parsers in the
same directory, then I'm going to be aware of that situation and resolve it.
If I don't resolve it, then they will both clobber y.tab.c, which is my fault.
I'm bitten by my own folly, and not by some hidden rule that destroys source
code.

That the yacc program clobbers y.tab.c is not the result of some secret rule
which only emerges when you've created an important file (not by means of
yacc) and named it y.tab.c! Everyone knows that yacc makes a y.tab.c file. 
Not everyone knows that make will clobber your foo.c, because a foo.y exists.

There are going to be other issues anyway. If I have two parsers that go into
the same link, there will be clashes on all the YY stuff. It's not enough to
just rename the files.

If I don't like the name y.tab.c, I can easily write a rule like this:

 myparser.c: myparser.y
$(YACC) $(YFLAGS) -o $@ $

If I want that to be an implicit rule for general .y - .c conversion, I can
do it like this:

 %.c: %.y
$(YACC) $(YFLAGS) -o $@ $

Now I have a rule which clobbers .c files. I wrote it; it's spelled out in my
Makefile. If that overwrites a non-generated .c file, it serves me right!


___

Reply to this item at:

  http://savannah.gnu.org/bugs/?27609

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #27609] Stupid inference rule for yacc files can clobber C sources!

2009-10-05 Thread Kaz Kylheku

Follow-up Comment #3, bug #27609 (project make):

Re: what can be done about it.

Enough silly venting. How about the question of what can be done about it? I
have an idea. How about a check to see whether the .c file to be clobbered is
actually a yacc-generated file?

If the file already exists, only do the move if, say, the first three lines
of the the file are different from the first three lines of y.tab.c.

Otherwise emit a diagnostic.

If you have GNU bash, or some other shell which supports process
substitution, the logic can be expressed as:

  # Do the rename if $target does not exist, or if it
  # matches source in the first three lines.
  
  if ![ -e $target ] || !diff (head -3 $source) (head -3 $target);
then
mv -- $source $target
  else
echo refusing update $target by replacing it with $source
echo target seems to have contents unrelated to $source
  fi

Of course, it has to be done according to whatever portability guidelines
apply to the ruleset.

The downside would be that the rule refuses to do the move when it should:
there is a false difference in the first three lines on every incremental
rebuild. This might happen if the yacc implementation does something different
in the first three lines (like adding a date stamp). Or (probably very
unlikely) if edits in the actual yacc spec are reflected in an actual change
in the first three lines.

The output of Bison does have a date stamp in the first three lines, but it's
not generated; it's part of the boiler plate. For example:

#ifndef lint
static char const
yyrcsid[] = $FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28 2000/01/17 02:04:06
bde Exp $;

This stamp won't change unless someone checks in the generated parser under
version control which not only does RCS keyword expansion, but recognizes and
expands the custom FreeBSD keyword.

Suppose your CVS does that. So you'd be doing a ``cvs up'', and then a
``make'', and ... oops! The parser.c got refreshed, so did parser.y, and now
GNU make refuses to rename y.tab.c to parser.c, because CVS modified the
$FreeBSD: ... $ text.

You would have to rm parser.c and run make again.


___

Reply to this item at:

  http://savannah.gnu.org/bugs/?27609

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


[bug #27609] Stupid inference rule for yacc files can clobber C sources!

2009-10-05 Thread Kaz Kylheku

Follow-up Comment #4, bug #27609 (project make):

By the way, this is quite bad. The behavior happens even if I have an
explicit rule like this:

  foo.o: foo.c

If there is a foo.y, foo.c is clobbered, even though foo.c exists.

This is so retarded.

The search for the prerequisite of foo.o must stop when foo.c is found.

I can understand that the search, upon not finding foo.c, might go on to try
other suffixes like foo.y.

That is to say, the rule should be about making a foo.o from a foo.y, not
making a foo.c from a foo.y!!!

Yes, sure. Okay. If I have a Makefile like this:

  program: foo.o

and the only file in the directory is foo.y (and no foo.c), then go ahead and
run yacc to make foo.c from foo.y, and compile foo.c to foo.o.

Actually we don't need foo.c in that case. We just need some temporary name.
The rule has to handle the complete job of translating .y to .o:

   $(YACC) $(YACCFLAGS) foo.y
   mv y.tab.c temporary_name
   $(CC) $(CFLAGS) -c temporary_name -o foo.o

Now this actually makes sense. If there is no .c file, why not infer that .y
is the prerequisite for a .o?

Just don't involve a foo.c file in the inference chain.

temporary_name can be based on foo.y somehow (just not in a naive way like
foo.c!)  Even if it was foo.y.tab.c, or foo.y.out, or whatever.

There could even be an implicit rule which, given a foo.o, finds the
prerequisite foo.y.tab.c.

It's less likely that someone would write a file by hand called foo.y.tab.c,
than foo.c.










___

Reply to this item at:

  http://savannah.gnu.org/bugs/?27609

___
  Message sent via/by Savannah
  http://savannah.gnu.org/



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make