I'm creating a Rules.make
file, similar to Linux's 2.0 version, which contains all kinds of targets - including .so
files. My goal is to then only need to make minimalistic Makefiles like so:
include $(DIR_TOP)/Rules.make
in the directories that contain any source files I need compiled. The rules also enable me to create targets like so in the "main" Makefile:
something: something_else lib.so
, so that something_else
is done first, and then lib.so
is built.
Everything has been going smoothly, until I decided to add dependencies to the aforementioned shared library target. I figured something like the following would do the trick:
${DIR_OUT}/%.so: $(shell find $(dir $@) -name *.o)
$(CC) $(CFLAGS) -o $@ $(CLIBS) -shared $^
However, to my demise, $(dir $@)
apparently expands to $(dir ${DIR_OUT}/%.so)
, which then results in simply ${DIR_OUT}
, which is exactly not what I need. DIR_OUT
is simply the top-level directory string, but the target may be invoked from any sub-directories, or simply like target: $(DIR_OUT)/path/to/lib.so
. I was hoping that %
could match not only file names, but also any directories (which it does), and then have that expanded to $@
once it's already decided what the full path is. Doesn't work like that. With this solution, not only the object files I need are included in the building process, but also any other object files that are there in the output folder, and that then produces errors of kind multiple definition of x y z
etc.
Is there any other way to get the list of dependencies for the shared library I want to build? Ideally a purely Makefile based solution, but if there isn't one, I'm fond of some bash
scripting too.
The solution turns out to be secondary expansion:
.SECONDEXPANSION:
${DIR_OUT}/%.so: $$(shell find $$(dir $$@) -name *.o)
$(CC) $(CFLAGS) -o $@ $(CLIBS) -shared $^