当我运行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)部分移走?
答案 0 :(得分:4)
请勿使用$?
。这将扩展到比目标新新的文件列表。您不能仅从更改的文件中构建可执行文件:您必须从 all 个文件中构建可执行文件。
您想在此处使用$^
。
真的,给定这个makefile,使用make
是没有意义的;它总是每次都运行相同的东西,除非根本没有更改任何源文件。您拥有的东西几乎比Shell脚本要好。