unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
@ 2014-01-25 10:21 Tomi Ollila
  2014-02-13  7:10 ` Austin Clements
  0 siblings, 1 reply; 11+ messages in thread
From: Tomi Ollila @ 2014-01-25 10:21 UTC (permalink / raw)
  To: notmuch; +Cc: tomi.ollila

So that the target is newer than its prerequisites.
---
 emacs/Makefile.local | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 42bfbd9..d5d402e 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
 ifeq ($(HAVE_EMACS),1)
 $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
 	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
-		-f batch-make-deps $(emacs_sources) > $@.tmp && \
-		(cmp -s $@.tmp $@ || mv $@.tmp $@)
+		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
 -include $(dir)/.eldeps
 endif
 CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
  2014-01-25 10:21 [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade Tomi Ollila
@ 2014-02-13  7:10 ` Austin Clements
  2014-02-13  7:26   ` Tomi Ollila
  0 siblings, 1 reply; 11+ messages in thread
From: Austin Clements @ 2014-02-13  7:10 UTC (permalink / raw)
  To: Tomi Ollila; +Cc: notmuch

Quoth Tomi Ollila on Jan 25 at 12:21 pm:
> So that the target is newer than its prerequisites.
> ---
>  emacs/Makefile.local | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
> index 42bfbd9..d5d402e 100644
> --- a/emacs/Makefile.local
> +++ b/emacs/Makefile.local
> @@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
>  ifeq ($(HAVE_EMACS),1)
>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
> -		-f batch-make-deps $(emacs_sources) > $@.tmp && \
> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
> +		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
>  -include $(dir)/.eldeps
>  endif
>  CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp

Is this just so the rule doesn't get run again on the next make
invocation (unless, of course, a dependent changed)?

Interestingly, if any of the dependents have changed, but in ways that
don't affect .eldeps, this change will make the build more expensive
because it will trigger a make restart after .eldeps is updated.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
  2014-02-13  7:10 ` Austin Clements
@ 2014-02-13  7:26   ` Tomi Ollila
  2014-02-13  7:49     ` Austin Clements
  0 siblings, 1 reply; 11+ messages in thread
From: Tomi Ollila @ 2014-02-13  7:26 UTC (permalink / raw)
  To: Austin Clements; +Cc: notmuch

On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:

> Quoth Tomi Ollila on Jan 25 at 12:21 pm:
>> So that the target is newer than its prerequisites.
>> ---
>>  emacs/Makefile.local | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>> 
>> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
>> index 42bfbd9..d5d402e 100644
>> --- a/emacs/Makefile.local
>> +++ b/emacs/Makefile.local
>> @@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
>>  ifeq ($(HAVE_EMACS),1)
>>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
>>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
>> -		-f batch-make-deps $(emacs_sources) > $@.tmp && \
>> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
>> +		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
>>  -include $(dir)/.eldeps
>>  endif
>>  CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
>
> Is this just so the rule doesn't get run again on the next make
> invocation (unless, of course, a dependent changed)?

Basically yes. I did multiple builds in rapid succession when developing
something and this thing confused me quite a lot in the beginning...

> Interestingly, if any of the dependents have changed, but in ways that
> don't affect .eldeps, this change will make the build more expensive
> because it will trigger a make restart after .eldeps is updated.

