I have a makefile
that I want to run against both linux (debian/Ubuntu) and Windows/Cygwin.
I need to do something slightly different according to the running environment and I came out with the following piece of code which is supposed to store in the variable a string which is foo
if the OS is linux, otherwise foo.exe
:
EXECUTABLE_FILENAME=bash -c 'os_type=`uname`; if [ $os_type == "Linux" ]; then echo "foo"; else echo "foo.exe"; fi'
then I would like to use that variable in another one, something like:
GODEPBUILD=$(godep go build -o $(EXECUTABLE_FILENAME))
the previous one with/without the evaluation via $(...some stuff...)
(see below for all the tests I made to make this work)
finally I would like to "run" that command somewhere else in a task within the makefile
, something like:
build-all:
@echo -e "build my project"
$(GODEPBUILD)
I have tried many different combinations
- with/without
$(some stuff here)
, - with/without single quotes
'
, - with/without the bash "`"
- with/without the wrap
bash -c '...some commands here...'
but I get all sorts of bash errors e.g.:
invalid option -- 'c'
- the
go
compiler complainingEXECUTABLE_FILENAME
is empty with this message:flag needs an argument: -o
- silent ignore of the
$(GODEPBUILD)
(I believe because somehow it evaluates to an empty command)
I am doing this chain of steps because I need to wrap many commands of the go
toolchain into another tool called godep
, also I need to combine this with some specific features of the Operating System (e.g. the filename thing I am stuck with). I have defined many different "commands" of the go
toolchain at the beginning of the makefile
e.g.:
GODEP_VERSION=godep version
GODEPRESTORE=godep restore
GODEPTEST=godep go test -v
GOCLEAN=go clean
I call these "commands" inside the makefile
tasks like $(GODEP_VERSION)
(or -$(GODEP_VERSION)
if I need to ignore the stderr
) and for me it was nice to add the "build command" in a similar fashion.
The make
version is:
- 4.1 on Ubuntu
- 4.2.1 on Cygwin
Is this thing possible at all?
How could I achieve this combination of different "small scripts" to build the final command that make
should run inside a task?
Surely you want the output of the bash command as the filename, right? You are using the bash command itself as the filename. i.e.
$(EXECUTABLE_FILENAME)
is a string consisting of several words. When you pass that to thegodep
command it gets passed as multiple arguments:becomes:
which is complete nonsense (note that
$o
gets expanded as a make variable, but that's the least of your problems).Surely you want to run the bash command to decide the filename. You can run a shell command with make's
$(shell ...)
function:Note I used
$$os_type
to refer to a shell variable, so make doesn't try to expand$os_type
before invoking the shell.But I would simplify that to something like:
Or maybe:
Now the make variable
$(EXECUTABLE_FILENAME)
will expand to the filename.The next problem is here:
What is this supposed to mean? Why have you enclosed it in
$(...)
? That tries to run amake
function calledgodep
, surely you just want:Then when you use it in the recipe it will expand to either:
Or:
N.B. as an optional (but recommended) improvement you should use
:=
to set make variables, because otherwise they get expanded every time they are used. This would mean that every time you refer to a variable that uses$(EXECUTABLE_SUFFIX)
the shell command is run again. Changing it to use:=
will mean it gets evaluated once:Similarly, you can use
:=
for the other variables too:(These ones don't really matter, as long as
EXECUTABLE_SUFFIX
used:=
and so already contains the filename).