Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Re: [OT] Making GNU make do what I mean

by Perlbotics (Bishop)
on Sep 14, 2022 at 18:26 UTC ( #11146882=note: print w/replies, xml ) Need Help??

in reply to [OT] Making GNU make do what I mean

Try this rule (verified with GNU Make 4.2.1):

%.obj: $(filter %.src,$<) # obj dummy compiler @echo compile $< to $@ cat $< > $@
Simpler/more brutal: Remove the %.src part from your original rule to compile anything into an *.obj file if all possible source files can be compiled by the same sequence of instructions.

Replies are listed 'Best First'.
Re^2: [OT] Making GNU make do what I mean
by afoken (Chancellor) on Sep 16, 2022 at 19:41 UTC

    It works great, but I don't fully understand why. It even works better than specified in my post, because I want the compiled SDK files in a subdirectory. This is my working test dummy:

    default: all all: exe clean: rm -f foo.obj bar.obj sdk-objects/baz.obj main.obj exe %.obj: $(filter %.src,$<) @mkdir -p "$(dir $@)" @echo "Compile $< to $@" cat $< > $@ exe: main.obj foo.obj bar.obj sdk-objects/baz.obj @echo link $^ to $@ cat $^ > $@ main.obj: main.src foo.obj: subdir/foo.src bar.obj: subdir/bar.src sdk-objects/baz.obj: /tmp/baz.src

    It just does what I mean! But how does it work? The filter function should just return $< - but at that point, the filter function has processed the source pattern %.src, so the rule is no longer a simple pattern rule. And then, something magic happens ... ;-)


    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      ... the rule is no longer a simple pattern rule.
      Right. Since all your targets have no receipt, make tries to find an implicit rule to create the target using a complex Implicit-Rule-Search algorithm.

      The filter-rule is not a simple pattern rule, it is an implicit rule. The prerequisite is computed. Here filter returns the full(!) prerequisite path as a prerequisite of this computed rule as if you have written the explicit rule
      foo.obj: some/dir/foo.src. A computed rule that matches your initial dependency but this time one that also delivers a receipt. The filter just narrows the potential prerequisite candidates to the wanted group of *.src files. You could even perform complex string manipulation here (GNU make).

      The %.src within the filter expression is not a pattern in the sense of a simple pattern rule. Here, it is a match against $< when the filter function is executed - something like grep { /\.src$/ } @prerequisites. During the test, $< is the full path (dir + filename) of the initial prerequisite.

      Running make ; rm foo.obj ; LANG=C make -d shows the whole drama when make starts recursing to find an implicit rule to make some/dir/foo.src which is now treated as a target/dependency of the matching filter expression. But finally make comes to the conclusion that some/dir/foo.src is not a dependency that needs treatment and the filter-receipt is executed:

      ... Considering target file 'foo.obj'. File 'foo.obj' does not exist. Looking for an implicit rule for 'foo.obj'. Trying pattern rule with stem 'foo'. Trying pattern rule with stem 'foo'. Found an implicit rule for 'foo.obj'. <-- + the "filter" rule matched Considering target file 'some/dir/foo.src'. Looking for an implicit rule for 'some/dir/foo.src'. ... dramatic search for a rule to make 'some/dir/foo.src' ... No implicit rule found for 'some/dir/foo.src'. Finished prerequisites of target file 'some/dir/foo.src'. No need to remake target 'some/dir/foo.src'. Finished prerequisites of target file 'foo.obj'. Must remake target 'foo.obj'. Putting child 0x5582f63d0120 (foo.obj) PID 9420 on the chain. Live child 0x5582f63d0120 (foo.obj) PID 9420 === compile some/dir/foo.src to foo.obj Reaping winning child 0x5582f63d0120 PID 9420 cat some/dir/foo.src > foo.obj Live child 0x5582f63d0120 (foo.obj) PID 9421 Reaping winning child 0x5582f63d0120 PID 9421 Removing child 0x5582f63d0120 PID 9421 from chain. Successfully remade target file 'foo.obj'. ...

      Update: Run make -p to identify the rule that matched. My test Makefile where the rule is at line #13 returned something like:

      foo.obj: some/dir/foo.src # Implicit rule search has been done. # Implicit/static pattern stem: 'foo' # Last modified 2022-09-17 11:10:23.135420027 # File has been updated. # Successfully updated. # recipe to execute (from 'Makefile', line 14): @echo === compile $< to $@ cat $< > $@

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11146882]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2023-03-27 01:39 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (63 votes). Check out past polls.