makefile 中无法识别规则?

Rule not recognized in makefile?

我有一个基本的 makefile 来编译编译共享库所需的 C 文件,我有一个错误,因为 makefile 无法识别:

 SOURCES=/home/test/project/sources
 OBJECTS=/home/test/project/objects

 $(OBJECTS)/%.o:$(SOURCES)/%.c
 $(CC) -fPIC -c $^ -o $@

 sharedlib: $(OBJECTS)/%.o
 $(CC) -shared -o libsharedlib.so $<

当我 运行 make 时,我发现目标没有规则:sharedlib 需要 $(OBJECTS)/%.o。虽然规则写在 sharedlib 之前。

主要问题是您无处明确告诉make您的源文件是什么。从这样做开始:

SOURCEDIR=/home/test/project/sources
SOURCES=$(wildcard $(SOURCEDIR)/*.c)

然后,通过用 .c 代替 .o 来从源文件名派生目标文件名:

OBJECTDIR=/home/test/project/objects
OBJECTS=$(patsubst $(SOURCEDIR)/%.c,$(OBJECTDIR)/%.o,$(SOURCES))

您仍然可以保留构建目标文件的通用规则:

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.c
        $(CC) -fPIC -c $^ -o $@

但是您将目标文件的显式列表提供给要制定的规则 sharedlib:

libsharedlib.so: $(OBJECTS)
        $(CC) -shared -o $@ $<

请注意,我将规则的名称设置为与正在生成的文件相同的名称。这很重要,因为连续两次调用 make 将跳过第二次构建库。如果需要,您可以随时添加别名:

sharedlib: libsharedlib.so

在那种情况下,告诉 make sharedlib 不是真实文件也很好:

.PHONY sharedlib

如果目录中确实有一个名为 sharedlib 的文件,这可以防止奇怪的事情发生。

图书馆规则

sharedlib: $(OBJECTS)/%.o

不足以告诉 Make 库需要哪些 objs。

这应该有效,并且可以明确控制库中你想要的 sources/objs 对:

SOURCESDIR=/home/test/project/sources
OBJECTDIR=/home/test/project/objects

OBJLIST = \
    $(OBJECTS)/file1.o \
    $(OBJECTS)/file2.o

$(OBJECTDIR)/%.o: $(SOURCESDIR)/%.c
    $(CC) -fPIC -c $^ -o $@

sharedlib: $(OBJLIST)
    $(CC) -shared -o libsharedlib.so $<