help-make
[Top][All Lists]
Advanced

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

Re: eval of foreach loop of a define runs first target more than once


From: Philip Guenther
Subject: Re: eval of foreach loop of a define runs first target more than once
Date: Tue, 25 May 2010 20:28:46 -0700

On Mon, May 24, 2010 at 8:55 AM, Utku Ozcan <address@hidden> wrote:
> On Fri, May 21, 2010 at 8:51 PM, Philip Guenther <address@hidden> wrote:
> ...
>>> define write_list_to_file
>>> $(2):
>>>   $(foreach file,$($1),$(shell echo $(file) >> $(2)))
>>> endef
>>
>> As you noticed, this function is completely broken.  Consider the
>> output and side-effects of
>>
>> $(info $(call write_list_to_file foo,bar))
>>
>> Note that simply putting that line in the makefiles results in the
>> creation of the file 'bar' EVEN IF 'bar' ISN'T A MAKE TARGET!  When
>> does the $(shell) function get expanded?
>>
>> Why are you using the make functions $(foreach) and $(shell) in the
>> commands for the rule and not just writing shell commands?  Did you
>> first write a correct Makefile that does stuff directly without using
>> $(eval) and only factor out the code after doing that?  If not, how
>> did you know what the generated Makefile rules should look like?
>
> Hi guys, I am really running out of ideas. I have replaced the code in
> define with shell commands, as Philip proposed:

<sigh>  Did you notice my second question which asked whether you
wrote out a correct Makefile without using $(eval) and *then* factor
out the common code into macro functions?  You're jumping too many
steps and when things aren't right you don't have the experience or
context to see where the problem is!

Step 1: write a correct makefile without $(eval), $(foreach), or $(shell):
-------
# variables go here...
codefile_list_CODE:
        printf '%s\n' $(CODE_SRCS) >$@

codefile_list_CODE_part01:
        printf '%s\n' $(CODE_part01_SRCS)  >$@

codefile_list_CODE_part02:
        printf '%s\n' $(CODE_part02_SRCS) >$@

codefile_list_CODE_part03:
        printf '%s\n' $(CODE_part03_SRCS) >$@
-------


Step 2: notice that the variable names can be derived from the target
names (it would be insane to do otherwise), so use computed variable
names:
-------
# variables go here...
${CODE_SRCS_LIST:%=codefile_list_%}:
        printf '%s\n' $($(@:codefile_list_%=%_SRCS)) >$@
-------

Step 3: STOP.  Heck, that's even portable to other versions of make!

(This was today's example of how to write a simpler, *MAINTAINABLE*
Makefile by treating it as a declarative language, like it has been
for 33 years, instead of as an imperative language, using features
that have been around for decades instead of advanced features that
were introduced in just the last handful of years.  Yes, $(eval) has a
place, but this isn't it.)


Philip Guenther



reply via email to

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