Makefile没有看到我的隐式规则

时间:2017-01-05 21:42:05

标签: makefile gnu-make

我正在努力让世界变得最简单(相对通用)Makefile。我可以用来驱动一小部分测试来学习C.出于某种原因,Makefile拒绝理解我的隐式规则,使目标文件形成c: %.o: %.c,我需要no rule to make target %.o { {1}}。以下是我test1.exe的全部内容:

Makefile

我使用INC = sglib CC = gcc LD = gcc LDFLAGS = # On MS-Windows, say "make os=win" to set proper extensions os = SO = EXE = ifeq ($(os), win) SO = dll EXE = .exe # -fPIC is a no-op on Windows, but causes a compiler warning CFLAGS = -std=gnu99 -ggdb3 -Wall else SO = so CFLAGS = -std=gnu99 -ggdb3 -Wall -fPIC endif all: test1$(EXE) test1$(EXE): %.o $(LD) $< -o $@ lib-test.$(SO): %.o $(LD) -shared $(LDFLAGS) -o $@ $< %.o: %.c $(CC) $(CFLAGS) -I$(INC) -c $< -o $@ check: echo Nothing yet! .PHONY: all clean clean: rm -f *.o *.$(SO) test1$(EXE) gnu make 4.2.1在Windows 20上使用msys。我很困惑那里有什么问题。它可能很简单,但我现在似乎是盲目的。

2 个答案:

答案 0 :(得分:3)

此:

test1$(EXE): %.o

定义了一条规则,规定目标test1的先决条件是文件%.o。不是一些通配符的目标文件列表。 具体名为%.o的文件。您的makefile中没有其他规则来创建该文件,并且它当前不存在,因此您会收到错误。

%仅作为Pattern Rules中的占位符(以及patsubst)等类似函数,这些是目标中出现%的规则。所以你的:

%.o : %.cpp
    $(CC) $(CFLAGS) -I$(INC) -c $< -o $@
由于%中的%.o

是一种模式规则。这不会创建构建目标%.o的规则,而是创建后缀为.o的任何文件。这在尝试构建目标foo.o时适用 - 我们使用preqrequiste foo.cpp创建隐式规则,其中%foo匹配。

您实际想要的是通配您的目标文件。它的功能是:

test1$(EXE) : $(wildcard *.o)

但这实际上也不起作用。当您第一次尝试构建时,还没有任何目标文件存在。显然。所以$(wildcard *.o)将返回一个空字符串,最后你会得到废话。所以你不能通配它们。您需要明确提供该字符串:

test1$(EXE) : $(object_files)
    $(LD) $< -o $@

现在我们只需提出该清单:

source_files := $(wildcard *.c)
object_files := $(source_files:.c=.o)

现在,如果您有foo.cbar.cbaz.c等源文件,$(wildcard)函数会找到它们并将source_files设置为{{1 }}。下一行的替换会将foo.c bar.c baz.c设置为object_files。因此,根据这三个目标文件,我们最终得到foo.o bar.o baz.o,并且您已经有了一个模式规则来构建这些目标文件。

答案 1 :(得分:0)

你似乎在想这样的规则:

 test1$(EXE): %.o

%符号是一个通配符,导致文件名扩展 - 它不是。如果要创建.o文件列表,则应使用内置的wildcard函数。

我有一些关于通用makefile的博客文章,从https://latedev.wordpress.com/2014/11/08/generic-makefiles-with-gcc-and-gnu-make/开始,可能(或可能不)有用。