1

我有这个简单的结构:

.
test.c
plugins/a.c
plugins/b.c
plugins/c.c

我正在用 bash 脚本编译它:

gcc -o test test.c -std=gnu99 -ldl -Wl,--export-dynamic

gcc -c plugins/a.c -o plugins/a.o -pedantic -g -Wall -std=c99 -fpic -I.
gcc plugins/a.o -o plugins/a.so  -shared

...same for b and c...

无论如何,我想将它移植到 Makefile。这是我所拥有的:

CC          =   gcc

PLUGIN_DIR  =   plugins
PLUGINS_C   =   $(wildcard $(PLUGIN_DIR)/*.c)
PLUGINS_O   =   $(patsubst %.c,%.o, $(PLUGINS_C))

new: clean all

all: test plugins

test: test.o
    $(CC) -o $@ $^ -std=gnu99 -ldl -Wl,--export-dynamic

plugins:
    ???

$(PLUGIN_DIR)/*.c:
    $(CC) -c $(PLUGIN_DIR)/$@ $^ -pedantic -g -Wall -std=c99 -fpic -I.

$(PLUGIN_DIR)/*.o:
    $(CC) $@ $^ -shared

clean:
    rm -rf test *.o *.a plugins/*.o plugins/*.so

但这不起作用,因为plugins规则是空的,我真的不知道我应该在那里写什么来使它编译plugins文件夹内的所有插件。另外,我不确定我是否把事情搞砸了$@and $^

4

1 回答 1

2

在我们回答您的问题之前,您的 makefile 存在许多问题。

规则目标中的通配符%不是*(在类似 your 的行中$(PLUGIN_DIR)/*.c:)。

规则指定如何构建由目标/目标模式命名的文件。因此,您的%.c规则是告诉 make 如何构建 .c 文件(我相信您会同意)并不是您的意思。(同样,您的%.o规则是告诉 make 如何构建 .o 文件)。

您没有为构建规则列出任何先决条件(目标行的右侧:),因此 make 无法智能地重建目标,因为它们的先决条件已更改(并且永远不会重建它们)。

要解决您的问题,您可能不希望插件目标的主体中包含任何内容。相反,您希望列出所需的插件输出文件(.so 文件)作为plugins目标的先决条件。(您还需要包含.PHONY: plugins在您的 makefile 中,以告诉 make 这plugins不是一个真实的文件,而是一个虚假的目标。)

您的%.so规则希望更像:

$(PLUGINS_DIR)/%.so: $(PLUGINS_DIR)/%.o
        $(CC) $^ -o $@ -shared

并且您的%.o规则希望更像:

$(PLUGINS_DIR)/%.o: $(PLUGINS_DIR)/%.c
        $(CC) -c $< -o $@ -pedantic -g -Wall -std=c99 -fpic -I.
于 2013-11-10T18:36:50.057 回答