Make question

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Make question

Andreas.Raab
Hi Folks -

I'm trying to rework the windows build structure and I'm running into a
problem with make. Basically, what I'm trying to do is to test whether a
file exists in a given location and if so, copy it, and if not, copy a
default from elsewhere. This should look like here:

foo.here:
if $(file-exists locationA/foo.locA)
        cp locationA/foo.locA foo.here
else
        cp locationB/foo.locB foo.here
endif

I think you get the idea. My problem is that I can't seem to find a
reliable way of expressing the line

if $(file-exists locationA/foo.locA)

in any reasonable way (i.e., by using make's functions). Any ideas how
to convince make to determine whether the file exists or not?

Thanks,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: Make question

Bert Freudenberg
Andreas Raab schrieb:

>
> Hi Folks -
>
> I'm trying to rework the windows build structure and I'm running into a
> problem with make. Basically, what I'm trying to do is to test whether a
> file exists in a given location and if so, copy it, and if not, copy a
> default from elsewhere. This should look like here:
>
> foo.here:
> if $(file-exists locationA/foo.locA)
>     cp locationA/foo.locA foo.here
> else
>     cp locationB/foo.locB foo.here
> endif
>
> I think you get the idea. My problem is that I can't seem to find a
> reliable way of expressing the line
>
> if $(file-exists locationA/foo.locA)
>
> in any reasonable way (i.e., by using make's functions). Any ideas how
> to convince make to determine whether the file exists or not?

I think you have to use the $(wildcard ...) function to test for file
existence.

Alternatively, you could specify a vpath
(http://www.gnu.org/software/make/manual/html_node/Directory-Search.html)

- Bert -

Reply | Threaded
Open this post in threaded view
|

Re: Make question

Andreas.Raab
Bert Freudenberg wrote:

>> I think you get the idea. My problem is that I can't seem to find a
>> reliable way of expressing the line
>>
>> if $(file-exists locationA/foo.locA)
>>
>> in any reasonable way (i.e., by using make's functions). Any ideas how
>> to convince make to determine whether the file exists or not?
>
> I think you have to use the $(wildcard ...) function to test for file
> existence.

That's what I tried but I couldn't get it to work. It seems that no
variation of

ifneq (,$(wildcard locationA/foo.locA))
        @echo foo.locA exists
else
        @echo foo.locA does NOT exist
endif

works properly due to the way the "failure" case needs to be specified
(i.e., the result of the $wildcard function is not just "empty").

> Alternatively, you could specify a vpath
> (http://www.gnu.org/software/make/manual/html_node/Directory-Search.html)

Tried that, too, but there is a real problm if foo.locA exists in
multiple places (and it's hard to rule out that it exists *somewhere* in
the search path). If it does, it will be picked up not only from
locationA but possibly also from some other locations.

Cheers,
   - Andreas


Reply | Threaded
Open this post in threaded view
|

Re: Make question

David T. Lewis
In reply to this post by Andreas.Raab
On Mon, Sep 04, 2006 at 07:58:01PM -0700, Andreas Raab wrote:

>
> I'm trying to rework the windows build structure and I'm running into a
> problem with make. Basically, what I'm trying to do is to test whether a
> file exists in a given location and if so, copy it, and if not, copy a
> default from elsewhere. This should look like here:
>
> foo.here:
> if $(file-exists locationA/foo.locA)
> cp locationA/foo.locA foo.here
> else
> cp locationB/foo.locB foo.here
> endif

If the tool chain is using bash, or if there is a /bin/test available,
then the following should work:

FOO-AT-A=locationA/foo.locA
FOO-AT-B=locationB/foo.locB
foo.here:
        if test -r $(FOO-AT-A) ; \
        then \
          cp "$(FOO-AT-A)" $@; \
        else \
          cp "$(FOO-AT-B)" $@; \
        fi


Dave


Reply | Threaded
Open this post in threaded view
|

Re: Make question

Ian Piumarta
In reply to this post by Andreas.Raab
> It seems that no variation of
>
> ifneq (,$(wildcard locationA/foo.locA))
> @echo foo.locA exists
> else
> @echo foo.locA does NOT exist
> endif
>
> works properly due to the way the "failure" case needs to be specified
> (i.e., the result of the $wildcard function is not just "empty").

(I tried for five minutes and couldn't make it generate anything but the file name or an empty string.  But I'm not running MinGW so that's not really helpful...)

Why not just invert the sense of the test and compare for what you know is a valid result of the$wildcard?

ifeq (locationA/foo.locA,$(wildcard locationA/foo.locA))
        @echo foo.locA exists
else
        @echo foo.locA does NOT exist
endif

Cheers,
Ian




Reply | Threaded
Open this post in threaded view
|

Re: Make question

Andreas.Raab
I have simplified this a little and would appreciate if you could
double-check to see if that's an issue with make or if I'm doing
something stupid. Try this:
- Create directories source/foo/
- Create directories dest/foo/
- Add a file source/foo/test
- Create a Makefile containing:

foo: dest/foo/test

dest/%/test:
        @echo Trying to create $@
        @echo Wildcard is $(wildcard source/$*/test)
ifeq (source/$*/test, $(wildcard source/$*/test))
        @echo Everything is fime
else
        @echo WHERE IS THE FILE???
endif


- Run it via make foo to see the effect.

In my understanding the ifeq *should* fire appropriately but it doesn't.
Any ideas why?

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: Make question

Andreas.Raab
Oh, I should have added that changing

        ifeq (source/$*/test, $(wildcard source/$*/test))

to

        ifeq (source/foo/test, $(wildcard source/foo/test))

works fine, but neither do

        ifeq (source/$*/test, $(wildcard source/foo/test))
        ifeq (source/foo/test, $(wildcard source/$*/test))

Something special about $* in ifeq?

Cheers,
   - Andreas

Andreas Raab wrote:

>
> I have simplified this a little and would appreciate if you could
> double-check to see if that's an issue with make or if I'm doing
> something stupid. Try this:
> - Create directories source/foo/
> - Create directories dest/foo/
> - Add a file source/foo/test
> - Create a Makefile containing:
>
> foo: dest/foo/test
>
> dest/%/test:
>     @echo Trying to create $@
>     @echo Wildcard is $(wildcard source/$*/test)
> ifeq (source/$*/test, $(wildcard source/$*/test))
>     @echo Everything is fime
> else
>     @echo WHERE IS THE FILE???
> endif
>
>
> - Run it via make foo to see the effect.
>
> In my understanding the ifeq *should* fire appropriately but it doesn't.
> Any ideas why?
>
> Cheers,
>   - Andreas
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Make question

Bert Freudenberg
this works for me:


foo: dest/foo/test

dest/%/test:
         @echo Trying to create $@
         @echo Wildcard is $(wildcard source/*/test)
ifeq ("source/foo/test", "$(wildcard source/*/test)")
         @echo Everything is fime
else
         @echo WHERE IS THE FILE???
endif


Andreas Raab schrieb:

>
> Oh, I should have added that changing
>
>     ifeq (source/$*/test, $(wildcard source/$*/test))
>
> to
>
>     ifeq (source/foo/test, $(wildcard source/foo/test))
>
> works fine, but neither do
>
>     ifeq (source/$*/test, $(wildcard source/foo/test))
>     ifeq (source/foo/test, $(wildcard source/$*/test))
>
> Something special about $* in ifeq?
>
> Cheers,
>   - Andreas
>
> Andreas Raab wrote:
>>
>> I have simplified this a little and would appreciate if you could
>> double-check to see if that's an issue with make or if I'm doing
>> something stupid. Try this:
>> - Create directories source/foo/
>> - Create directories dest/foo/
>> - Add a file source/foo/test
>> - Create a Makefile containing:
>>
>> foo: dest/foo/test
>>
>> dest/%/test:
>>     @echo Trying to create $@
>>     @echo Wildcard is $(wildcard source/$*/test)
>> ifeq (source/$*/test, $(wildcard source/$*/test))
>>     @echo Everything is fime
>> else
>>     @echo WHERE IS THE FILE???
>> endif
>>
>>
>> - Run it via make foo to see the effect.
>>
>> In my understanding the ifeq *should* fire appropriately but it
>> doesn't. Any ideas why?
>>
>> Cheers,
>>   - Andreas
>>
>>


--
- Bert -

Reply | Threaded
Open this post in threaded view
|

Re: Make question

Ian Piumarta
In reply to this post by Andreas.Raab
> From: Andreas Raab [mailto:[hidden email]]
>
> ifeq (source/foo/test, $(wildcard source/foo/test))
>
> works fine, but neither do
>
> ifeq (source/$*/test, $(wildcard source/foo/test))
> ifeq (source/foo/test, $(wildcard source/$*/test))
>
> Something special about $* in ifeq?

The automatic variables ($@, $< $*, etc.) are only valid within the rule(s) of an implicit template.  Conditionals are not rules, so automatic variables are meaningless to (and are not defined within) them.

If you have to use automatic variables to construct the path to an optional file then I think I would suggest Dave's approach that puts the test into a shell command run from within the rule proper, where the $* makes sense and wil be correctly substituted.

(If you have a finite set of possible locations that you can enumerate, you might be able to make things easier by writing a script to do the job: 'copy_if_source_present_and_dest_missing sourceFile destFile' or somethine along those lines and then just run it for every possible candidate.)

Cheers,
Ian




Reply | Threaded
Open this post in threaded view
|

Re: Make question

Andreas.Raab
[hidden email] wrote:
>> Something special about $* in ifeq?
>
> The automatic variables ($@, $< $*, etc.) are only valid within the rule(s) of an implicit template.  Conditionals are not rules, so automatic variables are meaningless to (and are not defined within) them.

Ouch. That stinks. But it sure as hell explains it.

> If you have to use automatic variables to construct the path to an optional file then I think I would suggest Dave's approach that puts the test into a shell command run from within the rule proper, where the $* makes sense and wil be correctly substituted.

This is windows so shell commands are tricky (I'm not going to require
Cygwin etc) but I think I can solve this via recursive Makefile invokation.

Thanks for the help.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: Make question

Ian Piumarta
In reply to this post by Andreas.Raab
> From: [hidden email] [mailto:[hidden email]]
>
> The automatic variables ($@, $< $*, etc.) are only valid within the rule(s) of an implicit template.

Everywhere I said 'rules' I really meant 'rules and associated commands', otherwise the allusion to Dave's solution makes little sense.

(BTW: my explanation holds for static patterns too, which I suspect might be what you're actually using, where '$*' is bound to the text make has inferred for '%' in the target pattern.)

Tchao,
Ian




Reply | Threaded
Open this post in threaded view
|

Re: Make question

Bert Freudenberg
In reply to this post by Andreas.Raab
Andreas Raab schrieb:
>
> [hidden email] wrote:
>>> Something special about $* in ifeq?
>>
>> The automatic variables ($@, $< $*, etc.) are only valid within the
>> rule(s) of an implicit template.  Conditionals are not rules, so
>> automatic variables are meaningless to (and are not defined within) them.
>
> Ouch. That stinks. But it sure as hell explains it.

Ah, it does indeed.

>> If you have to use automatic variables to construct the path to an
>> optional file then I think I would suggest Dave's approach that puts
>> the test into a shell command run from within the rule proper, where
>> the $* makes sense and wil be correctly substituted.
>
> This is windows so shell commands are tricky (I'm not going to require
> Cygwin etc) but I think I can solve this via recursive Makefile invokation.

Given your original problem ... how about this?

foo: dest/foo/test

dest/%/test: source/%/test
        @echo making $@ from $<

dest/%/test: default/%/test
        @echo making $@ from $<


This looks first for source/foo/test and then for default/foo/test.

- Bert -

Reply | Threaded
Open this post in threaded view
|

Re: Make question

Andreas.Raab
Bert Freudenberg wrote:
> Given your original problem ... how about this?

Ah, this is nice. I like it and it works like a charm.

Thanks!
   - Andreas

>
> foo: dest/foo/test
>
> dest/%/test: source/%/test
>     @echo making $@ from $<
>
> dest/%/test: default/%/test
>     @echo making $@ from $<
>
>
> This looks first for source/foo/test and then for default/foo/test.
>
> - Bert -
>
>