I am trying to build a shared library with one set of code, and everything works, except for this issue with my Makefile. Here’s my (simplified) Makefile thus far:
OBJS = bar.o
libfoo.so: OS = LINUX # These don't seem to happen
libfoo.dll: OS = WINDOWS
# Linux
ifeq ($(OS), LINUX)
CC = gcc
...
# Windows
else ifeq ($(OS), WINDOWS)
CC = i686-pc-mingw32-gcc
...
endif
all: libfoo.so libfoo.dll
libfoo.so: clean $(OBJS)
...
libfoo.dll: clean $(OBJS)
...
bar.o: bar_$(OS).c bar.h
...
So, when you type make libfoo.so, I expect it to set OS = LINUX first. Then, when it gets to bar.o (it is a dependency of libfoo) it should know which bar_$(OS).c to use. However, I get the error:
make: *** No rule to make target `bar_.c', needed by bar.o. Stop.
Which tells me that when it tries to make bar.o, $(OS) is not set. But shouldn’t that be the first thing that happens when I try to make libfoo.so, and that rule is evaluated?
If you want to set a target-specific variable, and then have that variable available outside the body of that rule, you can recursively call the Makefile, after exporting the variable:
You have to remember to export the variables you want to “persist” after the recursive make call. And also, as shown above, if you append to any variables before the call, you’ll want to make their initial assignment with
?=so they aren’t set the second time.