开发者

Building hierarchical Makefile with GNU Make

开发者 https://www.devze.com 2023-02-22 17:24 出处:网络
I have a project divided in modules, each hosted in a directory, say: root |_module_A _module.cpp _Makefile

I have a project divided in modules, each hosted in a directory, say:

root
|_module_A
 |_module.cpp
 |_Makefile
|_module_B
 |_Makefile
|_main.c
|_Makefile

main.c depends on targets defined in Makefiles related to module_A and module_开发者_运维技巧B.

I want to write my root/Makefile with respect to targets defined in Makefiles of both modules.

Now, I know that I could use the include directive, but the problem here is that targets and filenames in module_A and module_B aren't prepended with their directory, so I get something like this:

make: *** No rule to make target `module.o', needed by `main.c'.  Stop.

There is a good way to solve this?

Thanks.


There are a couple of ways to do this, none of them perfect. The basic problem is that Make is good at using things there to make things here, but not the other way around.

You haven't said what the targets in module_B are; I'll be pessimistic and suppose that module_A and module_B both have targets called module (different source files, different recipes), so you really can't use include.

The biggest choice you have to make is whether to use recursive Make:

If you don't, then root/Makefile must know how to build module_A/module and module_B/module, so you'll simply have to put those rules in. Then you must either leave the redundant rules in the subdir makefiles (and run the risk that they'll drift out of agreement with the master makefile), or eliminate them, or have them call the master makefile recursively (which you wouldn't have to do very often, but it sure would look silly).

If you do, then root/Makefile will look something like this:

main: main.o module_A/module.o Module_B/module.o
    ...

main.o: main.c
    ...

%/module.o:
    $(MAKE) -C $(@D) $(@F)

This will work well enough, but it will know nothing about dependencies within the subdirectories, so it will sometimes fail to rebuild an object that is out of date. You can make clean (recursively) beforehand every time, just to be on the safe side, crude but effective. Or force the %/module.o rule, which is less wasteful but a little more complicated. Or duplicate the dependency information in root/Makefile, which is tedious and untidy.

It's just a question of your priorities.


Can't you write the makefile in a non-recursive way?

Recursive Make Considered Harmful

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号