测试 Makefile 中除了 clean 规则之外的所有变量设置的有效/正确方法是什么?

问题描述 投票:0回答:1

我想创建一个 Makefile 来强制设置变量(如果不正确则失败)。

已阅读 从命令行传递附加变量到 makeMakefile -- 如果未设置变量则出错如果未设置变量如何中止 makefile?目标内 Makefile 中的条件,我知道有两个明显的选择:

make
条件函数,例如
$(if condition,then-part[,else-part])
,以及“全局”条件,例如
ifndef variable-name

我的理解是,全局条件实际上是这样的:

.PHONY: all, clean

OBJS=lorem.o ipsum.o

ifndef LIBUV_LIB
$(error LIBUV_LIB not set)
endif

all: liblorem.so libipsum.so

liblorem.so: lorem.o
        $(CC) -shared -o $@ $^ -L $(LIBUV_LIB) -luv

libipsum.so: ipsum.o
        $(CC) -shared -o $@ $^ -L $(LIBUV_LIB) -luv

clean:
        rm -f $(OBJS) liblorem.so libipsum.so

...即

LIBUV_LIB
的存在是“全局”评估的,我可以通过将其作为
make
参数传递来设置它:

$ make
Makefile:6: *** LIBUV_LIB not set.  Stop.
$
$ make LIBUV_LIB=/usr/local/libuv1.45.0
cc    -c -o lorem.o lorem.c
cc -shared -o liblorem.so lorem.o -L /usr/local/libuv1.45.0 -luv
cc    -c -o ipsum.o ipsum.c
cc -shared -o libipsum.so ipsum.o -L /usr/local/libuv1.45.0 -luv
$

这完成了工作,它只是有一个恼人的效果,需要为

clean
目标进行设置,而它并不真正相关:

$ make clean
Makefile:6: *** LIBUV_LIB not set.  Stop.
$ make LIBUV_LIB=/usr/local/libuv1.45.0 clean
rm -f lorem.o ipsum.o liblorem.so libipsum.so
$

探索条件函数,我想出了这个Makefile:

.PHONY: all, clean

OBJS=lorem.o ipsum.o

all: liblorem.so libipsum.so

liblorem.so: lorem.o
        $(if $(LIBUV_LIB),,$(error LIBUV_LIB not set))
        $(CC) -shared -o $@ $^ -L $(LIBUV_LIB) -luv

libipsum.so: ipsum.o
        $(if $(LIBUV_LIB),,$(error LIBUV_LIB not set))
        $(CC) -shared -o $@ $^ -L $(LIBUV_LIB) -luv

clean:
        rm -f $(OBJS) liblorem.so libipsum.so

这也能完成工作:

$ make
cc    -c -o lorem.o lorem.c
Makefile:8: *** LIBUV_LIB not set.  Stop.
$
$ make LIBUV_LIB=/usr/local/libuv1.45.0
cc -shared -o liblorem.so lorem.o -L /usr/local/libuv1.45.0 -luv
cc    -c -o ipsum.o ipsum.c
cc -shared -o libipsum.so ipsum.o -L /usr/local/libuv1.45.0 -luv
$

...但似乎需要为

LIBUV_LIB
目标指定
clean
来规避我的不满:

$ make clean
rm -f lorem.o ipsum.o liblorem.so libipsum.so
$

我现在的抱怨是重复

$(if $(LIBUV_LIB),,$(error LIBUV_LIB not set))
声明,因为这感觉像是违反了 DRY 原则

我的问题是:是否有一种(n)(惯用的)方法来编写一个Makefile,强制(如果不正确则失败)为除

clean
目标之外的所有目标设置变量?

makefile gnu-make
1个回答
0
投票

您可以通过查看

$(MAKECMDGOALS)
变量来检查调用了哪些目标。如果指定了除 clean 以外的任何目标
other
,您可能希望失败,因为您想要正确处理诸如
make clean all
之类的事情。

所以你可以这样做:

ifndef LIBUV_LIB
  ifneq ($(MAKECMDGOALS),clean)
    $(error LIBUV_LIB not set)
  endif
endif
© www.soinside.com 2019 - 2024. All rights reserved.