tamjd1
tamjd1

Reputation: 966

reading makefile variables from bash script

I have a makefile in which I'm trying to set some variables which already exist in a bash script which I wrote called: set-vars.sh (it just contains variable names and values).

I'm using these variables in several other bash scripts. I need to also be able to use them in my makefile.

After a lot of researching and trying to figure out what is the best way to set variables from a bash script in makefile, I've found a way which works; which is as follows:

set-vars.sh:

# set vars
foo=FOO1
bar=BAR1
baz=BAZ1

# if a command line arg is given (e.g. foo) 
# echo value command line arg (e.g. echo $foo)

if ! [ -z ${1+x} ]; then echo ${!1}; fi

The magic here is the last line which echoes the value of a variable the name of which is provided in the command line argument, IF there is a command line argument. I call this script in the makefile and provide the variable name and use the echoed value to set the makefile variables.

Makefile:

.PHONY:  target1 target2 target3

export foo = $(shell sh set-vars.sh foo)

target1:
    @echo $(foo)

# ... other targets which reference $(foo) ...

This works, but it is probably a hacky way of doing it. I'm wondering if there is a more simple, elegant way to do what I want to do.

I've come across several similar questions and answers on StackOverflow but didn't find anything that works with my example. If there is an answer already which I missed, please point me to it.

Many thanks!

Upvotes: 5

Views: 3632

Answers (3)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136208

It is generally considered poor practice for build systems to depend on environment variables because if they do you suddenly have a reproducibility problem when the output depends not only on the command line but also on the state of environment variables.

Having warned you, all environment variables are accessible in make, e.g.:

user := ${USER} # ${USER} comes from the environment.
all :
    @echo ${user}

In other words, have a script that sets the environment variables and invokes make:

#!/bin/bash
export foo=FOO1
export bar=BAR1
export baz=BAZ1
exec make "$@"

Alternatively, you can have a shell script with export foo=FOO1 statements only. This turns out to be valid makefile syntax, so that you can do include set-vars.sh in your Makefile.

Upvotes: 1

aragaer
aragaer

Reputation: 17848

Not sure if it's less hacky, but you can "create" a file that can be included into Makefile. In runtime. Like this:

$(shell grep '=' vars.sh > /tmp/vars.tmp)
include /tmp/vars.tmp
$(shell rm /tmp/vars.tmp)

Replace the first line with something more sane.

Upvotes: 1

Renaud Pacalet
Renaud Pacalet

Reputation: 28965

You can define your variables in a file that can be sourced from your shell scripts and included from your Makefile:

$ cat vardef.txt
foo=FOO1
bar=BAR1
baz=BAZ1
$ cat set-vars.sh
source ./vardef.txt
echo "$foo $bar $baz"
$ sh ./set-vars.sh
FOO1 BAR1 BAZ1
$ cat Makefile
include vardef.txt
all:
    @echo "$(foo) $(bar) $(baz)"
$ make
FOO1 BAR1 BAZ1

Isn't it just wonderful when two languages partly use the same syntax?

Upvotes: 8

Related Questions