我正在努力让世界变得最简单(相对通用)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。我很困惑那里有什么问题。它可能很简单,但我现在似乎是盲目的。
答案 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.c
,bar.c
和baz.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/开始,可能(或可能不)有用。