Re: feature request - order only deps

2013-02-04 Thread Matěj Týč

On 4.2.2013 01:09, Sebastian Pipping wrote:
 On 04.02.2013 00:13, Matěj Týč wrote:
 On Ne, 2013-02-03 at 23:40 +0100, Sebastian Pipping wrote:
 To my understanding, it would have to be optional and off by default to
 not break other cases that are currently supported.  Think of something like

 ...
 ...

 Dirs: dir1 dir2

 dir%:
  mkdir $@

 dir2/foo: dir1/bar
  touch $@

 dir1/bar: | Dirs
  touch $@

 .PHONY: Dirs

 If you make 'dir1/bar', then remove 'dir2' and decide to make
 'dir2/foo', you appreciate that 'dir2' is remade because 'dirs' is an
 order-only dep of 'bar' and it is remade as soon as make realizes that
 'dirs' is not complete because 'dir2' is missing.
 So although this can be considered as the Makefile bug, cases like this
 can exist, so the proposed change would break this behavior (I propose
 that the 'Dirs' order-only dep is ignored because dir1/bar is all right
 and dir2/foo says that it depends only on dir1/bar)
 If I am not mistaken, you are saying that:

If

 1. an order-only dependency is missing and

 2. the target is not re-built (i.e. neither missing or older than
normal prerequisites

the order-only dependency should not be built.

Thank you for your reply,and yes, that's it indeed.


 I'm starting to see why you want support for that.

Thank you, this sounds good.

 I think that this is a nice idea, since 'make' doesn't play well with
 filters that can process batches of files at once, the server process
 is a good way to reduce overhead of processing those files one by one
 and you may end up needing a cache quite soon :-)

 Actually I might be wrong, but I think that if I have a program 'filter'
 capable of processing in01 in02 in03 ... files to out01 out02 out03 ...
 etc., it is not possible to tell this to 'make', so if out05 and out07
 are needed at some point, 'make' would call 'filter in05 in07 --some
 --flags'. Is that right? Because if this was somehow possible, I would
 not need that process at all.
 I do not see the relation to the rest of this thread yet, but what you
 describe sounds like classic pattern rules:

The only relation is that the fact that I wouldn't need a server process 
neither cache if 'n in' - 'n out' filter programs were supported like I 
explain in the comment below.

out%: in%
   cp $ $@

 Here, cp would be the filter.  Are you referring to something else?

The problem is that if I have like 50 'in' files and I want 50 'out' 
files, the 'cp' program would be launched 50 times, whereas the filter 
I have in mind is able to consume like 50 files and output 50 files as a 
result at once.
I would say that this could be formulated as rule that has a dynamic 
number of targets depending on the number of dependencies (inputs).

 Best,



 Sebastian

Best wishes,
Matej



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


Re: feature request - order only deps

2013-02-03 Thread Matěj Týč
On Ne, 2013-02-03 at 00:45 +0100, Sebastian Pipping wrote:
 On 02.02.2013 18:38, Matěj Týč wrote:
  How about something like this?
 
bar_deps = foo1 foo2
 
bar: $(bar_deps)
 
$(bar_deps):
 $(MAKE) cache-foo
 touch $@
 
%:
 touch $@
  
  I have also thought of that, but this can work well reliably only in the
  case if there is only one make job. If I specify -j4, it may happen that
  all jobs will attempt to load the same cache simultaneously, which I
  have to avoid :-(
 
 If that happens how about replacing
 
   $(MAKE) cache-foo
 
 by something like
 
   mkdir .lock 2/dev/null || exit 0 ; \
   $(MAKE) cache-foo ; \
   ret=$$?; \
   rmdir .lock  exit $${ret}
 
 The idea is:
 
  - mkdir can only succeed once
 
  - if $(MAKE) cache-foo fails
 
 1. the whole should return non-zero
 
 2. .lock is not left laying around

Thank you,
but just by looking at it, I think that if .lock exists, 0 is returned
and while one make job is busy loading the cache, the others act like
the cache was loaded.
Writing the makefile and trying it confirms this assumption, so I guess
that it has to behave like that.
I am beginning to think that the most elegant (from the user's point of
view) would be (probably optional) ignore of order-only dependencies if
the target exists and is more up-to-date than its ordinary dependencies.
How difficult could be writing a patch that would enable this?

Matej


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


Re: feature request - order only deps

2013-02-03 Thread Sebastian Pipping
On 03.02.2013 23:20, Matěj Týč wrote:
 If that happens how about replacing

   $(MAKE) cache-foo

 by something like

   mkdir .lock 2/dev/null || exit 0 ; \
   $(MAKE) cache-foo ; \
   ret=$$?; \
   rmdir .lock  exit $${ret}

 The idea is:

  - mkdir can only succeed once

  - if $(MAKE) cache-foo fails

 1. the whole should return non-zero

 2. .lock is not left laying around
 
 Thank you,
 but just by looking at it, I think that if .lock exists, 0 is returned
 and while one make job is busy loading the cache, the others act like
 the cache was loaded.
 Writing the makefile and trying it confirms this assumption, so I guess
 that it has to behave like that.

I see, so actually waiting is needed.

Have you tried modifying the call to do that?  I'd bet it's possible :-)


 I am beginning to think that the most elegant (from the user's point of
 view) would be (probably optional) ignore of order-only dependencies if
 the target exists and is more up-to-date than its ordinary dependencies.

