Search code examples
linuxmakefiledependencies

Getting dependencies of a shared library that could be located at any folder


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.


Solution

  • The solution turns out to be secondary expansion:

    .SECONDEXPANSION:
    ${DIR_OUT}/%.so: $$(shell find $$(dir $$@) -name *.o)
        $(CC) $(CFLAGS) -o $@ $(CLIBS) -shared $^