Linux make第一次运行失败,第二次运行成功

时间:2019-12-03 16:40:58

标签: c linux makefile cc

当我运行make时,第一次运行总是以Error 1失败,但是第二次运行按预期进行编译。

第一次运行会产生以下命令:

cc -g -I../../../../include -I../../../../include/sdk/ctree.ctdb/multithreaded/static -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -ldl -o ../project42 ../project42.c -L../../../../lib/ctree.ctdb/multithreaded/static -lmtclient -lpthread -ldl -lm -lglib-2.0

第二次运行会产生以下命令(注意包含csvparser.c和nxjson.c):

cc -g -I../../../../include -I../../../../include/sdk/ctree.ctdb/multithreaded/static -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -ldl -o ../project42 ../csvparser.c ../nxjson.c ../project42.c -L../../../../lib/ctree.ctdb/multithreaded/static -lmtclient -lpthread -ldl -lm -lglib-2.0

Makefile如下:

ACEBASEDIR=../../../..
APIDIR=ctree.ctdb/multithreaded/static
GLIBINC=$(shell pkg-config --cflags glib-2.0 | xargs)
INCDIRS=-I$(ACEBASEDIR)/include -I$(ACEBASEDIR)/include/sdk/$(APIDIR) $(GLIBINC)
CFLAGS=-g $(INCDIRS) -ldl -o $@
LIBDIRS=-L$(ACEBASEDIR)/lib/$(APIDIR)
SYSLIBS=-lpthread -ldl -lm -lglib-2.0
SRCDIR=..
OUTDIR=..
$(OUTDIR)/project42: $(SRCDIR)/csvparser.c $(SRCDIR)/nxjson.c $(SRCDIR)/project42.c
    cc $(CFLAGS) $? $(LIBDIRS) -lmtclient $(SYSLIBS)
clean:
    rm -f $(OUTDIR)/project42

当我展开命令时,我得到了:

cc -g -I../../../../include -I../../../../include/sdk/ctree.ctdb/multithreaded/static $(shell pkg-config --cflags glib-2.0 | xargs) -ldl -o $@ $? -L../../../../lib/ctree.ctdb/multithreaded/static -lmtclient -lpthread -ldl -lm -lglib-2.0

运行pkg-config --cflags glib-2.0 | xargs返回-I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include

对我来说,问题似乎出在$?变量kindly described here上。在第一次运行时,它似乎只能解析为../project42.c而不是../csvparser.c ../nxjson.c ../project42.c

我怀疑我的机器出现了故障,并且在第一次运行时就被缓存了,但是只有在此之后才需要。

我需要在Makefile中进行哪些更改才能使编译第一次生效?我是否需要先将-L(LIBDIRS)部分移走?

1 个答案:

答案 0 :(得分:4)

请勿使用$?。这将扩展到比目标新的文件列表。您不能仅从更改的文件中构建可执行文件:您必须从 all 个文件中构建可执行文件。

您想在此处使用$^

真的,给定这个makefile,使用make是没有意义的;它总是每次都运行相同的东西,除非根本没有更改任何源文件。您拥有的东西几乎比Shell脚本要好。