How to Create a Makeflow for Compiling Multiple Drivers from other Makefiles in Subdirectories

197 Views Asked by At

I am relatively new to GNU makefiles and currently for my job, I am required to create a target in a makefile for a project to compile a bunch of drivers. Each driver already has their own makefile created in their own build directory and the targets that need to be called for each driver are the same. ie. for both driver A and driver B, "make shared" must be called.

My current idea is to define the path to each driver in the main makefile like so:

DRIVER_A = $(CURR_DIR)/<path_to_a>/driver
DRIVER_B = $(CURR_DIR)/<path_to_b>/driver
DRIVER_C = $(CURR_DIR)/<path_to_c>/driver

From here, what I really would like to do is call the same process for each of DRIVER_A, DRIVER_B and DRIVER_C ie:

        source <some_compiler>; \
        cp -r <some_folder> DRIVER_A/source/; \
        cd DRIVER_A/build; \
        make shared <some_flags>; \
        make so_test <some_flags>

And so to accomplish this, I tried putting DRIVER_A, DRIVER_B and DRIVER_C into one object like

DRIVER_SOURCES := \
        DRIVER_A\
        DRIVER_B \
        DRIVER_C

And then calling the target on DRIVER_SOURCES

drivers_sw: ${DRIVER_SOURCES}
        source <some_compiler>; \
        cp -r <some_folder> $@/source/; \
        cd $@/build; \
        make shared <some_flags>; \
        make so_test <some_flags>

But this doesn't work because there is no rule to make target for DRIVER_A, DRIVER_B and DRIVER_C which makes sense to me in hindsight however I don't know an alternative way to accomplish what I am trying to accomplish.

I'm also open to a better way of calling the make's for each driver than cd'ing to it's directory and calling make, I am sure there is a cleaner way but I just was going for function right off the bat.

Any help would be great, let me know if any more information is necessary, I apologize if I missed something, I am fairly new to posting on stack overflow.

Edit: I made a typo in the 4th code block, replaced "DRIVER_A" with $@

1

There are 1 best solutions below

1
On BEST ANSWER

Let's do the crude and simple way first. You already have a recipe for Driver A:

DRIVER_A = $(CURR_DIR)/<path_to_a>/driver
build_DRIVER_A:
    source <some_compiler>; \
    cp -r <some_folder> DRIVER_A/source/; \
    cd DRIVER_A/build; \
    make shared <some_flags>; \
    make so_test <some_flags>

If you confirm that this works, you can easily write the rules for B and C.

Once they're all working, you can have one rule to build all three:

build_all_drivers: build_DRIVER_A build_DRIVER_B build_DRIVER_C

And don't forget:

.PHONY: build_all_drivers build_DRIVER_A build_DRIVER_B build_DRIVER_C

Once all that is working, you can look to make the whole design more elegant, but it's hard to know how to do that without knowing the details of the project. I don't what what e.g. source <some compiler> does, so I don't know how to lift that out. I don't know what the various <some folders> contain, so I don't know how easy it would be to make those source files prerequisites of their drivers. But I would certainly look at the makefiles in the different driver directories, and see whether they could shoulder some of this burden-- after all, they're the ones responsible for building their respective drivers.