1

我有以下假设的 Makefile:

all: SOURCE = $(wildcard src/*.cpp)
unity: SOURCE = $(wildcard unity/*.cpp)

OBJECTS = $(SOURCE:.cpp=.o)

all: prog

unity: prog

prog: $(OBJECTS)
    $(CXX) $(OBJECTS) -o prog

我需要根据初始目标使用不同的源文件/对象进行编译。在我看来,变量扩展在依赖项上比在目标主体中发生得更早,因为上面的编译器命令用正确的文件名调用就好了,但是 prog 依赖项中的 $OBJECTS 仍然是空的,所以没有一个对象被建成。

unity 文件夹包含一个组合源文件,其中包含用于进行统一构建的所有其他源文件。这个统一文件是由 makefile 生成的,但它被忽略了,实际上可能是多个统一目标文件。

我的设计是失败的原因吗?我是否将不得不求助于递归 make 来实现这一目标?

4

3 回答 3

1

你不能那样做。因为一般来说,可能有多个目标需要构建。在命令行上,或作为中间目标。因此,设置变量将是模棱两可的。因此,目标特定变量的值“仅在目标命令脚本的上下文中可用(以及在其他目标特定分配中)。” (参见文件:make.info,节点:特定于目标)

但是您可以检查 MAKECMDGOALS 变量。

于 2012-10-12T23:44:16.563 回答
1

您遇到的问题是 RULES 中的变量(目标和依赖项列表)在生成文件为 READ 时被扩展,而为目标设置的变量(如上面的 $(SOURCES))仅在触发 taget 时设置。这意味着特定于目标的变量仅在 ACTIONS 中有用,因为这是设置它们后唯一发生的事情。

综上所述,你可以通过递归调用 make 来获得你想要的效果:

all:
        $(MAKE) SOURCE="$(wildcard src/*.cpp)" prog
unity:
        $(MAKE) SOURCE="$(wildcard unity/*.cpp)" prog

OBJECTS = $(SOURCE:.cpp=.o)

prog: $(OBJECTS)
        $(CXX) $(OBJECTS) -o prog

.PHONY: all unity

但这不是我通常会推荐的。

于 2012-10-13T02:49:00.497 回答
0

您不能使用 $SOURCE 来表示不同的东西,具体取决于执行的 make 目标。您可以在这里很好地理解 makefile 解析: http ://www.gnu.org/software/make/manual/make.html#Reading-Makefiles

对于您的问题,您必须为每种类型的源文件定义不同的变量。例如:

all: SOURCE_ALL = $(wildcard src/*.cpp)
unity: SOURCE_UNITY = $(wildcard unity/*.cpp)

OBJECTS_ALL = $(SOURCE_ALL:.cpp=.o)
OBJECTS_UNITY = $(SOURCE_UNITY:.cpp=.o)
etc ...
于 2012-10-13T00:23:19.307 回答