与Makefile中的变量扩展混淆

时间:2012-10-12 23:32:22

标签: c++ makefile

我有以下hypthetical 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生成的,但这是遗漏的,实际上可能是多个统一对象文件。

我的设计是否失败?我是否不得不求助于递归制作才能实现这一目标?

3 个答案:

答案 0 :(得分:1)

你做不到。因为通常可能需要构建多个目标。在命令行上,或作为中间目标。 因此设置变量将是不明确的。鉴于此,目标特定变量的值“仅在目标的命令脚本(以及其他特定于目标的分配)的上下文中可用。” (参见文件:make.info,节点:特定于目标)

但是你可以检查MAKECMDGOALS变量。

答案 1 :(得分:1)

您遇到的问题是,当makefile为READ时,RULES中的变量(目标和依赖项列表)会被扩展,而为目标设置的变量(如上面的$(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

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

答案 2 :(得分:0)

根据执行的make目标,你不能使用$ SOURCE表示不同的东西。 你可以在这里很好地理解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 ...