To my understanding, it would have to be optional and off by default to
not break other cases that are currently supported.  Think of something like

  tmp:
mkdir tmp

  tmp/foo.pdf: foo.tex | tmp
pdflatex -output-directory tmp $

In this scenario, the tmp directory needs to be created if missing.


 How difficult could be writing a patch that would enable this?

No idea without having a closer look.  To be honest, I am not yet
convinced that this feature would be of real use to other users or that
a new a global switch would be the best way to address this issue, if
really wanted.

Best,



Sebastian


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


Re: feature request - order only deps

2013-02-03 Thread Matěj Týč
On Ne, 2013-02-03 at 23:40 +0100, Sebastian Pipping wrote:
 On 03.02.2013 23:20, Matěj Týč wrote:
  If that happens how about replacing
 
$(MAKE) cache-foo
 
  by something like
 
mkdir .lock 2/dev/null || exit 0 ; \
$(MAKE) cache-foo ; \
ret=$$?; \
rmdir .lock  exit $${ret}
 
  The idea is:
 
   - mkdir can only succeed once
 
   - if $(MAKE) cache-foo fails
 
  1. the whole should return non-zero
 
  2. .lock is not left laying around
  
  Thank you,
  but just by looking at it, I think that if .lock exists, 0 is returned
  and while one make job is busy loading the cache, the others act like
  the cache was loaded.
  Writing the makefile and trying it confirms this assumption, so I guess
  that it has to behave like that.
 
 I see, so actually waiting is needed.
 
 Have you tried modifying the call to do that?  I'd bet it's possible :-)

Well, an infinite loop checking every sec. whether the .lock directory
still exists might do the trick. However, additional check whether the
cache load was succesful would be needed and actually the directories
would have to have different names for diferent cache that could get
loaded.

  I am beginning to think that the most elegant (from the user's point of
  view) would be (probably optional) ignore of order-only dependencies if
  the target exists and is more up-to-date than its ordinary dependencies.
 
 To my understanding, it would have to be optional and off by default to
 not break other cases that are currently supported.  Think of something like
 
   tmp:
   mkdir tmp
 
   tmp/foo.pdf: foo.tex | tmp
   pdflatex -output-directory tmp $
 
 In this scenario, the tmp directory needs to be created if missing.

Actually this would not be a problem, I would need to ignore the 'tmp'
target iff 'tmp/foo.pdf' existed and was more up-to-date than 'foo.tex'.
So in cases like that the behavior even wouldn't change at all.
I think that the problem could arise in cases like this:

Dirs: dir1 dir2

dir%:
mkdir $@

dir2/foo: dir1/bar
touch $@

dir1/bar: | Dirs
touch $@

.PHONY: Dirs

If you make 'dir1/bar', then remove 'dir2' and decide to make
'dir2/foo', you appreciate that 'dir2' is remade because 'dirs' is an
order-only dep of 'bar' and it is remade as soon as make realizes that
'dirs' is not complete because 'dir2' is missing.
So although this can be considered as the Makefile bug, cases like this
can exist, so the proposed change would break this behavior (I propose
that the 'Dirs' order-only dep is ignored because dir1/bar is all right
and dir2/foo says that it depends only on dir1/bar)

  How difficult could be writing a patch that would enable this?
 
 No idea without having a closer look.  To be honest, I am not yet
 convinced that this feature would be of real use to other users or that
 a new a global switch would be the best way to address this issue, if
 really wanted.

