【问题标题】:Makefile for plugins compilation插件编译的 Makefile
【发布时间】:2013-11-10 18:23:26
【问题描述】:

我有这个简单的结构:

.
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 文件夹中的所有插件。 另外,我不确定我是否把$@ 和$^ 搞砸了。

【问题讨论】:

    标签: c bash makefile


    【解决方案1】:

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

    规则目标中的通配符是 % 而不是 *(在您的 $(PLUGIN_DIR)/*.c: 这样的行中)。

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

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

    要回答您的问题,您可能不希望插件目标的主体中包含任何内容。相反,您希望列出所需的插件输出文件(.so 文件)作为plugins 目标的先决条件。 (您还需要在您的 makefile 中包含 .PHONY: plugins 以告诉 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.
    

    【讨论】:

    • 但我确实想告诉 Makefile 应该如何在 plugins 目录中编译我的文件。 $(PLUGIN_DIR)/%.c: 规则不正是这样做的吗?这个怎么样:pastebin.com/tVSYSTUq?
    • $(PLUGIN_DIR)/%.c: 说“如果您需要知道如何创建与此模式匹配的文件,请按照以下规则进行操作”。但这不是规则正在做的事情。该规则使用现有 .c 文件来创建 和匹配的.o 文件。所以你的目标模式需要表明这一点。尝试在您的规则中添加先决条件条目以了解我的意思(以您的 test: test.o 规则为例。
    • 那个链接的makefile更好。它对plugins 目标具有合理的先决条件(尽管您确实不需要在先决条件列表中包含$(PLUGINS_C),因为它们应该是$(PLUGINS_O) 中文件的先决条件(它们目前不是),所以不应该t 需要特别列出)。
    • 您也根本不需要plugins 目标,因为如果您愿意,可以直接将$(PLUGINS_O) 作为all 目标的先决条件。
    • 还有一条评论。您可能希望在干净规则中使用 $(PLUGINS_O) 和 $(PLUGINS_SO) 而不是通配符。这样,它与 make 期望构建的内容相匹配,并且不会删除不相关的文件。
    猜你喜欢
    • 2012-10-08
    • 2016-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多