help-make
[Top][All Lists]
Advanced

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

Re: Request for help in setting a variable in GNU Make.


From: sqweek
Subject: Re: Request for help in setting a variable in GNU Make.
Date: Thu, 6 Apr 2006 14:10:42 +0800

On 06/04/06, Louie McCrady <address@hidden> wrote:
> I think that the problem is the scope of the sourceFiles variable in the
> implicit rule is different from the sourceFiles variable outside of the
> implicit rule.

 Scope is one way to think of it, but it's not exactly correct. You're
mixing make and shell syntax. It's fairly simple to work out which is
being used - if the line begins with a tab, it needs to be shell
syntax, otherwise it is make syntax. So...

> myVar = snafu

 Here you set the make variable "myVar" to "snafu".

> target:
>         myVar = "hello"

 Here, you set the *shell environment variable* "myVar" to "hello".

>         @echo "--- $(myVar) ---"

 And finally you echo the value of the make variable "myVar". Now you
might be thinking:

myVar = snafu
target:
        myVar = "hello"
        @echo "-- $$myVar --"

 In an attempt to echo the value of the environment variable "myVar"
instead of the make variable. But, there's still a problem here - make
executes each command line in a /different/ subshell. So, your change
to the environment variable "myVar" in line 1 isn't going to be
reflected in your attempt to echo it on line 2. You can get around
this by putting all your commands on one line, separated by
semi-colons, and you can even keep things formatted nicely by putting
a backslash at the end of a line so that make treats 2 physical lines
as one single line. However, attempting to modify your make variable
"myVar" from the shell is going to be convoluted at best, so I don't
think all this is very helpful regarding your problem.
 You can have target specific variables, eg:
%.o : sourceFiles+=$<
 This will alter the value of the make variable "sourceFiles" to
include the dependee whenever executing a %.o rule. However, if you
try this approach you WILL run into a scoping issue, because the
variable change is only visible for this target and targets below it
(ie, targets that are being built to satisfy this target's
dependencies).

> objectFiles = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
 So it took me awhile to realise why you were bothering with
objectFiles at all when you plan on invoking the compiler once -
you're trying to build a list of updated sourcefiles and then only
compile them. Which I suspect is going to be a real PITA to pull off
in plain make, but would be easy enough to do in a couple of lines of
shell script (considering the .exe in the name of your target i f-ing
hope you're in cygwin or similar *nix style environment - i don't
fancy trying to pull any tricks with standard windows apps):

foo.exe: $(objectFiles)
        SOURCES=""; \
        for obj in $(objectFiles); \
        do src=$${obj%.o}.cpp; \
            test $$src -nt $$obj && SOURCES="$$SOURCES $$src"; \
        done; \
        test -n "$$SOURCES" && $(COMPILE.CPP) $$SOURCES
        $(LINK.CPP) $^ $(OUTPUT_OPTION)

 It occurs to me while writing this rule (which may well be the most
retarded make rule i've ever written) the other big problem with this
approach - it has the effect of updating multiple targets in a single
rule, which make really doesn't handle very well (in effect, you are
lying to make when you tell it "this is how to update a %.o file from
a %.cpp file", and then just adding the %.cpp file to a list instead
of updating the %.o).

 Summing up, I don't think this is a reasonable approach to take when
building your software with make. But, if you're absolutely convinced
this is the way to go, I've hopefully included enough information to
allow you to hack up a solution (keep in mind all the make code I
wrote in this post is untested and only intended to communicate the
concept).

reply via email to

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