I think that this is a nice idea, since 'make' doesn't play well with
filters that can process batches of files at once, the server process
is a good way to reduce overhead of processing those files one by one
and you may end up needing a cache quite soon :-)

Actually I might be wrong, but I think that if I have a program 'filter'
capable of processing in01 in02 in03 ... files to out01 out02 out03 ...
etc., it is not possible to tell this to 'make', so if out05 and out07
are needed at some point, 'make' would call 'filter in05 in07 --some
--flags'. Is that right? Because if this was somehow possible, I would
not need that process at all.

Matej


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


Re: feature request - order only deps

2013-02-03 Thread Sebastian Pipping
On 04.02.2013 00:13, Matěj Týč wrote:
 On Ne, 2013-02-03 at 23:40 +0100, Sebastian Pipping wrote:
 To my understanding, it would have to be optional and off by default to
 not break other cases that are currently supported.  Think of something like

   tmp:
  mkdir tmp

   tmp/foo.pdf: foo.tex | tmp
  pdflatex -output-directory tmp $

 In this scenario, the tmp directory needs to be created if missing.
 
 Actually this would not be a problem, I would need to ignore the 'tmp'
 target iff 'tmp/foo.pdf' existed and was more up-to-date than 'foo.tex'.
 So in cases like that the behavior even wouldn't change at all.
 I think that the problem could arise in cases like this:
 
 Dirs: dir1 dir2
 
 dir%:
   mkdir $@
 
 dir2/foo: dir1/bar
   touch $@
 
 dir1/bar: | Dirs
   touch $@
 
 .PHONY: Dirs
 
 If you make 'dir1/bar', then remove 'dir2' and decide to make
 'dir2/foo', you appreciate that 'dir2' is remade because 'dirs' is an
 order-only dep of 'bar' and it is remade as soon as make realizes that
 'dirs' is not complete because 'dir2' is missing.
 So although this can be considered as the Makefile bug, cases like this
 can exist, so the proposed change would break this behavior (I propose
 that the 'Dirs' order-only dep is ignored because dir1/bar is all right
 and dir2/foo says that it depends only on dir1/bar)

If I am not mistaken, you are saying that:

  If

   1. an order-only dependency is missing and

   2. the target is not re-built (i.e. neither missing or older than
  normal prerequisites

  the order-only dependency should not be built.

I'm starting to see why you want support for that.


 I think that this is a nice idea, since 'make' doesn't play well with
 filters that can process batches of files at once, the server process
 is a good way to reduce overhead of processing those files one by one
 and you may end up needing a cache quite soon :-)
 
 Actually I might be wrong, but I think that if I have a program 'filter'
 capable of processing in01 in02 in03 ... files to out01 out02 out03 ...
 etc., it is not possible to tell this to 'make', so if out05 and out07
 are needed at some point, 'make' would call 'filter in05 in07 --some
 --flags'. Is that right? Because if this was somehow possible, I would
 not need that process at all.

I do not see the relation to the rest of this thread yet, but what you
describe sounds like classic pattern rules:

  out%: in%
cp $ $@

Here, cp would be the filter.  Are you referring to something else?

Best,



Sebastian


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


Re: feature request - order only deps

2013-02-02 Thread Matěj Týč
On So, 2013-02-02 at 00:22 +0100, Sebastian Pipping wrote:
 On 01.02.2013 16:18, Matěj Týč wrote:
  ...
  
  Consider a server process that can execute commands and that can load
  (huge) data into cache to spped the execution up. Loading the data is a
  make task and a target file cache-foo is created to expose that the data
  has been succesfully loaded into the server cache. Then cache-foo is an
  order-only dependency of foo1, foo2 and foo3 targets that take advantage
  of it (rules to make them call the server process that uses the foo
  cache). Therefore those targets are not made before setting the cache up
  and also the cache is loaded once, not concurently even if like -j4 is
  used as a make argument.
  
  As you might guess, if I have a target 'bar' that depends on 'foo1' and
  'foo2', then even if 'foo1' and 'foo2' exist, if 'cache-foo' is missing,
  it is remade and data are loaded into the cache without being of any
  use, which is quite annoying. In other words, the whole server might
  have to start, load the cache and then do nothing.
 
 This is what I understand to be our current Makefile:
 
   bar_deps = foo1 foo2
 
   bar: $(bar_deps)
 
   $(bar_deps): | cache-foo
 
   %:
   touch $@

