2011-04-05 62 views
2

我有一个项目模块划分,在目录中的每个托管,说:与GNU大厦层​​次的Makefile让

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

的main.c取决于与module_Amodule_B在Makefile文件中定义的目标。

我想写我的root/Makefile相对于两个模块的Makefiles中定义的目标。现在

,我知道我可以使用include指令,但这里的问题是,在module_Amodule_B目标和文件名不符合他们的目录前缀,所以我得到的是这样的:

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

有一个很好的方法来解决这个问题?

谢谢。

+0

你想去哪儿把目标文件(例如'module.o')? – Beta 2011-04-05 12:14:55

+0

在相对源文件的相同(子)目录中。 – akappa 2011-04-05 14:23:45

回答

2

有几种方法可以做到这一点,但都不是完美的。基本问题在于,Make擅长使用那里的来制作东西这里的,但不是相反。

您还没有说过module_B中的目标是什么;我会悲观的,并假设module_Amodule_B都有目标module(不同的源文件,不同的食谱),所以你真的不能使用include

你必须做出最大的选择是,是否使用递归make:

如果你不这样做,那么root/Makefile必须知道如何建立module_A/modulemodule_B/module,所以你只需把这些规则。然后,你必须在子目录makefile中保留冗余规则(并且冒着与主makefile不一致的风险),或者消除它们,或让它们递归地调用master makefile(你不会必须经常做,但它肯定会看起来很傻)。

如果你这样做,那么root/Makefile会是这个样子:

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

main.o: main.c 
    ... 

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

这将工作做得不够好,但它会一无所知子目录内的相关性,因此有时会无法重建的对象,已过期。您可以每次预先递增make clean(只是为了安全起见,粗略而有效)。或者强制执行%/module.o规则,这个规则不那么浪费,但更复杂一点。或者复制root/Makefile中的依赖信息,这是单调乏味的。

这只是您优先考虑的问题。

+0

好,彻底的答案,如果你必须使用递归make,虽然我会说在通常情况下这是一个坏主意。 – 2011-04-08 07:15:13

+0

我真的希望有一个很好的解决方案。 – 2014-03-26 14:18:43

1

难道你不能以非递归方式编写makefile吗?

Recursive Make Considered Harmful

+0

我可以,但是我已经用它们的Makefile继承了所有这些模块,并且由于我很懒,我希望尽可能地重用它们.Makepp有一个很棒的工具(load_makefile),它将所有定义加载到Makefile中放置在给定的子目录中,将子目录前置到在那里定义的目标。我想知道是否有办法在Makefile中执行类似的操作,而不是复制各种Makefile中的所有目标,并手动添加子目录。 – akappa 2011-04-08 14:40:17

+1

@akappa,简短的回答:是的,但它不可靠。一个简短的'sed'脚本可以将目录名添加到目标文件中,但是如果makefile在任何地方都使用相对路径(并且makefile有很多种方法可以这样做),脚本将无法更正它们。 – Beta 2011-04-09 13:34:55

+0

@Beta:谢谢,我想我会写一个Makefile,毕竟它更容易(而且更简洁) – akappa 2011-04-10 21:21:47