bug-make
[Top][All Lists]
Advanced

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

Re: Defining new targets with eval during secondary expansion?


From: Ismail Badawi
Subject: Re: Defining new targets with eval during secondary expansion?
Date: Thu, 9 Mar 2017 20:19:37 -0500

Hi,

Sorry, I didn't see your message earlier because I'm not on the list and it didn't email me.

This seems to work fine, as long as I also define a rule for the build directory itself, since the % can't match an empty string.

It doesn't work in make 3.81 -- there, make seems to ignore the trailing slash in the prerequisite. As a workaround I can write '$$(@D)/.' (trailing dot) and it works fine.

Anyway thanks, this is good enough for me.

Thanks,
Ismail

Ismail Badawi wrote:

> I'm trying to define new targets with eval during secondary expansion, but
> apparently this is not allowed -- with make 4.2.1 I get an error like
> this:
> 
>   Makefile:94: *** prerequisites cannot be defined in recipes.  Stop.
> 
> I found bugs #24588 and #24622 related to this.
> 
> My use case is as follows. I have a bunch of targets which can be nested
> arbitrarily deeply in subdirectories within my build directory. For each
> target, I'd like to have an order-only prerequisite on the existence of
> its parent directory. So something like this:
> 
>   build/foo/bar/baz/mytarget: | build/foo/bar/baz
>   touch $@
> 
>   build/foo/bar/baz:
>   mkdir -p $@
> 
> The issue is that if I have many targets in many different directories,
> then I
> need to write lots of 'mkdir' rules like this. I can save some typing with
> a template and a foreach/eval/call, but that's still a bit awkward because
> I have
> to maintain a list of all the directories I need.

I don't have a solution to your general problem but for your specific 
requirement of creating directories this is what I do:

1. All directories must end in the '/' character.

2. Use secondary expansion to determine the target directory. Note trailing 
'/'.

   build/foo/bar/baz/mytarget: | $$(@D))/
        touch '$(@)'

3. Define pattern rule for directories.

   $(build_dir)%/ :
            mkdir -p '$(@)'

4. You may need to mark the pattern as precious

   .PRECIOUS : $(build_dir)%/

Works well for me for 4.1 and later. No need to list directories. Only one 
rule required.

-- 
JP

reply via email to

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