Yes, this is basically correct, great!

 Now you want that cache-foo is not built if all of $(bar_deps) exist.
 We can achieve that by only adding cache-foo as a dependency, if former
 is not the case.  So let's replace the line
 
   $(bar_deps): | cache-foo
 
 by
 
   $(bar_deps): | $(if $(call any_file_missing,$(bar_deps)),cache-foo,)
 

The first function here would be enough for me, BUT... (see below)
BTW. it is a pity one can't write $(call file_missing,$@)

 
 using two custom functions:
 
   # $(call file_missing,file_1)
   # returns:
   #   true (actually $(file_1)) if the file is missing
   #   false (empty string) if the file exists
   define file_missing
   $(if $(wildcard $1),,$1)
   endef
 
   ...
 
 I hereby put that into the public domain.
 
 
 This session confirms it working:
 
   $ touch foo1 foo2 bar
 
   $ make
   make: `bar' is up to date.# cache-foo not built!
 
   $ rm foo1
 
   $ make
   touch cache-foo  # cache-foo built, since foo1 is missing
   touch foo1
   touch bar
 
 I'm curious, if that helps.

Thank you for your quick help, your example indeed works, but it has one
weakness.
Consider a case when eg. 'foo1' depends on 'baz' and suddenly 'baz' is
updated, so 'foo1' should be updated, too.
However, the old 'foo1' is still there, so the 'file_missing' function
assumes that nothing has to be done = cache-foo is not needed, which is
not true.

Since I generate the makefile using some M4sugar macros, I don't mind
having to write some extra stuff; however now the workaround path seems
to complicate quite a lot...

Thank you,
Matej

 
 Best,
 
 
 
 Sebastian




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


Re: feature request - order only deps

2013-02-02 Thread Sebastian Pipping
On 02.02.2013 16:19, Matěj Týč wrote:
 This is what I understand to be our current Makefile:

   bar_deps = foo1 foo2

   bar: $(bar_deps)

   $(bar_deps): | cache-foo

   %:
  touch $@
 [..]
 
 Thank you for your quick help, your example indeed works, but it has one
 weakness.
 Consider a case when eg. 'foo1' depends on 'baz' and suddenly 'baz' is
 updated, so 'foo1' should be updated, too.
 However, the old 'foo1' is still there, so the 'file_missing' function
 assumes that nothing has to be done = cache-foo is not needed, which is
 not true.
 
 Since I generate the makefile using some M4sugar macros, I don't mind
 having to write some extra stuff; however now the workaround path seems
 to complicate quite a lot...

How about something like this?

  bar_deps = foo1 foo2

  bar: $(bar_deps)

  $(bar_deps):
$(MAKE) cache-foo
touch $@

  %:
touch $@

Now cache-foo is remade iff at least one of $(bar_deps) needs a rebuild.

Best,



Sebastian


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


Re: feature request - order only deps

2013-02-02 Thread Sebastian Pipping
On 02.02.2013 18:38, Matěj Týč wrote:
 How about something like this?

   bar_deps = foo1 foo2

   bar: $(bar_deps)

   $(bar_deps):
  $(MAKE) cache-foo
  touch $@

   %:
  touch $@
 
 I have also thought of that, but this can work well reliably only in the
 case if there is only one make job. If I specify -j4, it may happen that
 all jobs will attempt to load the same cache simultaneously, which I
 have to avoid :-(

If that happens how about replacing

  $(MAKE) cache-foo

by something like

  mkdir .lock 2/dev/null || exit 0 ; \
  $(MAKE) cache-foo ; \
  ret=$$?; \
  rmdir .lock  exit $${ret}

The idea is:

 - mkdir can only succeed once

 - if $(MAKE) cache-foo fails

1. the whole should return non-zero

2. .lock is not left laying around

If that works for you conceptually, you could abstract a little more and
turn it into something re-usable like

  $(call synced_make,cache-foo)

Best,



Sebastian


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


feature request - order only deps

2013-02-01 Thread Matěj Týč

Hi,
I have noticed that if we have a target that has prerequisities, if 
those prerequisities are missing and I want to make the target, then 
even if the target file exists, prerequisities are remade if possible 
and then, consequently, the target has to be remade, too, since its 
prerequisity is now more up-to-date. Which, of course, makes perfect sense.


However, if a prerequisity is order-only, it is also going to be remade 
despite the target file existis already, but unlike the case above, the 
target won't be remade because it is allowed to be older than its 
order-only prerequisity. This is normally not an issue, since order-only 
prereqs are probably often cheap commands lke mkdir etc., but my case is 
different:


Consider a server process that can execute commands and that can load 
(huge) data into cache to spped the execution up. Loading the data is a 
make task and a target file cache-foo is created to expose that the data 
has been succesfully loaded into the server cache. Then cache-foo is an 
order-only dependency of foo1, foo2 and foo3 targets that take advantage 
of it (rules to make them call the server process that uses the foo 
cache). Therefore those targets are not made before setting the cache up 
and also the cache is loaded once, not concurently even if like -j4 is 
used as a make argument.


As you might guess, if I have a target 'bar' that depends on 'foo1' and 
'foo2', then even if 'foo1' and 'foo2' exist, if 'cache-foo' is missing, 
it is remade and data are loaded into the cache without being of any 
use, which is quite annoying. In other words, the whole server might 
have to start, load the cache and then do nothing.


Could you help me with this?
There are two possible solutions I see here:
 - Change the make behavior or add an option to not to remake 
order-only deps if they are not relevant
 - Suggest a workaround for situations like this, so the cache is 
loaded only if it is needed and parallel make execution won't attempt to 
load the cache for each job separately.


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


Re: feature request - order only deps

2013-02-01 Thread Sebastian Pipping
On 01.02.2013 16:18, Matěj Týč wrote:
 Hi,
 I have noticed that if we have a target that has prerequisities, if
 those prerequisities are missing and I want to make the target, then
 even if the target file exists, prerequisities are remade if possible
 and then, consequently, the target has to be remade, too, since its
 prerequisity is now more up-to-date. Which, of course, makes perfect sense.
 
 However, if a prerequisity is order-only, it is also going to be remade
 despite the target file existis already, but unlike the case above, the
 target won't be remade because it is allowed to be older than its
 order-only prerequisity. This is normally not an issue, since order-only
 prereqs are probably often cheap commands lke mkdir etc., but my case is
 different:
 
 Consider a server process that can execute commands and that can load
 (huge) data into cache to spped the execution up. Loading the data is a
 make task and a target file cache-foo is created to expose that the data
 has been succesfully loaded into the server cache. Then cache-foo is an
 order-only dependency of foo1, foo2 and foo3 targets that take advantage
 of it (rules to make them call the server process that uses the foo
 cache). Therefore those targets are not made before setting the cache up
 and also the cache is loaded once, not concurently even if like -j4 is
 used as a make argument.
 
 As you might guess, if I have a target 'bar' that depends on 'foo1' and
 'foo2', then even if 'foo1' and 'foo2' exist, if 'cache-foo' is missing,
 it is remade and data are loaded into the cache without being of any
 use, which is quite annoying. In other words, the whole server might
 have to start, load the cache and then do nothing.

This is what I understand to be our current Makefile:

  bar_deps = foo1 foo2

  bar: $(bar_deps)

  $(bar_deps): | cache-foo

  %:
touch $@

Now you want that cache-foo is not built if all of $(bar_deps) exist.
We can achieve that by only adding cache-foo as a dependency, if former
is not the case.  So let's replace the line

  $(bar_deps): | cache-foo

by

  $(bar_deps): | $(if $(call any_file_missing,$(bar_deps)),cache-foo,)

using two custom functions:

  # $(call file_missing,file_1)
  # returns:
  #   true (actually $(file_1)) if the file is missing
  #   false (empty string) if the file exists
  define file_missing
  $(if $(wildcard $1),,$1)
  endef

  # $(call any_file_missing,file_1 file_2 ..)
  # returns:
  #   true (a non-empty string) if any file is missing
  #   false (empty string) if all file exist
  define any_file_missing
  $(strip $(foreach filename,$(1),$(call file_missing,$(filename
  endef

I hereby put that into the public domain.


This session confirms it working:

  $ touch foo1 foo2 bar

  $ make
  make: `bar' is up to date.# cache-foo not built!

  $ rm foo1

  $ make
  touch cache-foo  # cache-foo built, since foo1 is missing
  touch foo1
  touch bar

I'm curious, if that helps.

Best,



Sebastian


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