I am working in a large project where we have several subdirectories from which we build libs/archives. Most of the subdirectories do NOT have dependecies against eachother but some do.
So for example, this is the general form:
TARG1=targ1/
TARG2=targ2/
TARG3=targ3/
SUBDIRS= lib1\
lib2\
lib3\
...
.PHONY: $(TARG1) $(TARG2) $(TARG3)
The build order must be as follows: TARG1 -> TARG2-> TARG3 -> SUBDIRS
We have structured the targets like this:
build_libs:
$(MAKE) subdirs
subdirs: $(SUBDIRS)
$(SUBDIRS): $(TARG3)
$(MAKE) -C $@
$(TARG3): $(TARG2)
$(MAKE) -C $@
$(TARG2): $(TARG1)
$(MAKE) -C $@
$(TARG1):
$(MAKE) -C $@
Now as I see it, this would allow for maximum parallelization possible since when having built the targets (TARG1 -> TARG3), Make can build all libs in SUBDIRS simultaneously. But perhaps there is a better method to optimize this? The downside with this approach, which I see, is that we get a much larger Makefile since we must specify a recipe for every target which has a dependecy against another target. Is there some way to avoid this and still allow for full parallelization?
The other approach would be to build the targets like this:
SUBDIRS = targ1 targ2 targ3 lib1 lib2 lib3
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done
Now the good thing with this approach is that the dependencies can easily be specified just by writing the targets in the correct order. However Make would not be able to fully utilize the parallelization since it would have to complete every sub-directory before moving on to the next one.
Perhaps my assumptions are wrong so therefore I ask this question how to best organize the targets to allow for optimal parallelization? And as a side-question how to organize the targets to avoid code duplication?
You don't have to duplicate the recipes, if they are all the same. Recipes and prerequisites don't have to be defined at the same time, if you don't want to. You could rewrite your first example as:
build_libs:
$(MAKE) subdirs
$(SUBDIRS) $(TARG1) $(TARG2) $(TARG3):
$(MAKE) -C $@
subdirs: $(SUBDIRS)
$(SUBDIRS): $(TARG3)
$(TARG3): $(TARG2)
$(TARG2): $(TARG1)
I don't really know why you have the build_libs
recursion at all; why not just have build_libs: subdirs
?
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments