tags:

views:

369

answers:

3

So, to compile my executable, I need to have the library locations set up correctly. The problem is, the setup comes from a bunch of scripts that do the env variable exporting, and what needs to be set up may change (beyond my control) so I need to use those scripts instead of copying their functionality. To compile in regular command line, I need to do something like:

setup library1
setup library2
source some_other_setup_script.bash
g++ blah.c
# setup is a executable on my system that run some scripts

How would I write a makefile that accomplishes that? As far as I tried, the env variable exporting does not carry over (i.e. "export VAR=remember; echo $VAR" won't work)

+3  A: 

Ultimately you will need to define the variable and execute the compiler in a shell list or even a script, rather than in separate make commands. There are a couple of refinements you could add, however. You could tell make about the script:

maintarget: script.sh blah.c
    source script.sh; g++ blah.c

script.sh:
    setup include script here

Another thing would be to just execute all that stuff in the same shell

maintarget: blah.c
    run this; run that; run the other thing; g++ blah.c

I believe all make versions will run a ; list in the same shell, but you can always force a subshell with (list) or by calling specifically a shell script as a compiler command wrapper.

Don't forget to have the appropriate targets depend on your scripts themselves. BTW, some make versions (pmake aka bsd make) can execute a command when defining a make variable, and all versions of make then exports those. But I don't think gmake can do that.

DigitalRoss
+1  A: 

If variable exporting is not working the way it does on your command line, that suggests that Make is choosing a shell different from the one you're using, with different syntax for handling variables ("export VAR=remember; echo $VAR" works fine for me). Make uses /bin/sh by default, but you can override this with the SHELL variable, which Make does not import from the environment. I suggest setting SHELL (in the Makefile) to whatever you're using in your environment and trying the "export VAR=remember" experiment again.

Beta
I also realize that I should use $$VAR so that make won't think that I'm quoting a macro...
polyglot
It doesn't really mean that. GNU make simply runs a new shell for each line in the comand. (I suspect he combined the two commands with ; for brevity)http://www.gnu.org/software/make/manual/make.html#Execution"When it is time to execute commands to update a target, they are executed by invoking a new subshell for each command line."
Ted Mielczarek
+1  A: 

You could write another shell script that executes all those commands, then prints out variable assignments that make can use. Run the script, pipe its output to a file, then include that file from your Makefile. For example:

Makefile:

all:
    echo $(FOO)

test.mk: test.sh
    ./$< > $@

include test.mk

test.sh

echo "FOO=1"

Running "make" in the directory containing this Makefile produces:

make: Entering directory `/home/luser/build/mktest'
Makefile:7: test.mk: No such file or directory
./test.sh > test.mk
make: Leaving directory `/home/luser/build/mktest'
make: Entering directory `/home/luser/build/mktest'
echo 1
1
make: Leaving directory `/home/luser/build/mktest'

make creates test.mk by running the shell script, then includes it. test.mk contains the output of test.sh, and is parsed as a Makefile. See http://www.gnu.org/software/make/manual/make.html#Include for more details.
We use a variant of this in Mozilla's client.mk to let you define options in a "mozconfig" file: http://mxr.mozilla.org/mozilla-central/source/client.mk#138

Ted Mielczarek