I wondered what was the reason for the recipe you've chosen here, has
it something to do with inodes or something ;) (and were going to ask
an alternative to touch (or even : > $@) the target...

... but now I understand. E.g. change in notmuch-lib.el will cause *all* 
.el files to be re-bytecompiled after this change. 

An alternative to this patch would be adding a message to the rule
which informs user to touch .eldeps to avoid re-doing .eldeps if
that irritates one :D

something like:

(cmp -s $@.tmp $@ && \
     echo "touch $@ to avoid redoing this target" || mv $@.tmp $@)

Thanks, 

Tomi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
  2014-02-13  7:26   ` Tomi Ollila
@ 2014-02-13  7:49     ` Austin Clements
  2014-02-14 19:24       ` Tomi Ollila
  0 siblings, 1 reply; 11+ messages in thread
From: Austin Clements @ 2014-02-13  7:49 UTC (permalink / raw)
  To: Tomi Ollila; +Cc: notmuch

Quoth Tomi Ollila on Feb 13 at  9:26 am:
> On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
> 
> > Quoth Tomi Ollila on Jan 25 at 12:21 pm:
> >> So that the target is newer than its prerequisites.
> >> ---
> >>  emacs/Makefile.local | 3 +--
> >>  1 file changed, 1 insertion(+), 2 deletions(-)
> >> 
> >> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
> >> index 42bfbd9..d5d402e 100644
> >> --- a/emacs/Makefile.local
> >> +++ b/emacs/Makefile.local
> >> @@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
> >>  ifeq ($(HAVE_EMACS),1)
> >>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
> >>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
> >> -		-f batch-make-deps $(emacs_sources) > $@.tmp && \
> >> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
> >> +		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
> >>  -include $(dir)/.eldeps
> >>  endif
> >>  CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
> >
> > Is this just so the rule doesn't get run again on the next make
> > invocation (unless, of course, a dependent changed)?
> 
> Basically yes. I did multiple builds in rapid succession when developing
> something and this thing confused me quite a lot in the beginning...
> 
> > Interestingly, if any of the dependents have changed, but in ways that
> > don't affect .eldeps, this change will make the build more expensive
> > because it will trigger a make restart after .eldeps is updated.
> 
> I wondered what was the reason for the recipe you've chosen here, has
> it something to do with inodes or something ;) (and were going to ask
> an alternative to touch (or even : > $@) the target...
> 
> ... but now I understand. E.g. change in notmuch-lib.el will cause *all* 
> .el files to be re-bytecompiled after this change. 

This is unrelated to the cmp in the recipe.  A change in
notmuch-lib.el *must* cause almost all .el files to be recompiled
because they almost all require it and may use macros from it.  If you
touch, e.g., notmuch-hello.el, you'll see that very little is rebuilt
(with or without this patch).

> An alternative to this patch would be adding a message to the rule
> which informs user to touch .eldeps to avoid re-doing .eldeps if
> that irritates one :D
> 
> something like:
> 
> (cmp -s $@.tmp $@ && \
>      echo "touch $@ to avoid redoing this target" || mv $@.tmp $@)

I think this patch is good as it is; I was just pointing out that the
change also has a performance drawback in some situations.  (Knowing
make, there's probably *some* way to get the best of both worlds and
it's probably really ugly.)

> Thanks, 
> 
> Tomi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
  2014-02-13  7:49     ` Austin Clements
@ 2014-02-14 19:24       ` Tomi Ollila
  2014-02-14 21:58         ` Austin Clements
  0 siblings, 1 reply; 11+ messages in thread
From: Tomi Ollila @ 2014-02-14 19:24 UTC (permalink / raw)
  To: Austin Clements; +Cc: notmuch

On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:

> Quoth Tomi Ollila on Feb 13 at  9:26 am:
>> On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
>> 
>> > Quoth Tomi Ollila on Jan 25 at 12:21 pm:
>> >> So that the target is newer than its prerequisites.
>> >> ---
>> >>  emacs/Makefile.local | 3 +--
>> >>  1 file changed, 1 insertion(+), 2 deletions(-)
>> >> 
>> >> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
>> >> index 42bfbd9..d5d402e 100644
>> >> --- a/emacs/Makefile.local
>> >> +++ b/emacs/Makefile.local
>> >> @@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
>> >>  ifeq ($(HAVE_EMACS),1)
>> >>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
>> >>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
>> >> -		-f batch-make-deps $(emacs_sources) > $@.tmp && \
>> >> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
>> >> +		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
>> >>  -include $(dir)/.eldeps
>> >>  endif
>> >>  CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
>> >
>> > Is this just so the rule doesn't get run again on the next make
>> > invocation (unless, of course, a dependent changed)?
>> 
>> Basically yes. I did multiple builds in rapid succession when developing
>> something and this thing confused me quite a lot in the beginning...
>> 
>> > Interestingly, if any of the dependents have changed, but in ways that
>> > don't affect .eldeps, this change will make the build more expensive
>> > because it will trigger a make restart after .eldeps is updated.
>> 
>> I wondered what was the reason for the recipe you've chosen here, has
>> it something to do with inodes or something ;) (and were going to ask
>> an alternative to touch (or even : > $@) the target...
>> 
>> ... but now I understand. E.g. change in notmuch-lib.el will cause *all* 
>> .el files to be re-bytecompiled after this change. 
>
> This is unrelated to the cmp in the recipe.  A change in
> notmuch-lib.el *must* cause almost all .el files to be recompiled
> because they almost all require it and may use macros from it.  If you
> touch, e.g., notmuch-hello.el, you'll see that very little is rebuilt
> (with or without this patch).
>
>> An alternative to this patch would be adding a message to the rule
>> which informs user to touch .eldeps to avoid re-doing .eldeps if
>> that irritates one :D
>> 
>> something like:
>> 
>> (cmp -s $@.tmp $@ && \
>>      echo "touch $@ to avoid redoing this target" || mv $@.tmp $@)
>
> I think this patch is good as it is; I was just pointing out that the
> change also has a performance drawback in some situations.  (Knowing
> make, there's probably *some* way to get the best of both worlds and
> it's probably really ugly.)

Ah, now I understand, because emacs/Makefile.local includes emacs/.eldeps
when it notices mtime of emacs/.eldeps changes it restarts itself...

... to compare with current behaviour:

$ make
...
$ touch emacs/notmuch.el
$ make
...
$ make
Use "make V=1" to see the verbose compile lines.
EMACS emacs/.eldeps
make: Nothing to be done for `all'.
$ make
Use "make V=1" to see the verbose compile lines.
EMACS emacs/.eldeps
make: Nothing to be done for `all'.
$ make
Use "make V=1" to see the verbose compile lines.
EMACS emacs/.eldeps
make: Nothing to be done for `all'.

It will rerun emacs -L emacs -batch -l make-deps.el -f batch-make-deps ...
over and over again...

I thought I figured out a solution involving .eldeps.stamp file but
that turned out to be no-go... (circular dependency netween .eldeps.stamp
and Makefile.local).

So, with this if one edits emacs/* files and keeps building byte-compiled
versions often, make will both run EMACS emacs/.eldeps and restarting
-- and when moving to edit other files both of the above stops. Without
this change after editing emacs/* files EMACS emacs/.eldeps will be
executed until it is touched or make clean executed (I wonder how make
handles rebuilding emacs/.eldeps while doing make clean ;)


Tomi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
  2014-02-14 19:24       ` Tomi Ollila
@ 2014-02-14 21:58         ` Austin Clements
  2014-02-19 19:54           ` Austin Clements
  0 siblings, 1 reply; 11+ messages in thread
From: Austin Clements @ 2014-02-14 21:58 UTC (permalink / raw)
  To: Tomi Ollila; +Cc: notmuch

Quoth Tomi Ollila on Feb 14 at  9:24 pm:
> On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
> 
> > Quoth Tomi Ollila on Feb 13 at  9:26 am:
> >> On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
> >> 
> >> > Quoth Tomi Ollila on Jan 25 at 12:21 pm:
> >> >> So that the target is newer than its prerequisites.
> >> >> ---
> >> >>  emacs/Makefile.local | 3 +--
> >> >>  1 file changed, 1 insertion(+), 2 deletions(-)
> >> >> 
> >> >> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
> >> >> index 42bfbd9..d5d402e 100644
> >> >> --- a/emacs/Makefile.local
> >> >> +++ b/emacs/Makefile.local
> >> >> @@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
> >> >>  ifeq ($(HAVE_EMACS),1)
> >> >>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
> >> >>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
> >> >> -		-f batch-make-deps $(emacs_sources) > $@.tmp && \
> >> >> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
> >> >> +		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
> >> >>  -include $(dir)/.eldeps
> >> >>  endif
> >> >>  CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
> >> >
> >> > Is this just so the rule doesn't get run again on the next make
> >> > invocation (unless, of course, a dependent changed)?
> >> 
> >> Basically yes. I did multiple builds in rapid succession when developing
> >> something and this thing confused me quite a lot in the beginning...
> >> 
> >> > Interestingly, if any of the dependents have changed, but in ways that
> >> > don't affect .eldeps, this change will make the build more expensive
> >> > because it will trigger a make restart after .eldeps is updated.
> >> 
> >> I wondered what was the reason for the recipe you've chosen here, has
> >> it something to do with inodes or something ;) (and were going to ask
> >> an alternative to touch (or even : > $@) the target...
> >> 
> >> ... but now I understand. E.g. change in notmuch-lib.el will cause *all* 
> >> .el files to be re-bytecompiled after this change. 
> >
> > This is unrelated to the cmp in the recipe.  A change in
> > notmuch-lib.el *must* cause almost all .el files to be recompiled
> > because they almost all require it and may use macros from it.  If you
> > touch, e.g., notmuch-hello.el, you'll see that very little is rebuilt
> > (with or without this patch).
> >
> >> An alternative to this patch would be adding a message to the rule
> >> which informs user to touch .eldeps to avoid re-doing .eldeps if
> >> that irritates one :D
> >> 
> >> something like:
> >> 
> >> (cmp -s $@.tmp $@ && \
> >>      echo "touch $@ to avoid redoing this target" || mv $@.tmp $@)
> >
> > I think this patch is good as it is; I was just pointing out that the
> > change also has a performance drawback in some situations.  (Knowing
> > make, there's probably *some* way to get the best of both worlds and
> > it's probably really ugly.)
> 
> Ah, now I understand, because emacs/Makefile.local includes emacs/.eldeps
> when it notices mtime of emacs/.eldeps changes it restarts itself...
> 
> ... to compare with current behaviour:
> 
> $ make
> ...
> $ touch emacs/notmuch.el
> $ make
> ...
> $ make
> Use "make V=1" to see the verbose compile lines.
> EMACS emacs/.eldeps
> make: Nothing to be done for `all'.
> $ make
> Use "make V=1" to see the verbose compile lines.
> EMACS emacs/.eldeps
> make: Nothing to be done for `all'.
> $ make
> Use "make V=1" to see the verbose compile lines.
> EMACS emacs/.eldeps
> make: Nothing to be done for `all'.
> 
> It will rerun emacs -L emacs -batch -l make-deps.el -f batch-make-deps ...
> over and over again...
> 
> I thought I figured out a solution involving .eldeps.stamp file but
> that turned out to be no-go... (circular dependency netween .eldeps.stamp
> and Makefile.local).
> 
> So, with this if one edits emacs/* files and keeps building byte-compiled
> versions often, make will both run EMACS emacs/.eldeps and restarting
> -- and when moving to edit other files both of the above stops. Without
> this change after editing emacs/* files EMACS emacs/.eldeps will be
> executed until it is touched or make clean executed (I wonder how make
> handles rebuilding emacs/.eldeps while doing make clean ;)
> 
> 
> Tomi

Here's a way that works, but it's more complicated than your patch and
doesn't seem to perform any better:

diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 42bfbd9..8a1f1c2 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -29,14 +29,28 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
 # the byte compiler may load an old .elc file when processing a
 # "require" or we may fail to rebuild a .elc that depended on a macro
 # from an updated file.
+#
+# We do this in two rules.  .eldeps is the "real" dependencies file
+# and will be rebuilt if and only if a .el source file changes.  We
+# could include this directly, but then whenever a .el file changed
+# (and .eldeps's mtime changed), make would restart immediately after
+# the include below.  To avoid this, we create a second file,
+# .eldeps.x, that we only update when its *contents* differ from
+# .eldeps.  .eldeps will often have an mtime older than .eldeps.x (any
+# .el file change that does not change dependencies will cause this),
+# so the .eldeps.x rule will often run, but it executes quickly and
+# quietly and will not trigger a make restart unless the dependencies
+# actually change.
 ifeq ($(HAVE_EMACS),1)
 $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
 	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
 		-f batch-make-deps $(emacs_sources) > $@.tmp && \
-		(cmp -s $@.tmp $@ || mv $@.tmp $@)
--include $(dir)/.eldeps
+		mv $@.tmp $@
+$(dir)/.eldeps.x: $(dir)/.eldeps
+	@cmp -s $^ $@ || cp $^ $@
+-include $(dir)/.eldeps.x
 endif
-CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
+CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp $(dir)/.eldeps.x
 
 ifeq ($(HAVE_EMACS),1)
 %.elc: %.el $(global_deps)

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
  2014-02-14 21:58         ` Austin Clements
@ 2014-02-19 19:54           ` Austin Clements
  2014-02-19 20:47             ` Tomi Ollila
  0 siblings, 1 reply; 11+ messages in thread
From: Austin Clements @ 2014-02-19 19:54 UTC (permalink / raw)
  To: Tomi Ollila; +Cc: notmuch

Quoth myself on Feb 14 at  4:58 pm:
> Quoth Tomi Ollila on Feb 14 at  9:24 pm:
> > On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
> > 
> > > Quoth Tomi Ollila on Feb 13 at  9:26 am:
> > >> On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
> > >> 
> > >> > Quoth Tomi Ollila on Jan 25 at 12:21 pm:
> > >> >> So that the target is newer than its prerequisites.
> > >> >> ---
> > >> >>  emacs/Makefile.local | 3 +--
> > >> >>  1 file changed, 1 insertion(+), 2 deletions(-)
> > >> >> 
> > >> >> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
> > >> >> index 42bfbd9..d5d402e 100644
> > >> >> --- a/emacs/Makefile.local
> > >> >> +++ b/emacs/Makefile.local
> > >> >> @@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
> > >> >>  ifeq ($(HAVE_EMACS),1)
> > >> >>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
> > >> >>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
> > >> >> -		-f batch-make-deps $(emacs_sources) > $@.tmp && \
> > >> >> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
> > >> >> +		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
> > >> >>  -include $(dir)/.eldeps
> > >> >>  endif
> > >> >>  CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
> > >> >
> > >> > Is this just so the rule doesn't get run again on the next make
> > >> > invocation (unless, of course, a dependent changed)?
> > >> 
> > >> Basically yes. I did multiple builds in rapid succession when developing
> > >> something and this thing confused me quite a lot in the beginning...
> > >> 
> > >> > Interestingly, if any of the dependents have changed, but in ways that
> > >> > don't affect .eldeps, this change will make the build more expensive
> > >> > because it will trigger a make restart after .eldeps is updated.
> > >> 
> > >> I wondered what was the reason for the recipe you've chosen here, has
> > >> it something to do with inodes or something ;) (and were going to ask
> > >> an alternative to touch (or even : > $@) the target...
> > >> 
> > >> ... but now I understand. E.g. change in notmuch-lib.el will cause *all* 
> > >> .el files to be re-bytecompiled after this change. 
> > >
> > > This is unrelated to the cmp in the recipe.  A change in
> > > notmuch-lib.el *must* cause almost all .el files to be recompiled
> > > because they almost all require it and may use macros from it.  If you
> > > touch, e.g., notmuch-hello.el, you'll see that very little is rebuilt
> > > (with or without this patch).
> > >
> > >> An alternative to this patch would be adding a message to the rule
> > >> which informs user to touch .eldeps to avoid re-doing .eldeps if
> > >> that irritates one :D
> > >> 
> > >> something like:
> > >> 
> > >> (cmp -s $@.tmp $@ && \
> > >>      echo "touch $@ to avoid redoing this target" || mv $@.tmp $@)
> > >
> > > I think this patch is good as it is; I was just pointing out that the
> > > change also has a performance drawback in some situations.  (Knowing
> > > make, there's probably *some* way to get the best of both worlds and
> > > it's probably really ugly.)
> > 
> > Ah, now I understand, because emacs/Makefile.local includes emacs/.eldeps
> > when it notices mtime of emacs/.eldeps changes it restarts itself...
> > 
> > ... to compare with current behaviour:
> > 
> > $ make
> > ...
> > $ touch emacs/notmuch.el
> > $ make
> > ...
> > $ make
> > Use "make V=1" to see the verbose compile lines.
> > EMACS emacs/.eldeps
> > make: Nothing to be done for `all'.
> > $ make
> > Use "make V=1" to see the verbose compile lines.
> > EMACS emacs/.eldeps
> > make: Nothing to be done for `all'.
> > $ make
> > Use "make V=1" to see the verbose compile lines.
> > EMACS emacs/.eldeps
> > make: Nothing to be done for `all'.
> > 
> > It will rerun emacs -L emacs -batch -l make-deps.el -f batch-make-deps ...
> > over and over again...
> > 
> > I thought I figured out a solution involving .eldeps.stamp file but
> > that turned out to be no-go... (circular dependency netween .eldeps.stamp
> > and Makefile.local).
> > 
> > So, with this if one edits emacs/* files and keeps building byte-compiled
> > versions often, make will both run EMACS emacs/.eldeps and restarting
> > -- and when moving to edit other files both of the above stops. Without
> > this change after editing emacs/* files EMACS emacs/.eldeps will be
> > executed until it is touched or make clean executed (I wonder how make
> > handles rebuilding emacs/.eldeps while doing make clean ;)
> > 
> > 
> > Tomi
> 
> Here's a way that works, but it's more complicated than your patch and
> doesn't seem to perform any better:
> 
> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
> index 42bfbd9..8a1f1c2 100644
> --- a/emacs/Makefile.local
> +++ b/emacs/Makefile.local
> @@ -29,14 +29,28 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
>  # the byte compiler may load an old .elc file when processing a
>  # "require" or we may fail to rebuild a .elc that depended on a macro
>  # from an updated file.
> +#
> +# We do this in two rules.  .eldeps is the "real" dependencies file
> +# and will be rebuilt if and only if a .el source file changes.  We
> +# could include this directly, but then whenever a .el file changed
> +# (and .eldeps's mtime changed), make would restart immediately after
> +# the include below.  To avoid this, we create a second file,
> +# .eldeps.x, that we only update when its *contents* differ from
> +# .eldeps.  .eldeps will often have an mtime older than .eldeps.x (any
> +# .el file change that does not change dependencies will cause this),
> +# so the .eldeps.x rule will often run, but it executes quickly and
> +# quietly and will not trigger a make restart unless the dependencies
> +# actually change.

Here's a version of this comment that gets to the point directly:

# We could include .eldeps directly, but that would cause a make
# restart whenever any .el file was modified, even if dependencies
# didn't change, because the mtime of .eldeps will change.  Instead,
# we include a second file, .eldeps.x, which we ensure always has the
# same content as .eldeps, but its mtime only changes when dependency
# information changes, in which case a make restart is necessary
# anyway.

>  ifeq ($(HAVE_EMACS),1)
>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
>  		-f batch-make-deps $(emacs_sources) > $@.tmp && \
> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
> --include $(dir)/.eldeps
> +		mv $@.tmp $@
> +$(dir)/.eldeps.x: $(dir)/.eldeps
> +	@cmp -s $^ $@ || cp $^ $@
> +-include $(dir)/.eldeps.x
>  endif
> -CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
> +CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp $(dir)/.eldeps.x
>  
>  ifeq ($(HAVE_EMACS),1)
>  %.elc: %.el $(global_deps)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade
  2014-02-19 19:54           ` Austin Clements
@ 2014-02-19 20:47             ` Tomi Ollila
  2014-02-20  4:24               ` [PATCH] emacs: Avoid rebuilding .eldeps even when there's nothing to do Austin Clements
  0 siblings, 1 reply; 11+ messages in thread
From: Tomi Ollila @ 2014-02-19 20:47 UTC (permalink / raw)
  To: Austin Clements; +Cc: notmuch

On Wed, Feb 19 2014, Austin Clements <amdragon@MIT.EDU> wrote:

> Quoth myself on Feb 14 at  4:58 pm:
>> Quoth Tomi Ollila on Feb 14 at  9:24 pm:
>> > On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
>> > 
>> > > Quoth Tomi Ollila on Feb 13 at  9:26 am:
>> > >> On Thu, Feb 13 2014, Austin Clements <amdragon@MIT.EDU> wrote:
>> > >> 
>> > >> > Quoth Tomi Ollila on Jan 25 at 12:21 pm:
>> > >> >> So that the target is newer than its prerequisites.
>> > >> >> ---
>> > >> >>  emacs/Makefile.local | 3 +--
>> > >> >>  1 file changed, 1 insertion(+), 2 deletions(-)
>> > >> >> 
>> > >> >> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
>> > >> >> index 42bfbd9..d5d402e 100644
>> > >> >> --- a/emacs/Makefile.local
>> > >> >> +++ b/emacs/Makefile.local
>> > >> >> @@ -32,8 +32,7 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
>> > >> >>  ifeq ($(HAVE_EMACS),1)
>> > >> >>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
>> > >> >>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
>> > >> >> -		-f batch-make-deps $(emacs_sources) > $@.tmp && \
>> > >> >> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
>> > >> >> +		-f batch-make-deps $(emacs_sources) > $@.tmp && mv $@.tmp $@
>> > >> >>  -include $(dir)/.eldeps
>> > >> >>  endif
>> > >> >>  CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
>> > >> >
>> > >> > Is this just so the rule doesn't get run again on the next make
>> > >> > invocation (unless, of course, a dependent changed)?
>> > >> 
>> > >> Basically yes. I did multiple builds in rapid succession when developing
>> > >> something and this thing confused me quite a lot in the beginning...
>> > >> 
>> > >> > Interestingly, if any of the dependents have changed, but in ways that
>> > >> > don't affect .eldeps, this change will make the build more expensive
>> > >> > because it will trigger a make restart after .eldeps is updated.
>> > >> 
>> > >> I wondered what was the reason for the recipe you've chosen here, has
>> > >> it something to do with inodes or something ;) (and were going to ask
>> > >> an alternative to touch (or even : > $@) the target...
>> > >> 
>> > >> ... but now I understand. E.g. change in notmuch-lib.el will cause *all* 
>> > >> .el files to be re-bytecompiled after this change. 
>> > >
>> > > This is unrelated to the cmp in the recipe.  A change in
>> > > notmuch-lib.el *must* cause almost all .el files to be recompiled
>> > > because they almost all require it and may use macros from it.  If you
>> > > touch, e.g., notmuch-hello.el, you'll see that very little is rebuilt
>> > > (with or without this patch).
>> > >
>> > >> An alternative to this patch would be adding a message to the rule
>> > >> which informs user to touch .eldeps to avoid re-doing .eldeps if
>> > >> that irritates one :D
>> > >> 
>> > >> something like:
>> > >> 
>> > >> (cmp -s $@.tmp $@ && \
>> > >>      echo "touch $@ to avoid redoing this target" || mv $@.tmp $@)
>> > >
>> > > I think this patch is good as it is; I was just pointing out that the
>> > > change also has a performance drawback in some situations.  (Knowing
>> > > make, there's probably *some* way to get the best of both worlds and
>> > > it's probably really ugly.)
>> > 
>> > Ah, now I understand, because emacs/Makefile.local includes emacs/.eldeps
>> > when it notices mtime of emacs/.eldeps changes it restarts itself...
>> > 
>> > ... to compare with current behaviour:
>> > 
>> > $ make
>> > ...
>> > $ touch emacs/notmuch.el
>> > $ make
>> > ...
>> > $ make
>> > Use "make V=1" to see the verbose compile lines.
>> > EMACS emacs/.eldeps
>> > make: Nothing to be done for `all'.
>> > $ make
>> > Use "make V=1" to see the verbose compile lines.
>> > EMACS emacs/.eldeps
>> > make: Nothing to be done for `all'.
>> > $ make
>> > Use "make V=1" to see the verbose compile lines.
>> > EMACS emacs/.eldeps
>> > make: Nothing to be done for `all'.
>> > 
>> > It will rerun emacs -L emacs -batch -l make-deps.el -f batch-make-deps ...
>> > over and over again...
>> > 
>> > I thought I figured out a solution involving .eldeps.stamp file but
>> > that turned out to be no-go... (circular dependency netween .eldeps.stamp
>> > and Makefile.local).
>> > 
>> > So, with this if one edits emacs/* files and keeps building byte-compiled
>> > versions often, make will both run EMACS emacs/.eldeps and restarting
>> > -- and when moving to edit other files both of the above stops. Without
>> > this change after editing emacs/* files EMACS emacs/.eldeps will be
>> > executed until it is touched or make clean executed (I wonder how make
>> > handles rebuilding emacs/.eldeps while doing make clean ;)
>> > 
>> > 
>> > Tomi
>> 
>> Here's a way that works, but it's more complicated than your patch and
>> doesn't seem to perform any better:
>> 
>> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
>> index 42bfbd9..8a1f1c2 100644
>> --- a/emacs/Makefile.local
>> +++ b/emacs/Makefile.local
>> @@ -29,14 +29,28 @@ emacs_bytecode = $(emacs_sources:.el=.elc)
>>  # the byte compiler may load an old .elc file when processing a
>>  # "require" or we may fail to rebuild a .elc that depended on a macro
>>  # from an updated file.
>> +#
>> +# We do this in two rules.  .eldeps is the "real" dependencies file
>> +# and will be rebuilt if and only if a .el source file changes.  We
>> +# could include this directly, but then whenever a .el file changed
>> +# (and .eldeps's mtime changed), make would restart immediately after
>> +# the include below.  To avoid this, we create a second file,
>> +# .eldeps.x, that we only update when its *contents* differ from
>> +# .eldeps.  .eldeps will often have an mtime older than .eldeps.x (any
>> +# .el file change that does not change dependencies will cause this),
>> +# so the .eldeps.x rule will often run, but it executes quickly and
>> +# quietly and will not trigger a make restart unless the dependencies
>> +# actually change.
>
> Here's a version of this comment that gets to the point directly:
>
> # We could include .eldeps directly, but that would cause a make
> # restart whenever any .el file was modified, even if dependencies
> # didn't change, because the mtime of .eldeps will change.  Instead,
> # we include a second file, .eldeps.x, which we ensure always has the
> # same content as .eldeps, but its mtime only changes when dependency
> # information changes, in which case a make restart is necessary
> # anyway.

I think this behaviour is tolerable: instead of verbosely re-run emacs to
re-create .eldeps every time just to see the new .eldeps is not going to be
used we just silently re-run only lightweight cmp.

Tomi

>
>>  ifeq ($(HAVE_EMACS),1)
>>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
>>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
>>  		-f batch-make-deps $(emacs_sources) > $@.tmp && \
>> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
>> --include $(dir)/.eldeps
>> +		mv $@.tmp $@
>> +$(dir)/.eldeps.x: $(dir)/.eldeps
>> +	@cmp -s $^ $@ || cp $^ $@
>> +-include $(dir)/.eldeps.x
>>  endif
>> -CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
>> +CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp $(dir)/.eldeps.x
>>  
>>  ifeq ($(HAVE_EMACS),1)
>>  %.elc: %.el $(global_deps)
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] emacs: Avoid rebuilding .eldeps even when there's nothing to do
  2014-02-19 20:47             ` Tomi Ollila
@ 2014-02-20  4:24               ` Austin Clements
  2014-02-20 17:00                 ` Tomi Ollila
  2014-02-22  1:21                 ` David Bremner
  0 siblings, 2 replies; 11+ messages in thread
From: Austin Clements @ 2014-02-20  4:24 UTC (permalink / raw)
  To: notmuch; +Cc: tomi.ollila

Previously, we updated .eldeps only if the file contents actually
needed to change.  This was done to avoid unnecessary make restarts
(if the .eldeps rule changes the mtime of .eldeps, make has to restart
to collect the new dependencies).  However, this meant that, after a
modification to any .el file that did not change dependencies, .eldeps
would always be out of date, so every make invocation would run the
.eldeps rule, which is both expensive because it starts up Emacs and
noisy.  This was true even when there was nothing to do.  E.g.,

$ make clean && make
...
$ touch emacs/notmuch-lib.el && make
...
$ make
Use "make V=1" to see the verbose compile lines.
EMACS emacs/.eldeps
make: Nothing to be done for `all'.
$ make
Use "make V=1" to see the verbose compile lines.
EMACS emacs/.eldeps
make: Nothing to be done for `all'.

Fix this by replacing .eldeps with two files with identical content.
One tracks the mtime of the dependency information and triggers the
Emacs call to rebuild dependencies only when it may be necessary.  The
other tracks the content only; this rule over-triggers in the same way
the old rule did, but this rule is cheap and quiet.
---
 emacs/Makefile.local | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 42bfbd9..6a39b32 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -33,10 +33,19 @@ ifeq ($(HAVE_EMACS),1)
 $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
 	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
 		-f batch-make-deps $(emacs_sources) > $@.tmp && \
-		(cmp -s $@.tmp $@ || mv $@.tmp $@)
--include $(dir)/.eldeps
+		mv $@.tmp $@
+# We could include .eldeps directly, but that would cause a make
+# restart whenever any .el file was modified, even if dependencies
+# didn't change, because the mtime of .eldeps will change.  Instead,
+# we include a second file, .eldeps.x, which we ensure always has the
+# same content as .eldeps, but its mtime only changes when dependency
+# information changes, in which case a make restart is necessary
+# anyway.
+$(dir)/.eldeps.x: $(dir)/.eldeps
+	@cmp -s $^ $@ || cp $^ $@
+-include $(dir)/.eldeps.x
 endif
-CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
+CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp $(dir)/.eldeps.x
 
 ifeq ($(HAVE_EMACS),1)
 %.elc: %.el $(global_deps)
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] emacs: Avoid rebuilding .eldeps even when there's nothing to do
  2014-02-20  4:24               ` [PATCH] emacs: Avoid rebuilding .eldeps even when there's nothing to do Austin Clements
@ 2014-02-20 17:00                 ` Tomi Ollila
  2014-02-22  1:21                 ` David Bremner
  1 sibling, 0 replies; 11+ messages in thread
From: Tomi Ollila @ 2014-02-20 17:00 UTC (permalink / raw)
  To: Austin Clements, notmuch

On Thu, Feb 20 2014, Austin Clements <amdragon@MIT.EDU> wrote:

> Previously, we updated .eldeps only if the file contents actually
> needed to change.  This was done to avoid unnecessary make restarts
> (if the .eldeps rule changes the mtime of .eldeps, make has to restart
> to collect the new dependencies).  However, this meant that, after a
> modification to any .el file that did not change dependencies, .eldeps
> would always be out of date, so every make invocation would run the
> .eldeps rule, which is both expensive because it starts up Emacs and
> noisy.  This was true even when there was nothing to do.  E.g.,
>
> $ make clean && make
> ...
> $ touch emacs/notmuch-lib.el && make
> ...
> $ make
> Use "make V=1" to see the verbose compile lines.
> EMACS emacs/.eldeps
> make: Nothing to be done for `all'.
> $ make
> Use "make V=1" to see the verbose compile lines.
> EMACS emacs/.eldeps
> make: Nothing to be done for `all'.
>
> Fix this by replacing .eldeps with two files with identical content.
> One tracks the mtime of the dependency information and triggers the
> Emacs call to rebuild dependencies only when it may be necessary.  The
> other tracks the content only; this rule over-triggers in the same way
> the old rule did, but this rule is cheap and quiet.
> ---

LGTM. Works as expected.

Tomi

>  emacs/Makefile.local | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
> index 42bfbd9..6a39b32 100644
> --- a/emacs/Makefile.local
> +++ b/emacs/Makefile.local
> @@ -33,10 +33,19 @@ ifeq ($(HAVE_EMACS),1)
>  $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)
>  	$(call quiet,EMACS) --directory emacs -batch -l make-deps.el \
>  		-f batch-make-deps $(emacs_sources) > $@.tmp && \
> -		(cmp -s $@.tmp $@ || mv $@.tmp $@)
> --include $(dir)/.eldeps
> +		mv $@.tmp $@
> +# We could include .eldeps directly, but that would cause a make
> +# restart whenever any .el file was modified, even if dependencies
> +# didn't change, because the mtime of .eldeps will change.  Instead,
> +# we include a second file, .eldeps.x, which we ensure always has the
> +# same content as .eldeps, but its mtime only changes when dependency
> +# information changes, in which case a make restart is necessary
> +# anyway.
> +$(dir)/.eldeps.x: $(dir)/.eldeps
> +	@cmp -s $^ $@ || cp $^ $@
> +-include $(dir)/.eldeps.x
>  endif
> -CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp
> +CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp $(dir)/.eldeps.x
>  
>  ifeq ($(HAVE_EMACS),1)
>  %.elc: %.el $(global_deps)
> -- 
> 1.8.4.rc3
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] emacs: Avoid rebuilding .eldeps even when there's nothing to do
  2014-02-20  4:24               ` [PATCH] emacs: Avoid rebuilding .eldeps even when there's nothing to do Austin Clements
  2014-02-20 17:00                 ` Tomi Ollila
@ 2014-02-22  1:21                 ` David Bremner
  1 sibling, 0 replies; 11+ messages in thread
From: David Bremner @ 2014-02-22  1:21 UTC (permalink / raw)
  To: Austin Clements, notmuch; +Cc: tomi.ollila

Austin Clements <amdragon@MIT.EDU> writes:

> Previously, we updated .eldeps only if the file contents actually
> needed to change.  This was done to avoid unnecessary make restarts
> (if the .eldeps rule changes the mtime of .eldeps, make has to restart
> to collect the new dependencies).  However, this meant that, after a
> modification to any .el file that did not change dependencies, .eldeps
> would always be out of date, so every make invocation would run the
> .eldeps rule, which is both expensive because it starts up Emacs and
> noisy.  This was true even when there was nothing to do.  E.g.,
>

pushed.

d

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-02-22  1:21 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-25 10:21 [PATCH 1/1] emacs: always write emacs/.eldeps when the target is remade Tomi Ollila
2014-02-13  7:10 ` Austin Clements
2014-02-13  7:26   ` Tomi Ollila
2014-02-13  7:49     ` Austin Clements
2014-02-14 19:24       ` Tomi Ollila
2014-02-14 21:58         ` Austin Clements
2014-02-19 19:54           ` Austin Clements
2014-02-19 20:47             ` Tomi Ollila
2014-02-20  4:24               ` [PATCH] emacs: Avoid rebuilding .eldeps even when there's nothing to do Austin Clements
2014-02-20 17:00                 ` Tomi Ollila
2014-02-22  1:21                 ` David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).