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
gocompiler complainingEXECUTABLE_FILENAMEis 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 thegodepcommand it gets passed as multiple arguments:becomes:
which is complete nonsense (note that
$ogets 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_typeto refer to a shell variable, so make doesn't try to expand$os_typebefore 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 amakefunction 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_SUFFIXused:=and so already contains the filename).