I want to create a Makefile which will build a program which when run's output will be used as a value for a variable in the same Makefile.
Consider the program:
print_name.c:
#include <stdio.h>
int main() {
printf("foo\n");
return 0;
}
I'd like to use the standard output of this program to then determine a directory name to be stored in a variable used in the makefile and used for other rules, so far I've tried:
all: $(MY_DIRECTORY_NAME)/my_program
print_name: print_name.c | print_name
gcc $^ -o $@
MY_DIRECTORY_NAME:=$(shell ./print_name)
$(MY_DIRECTORY_NAME)/my_program: my_program.c
mkdir -p $(MY_DIRECTORY_NAME)
gcc $^ -o $@
However when I run:
make all
I get:
make: *** No rule to make target '/my_program', needed by 'all'. Stop
Whereas I'd like:
mkdir -p foo
gcc my_program.c -o foo/my_program
So basically, I want to compile print_name
before the assignment to MY_DIRECTORY_NAME
, and then that variable in then used in the following rules. Is this possible, and if not are there any workarounds for this?
The basic problem is that you need to build (and run) print_name before you can parse the rules that use it -- but all rules are read and parsed before anything is built. So you need to run make twice -- first to build print_name and second to build everything that depends on it. Something like
all: print_name
$(MAKE) `./print_name`/my_program
should do the trick