根据目标定义变量

时间:2013-03-15 17:19:32

标签: makefile gnu-make

我有一个看起来像的Makefile:

gator: LIB=-lm
gatorgpu : GPU=-DG

 ....
STATIC=
ifdef STATIC
  $(info CPU static)    
endif

但我希望有类似的东西:

gator: LIB=-lm
gatorgpu : GPU=-DG

 ....
STATIC=
ifdef STATIC
   ifdef GPU
     $(info GPU static) 
   else
    $(info CPU static)
   endif
 endif

因此,当某人键入$make gatorgpu STATIC=1$make gator STATIC=1时,它将使用静态库进行编译,具体取决于目标,在本例中为CPU或GPU。遗憾的是,STATIC被读取,但GPU变量不是,因此它始终用于CPU static。有一种优雅的方式吗?

2 个答案:

答案 0 :(得分:1)

根据您的描述,我会说可以使用以下方法:

ifdef STATIC
gator: LIB:=-static -lstaticlib
gatorgpu: GPU:=-DSTATICDEF
else
gator: LIB:=-lm
gatorgpu: GPU:=-DG
endif

在定义STATIC与未定义时,您还没有明确说明要使用或更改的选项,因此我已经编写了一些示例值。

答案 1 :(得分:1)

目标特定变量仅在相应的配方中可用。不同的目标可以为其配方使用相同变量的不同版本。

虽然如果您决定使用目标特定变量来实现您要做的任何事情,那么这将有效:

gator: export LIB := -lm
gatorgpu : export GPU := -DG
STATIC ?= 0
ACTUAL ?= 0

export STATIC

ifeq ($(ACTUAL),1)
ifeq ($(STATIC), 1)
    ifneq ($(GPU),)
        $(info GPU static) 
    else
        $(info CPU static)
    endif
endif
endif

.gator:
    @echo LIB=$(LIB) GPU=$(GPU)

.gatorgpu:
    @echo LIB=$(LIB) GPU=$(GPU)

gator:
    @$(MAKE) .gator ACTUAL=1

gatorgpu:
    @$(MAKE) .gatorgpu ACTUAL=1

PHONY: .gator .gatorgpu gator gatorgpu
  • 这有使用正确的导出变量集调用额外的make(每个目标)的开销。
  • 导出可确保为从make运行的任何子流程设置变量。

这是我看到的结果:

$ make gatorgpu
make[1]: Entering directory `/home/ash/.scratch/make-test'
LIB= GPU=-DG
make[1]: Leaving directory `/home/ash/.scratch/make-test'

$ make gator
make[1]: Entering directory `/home/ash/.scratch/make-test'
LIB=-lm GPU=
make[1]: Leaving directory `/home/ash/.scratch/make-test'

$ make gatorgpu STATIC=1
GPU static
make[1]: Entering directory `/home/ash/.scratch/make-test'
LIB= GPU=-DG
make[1]: Leaving directory `/home/ash/.scratch/make-test'

$ make gator STATIC=1
CPU static
make[1]: Entering directory `/home/ash/.scratch/make-test'
LIB=-lm GPU=
make[1]: Leaving directory `/home/ash/.scratch/make-test'

一些小的修正,虽然它不会对结果产生太大影响:

  • ?=(称为conditional variable assignment operator)仅在未分配变量时执行赋值。因此,当您运行make mytarget STATIC=1时,不会为变量STATIC分配0
  • ifeq相比,
  • ifneqifdef是更健全的检查,因为您可以将变量与您感兴趣的特定值进行比较。
  • :=应优先于常规=,以避免不必要的制作减速,除非您确实需要recursively expanded variables

更好的方法是重构您的Makefile,以便根据STATIC

的值定义不同的特定于目标的变量或规则
ifeq ($(STATIC), 1)
gator: LIB := -lm
gatorgpu : GPU := -DG
else
gator: LIB := <SOMETHING_ELSE_HERE>
gatorgpu : GPU := <SOMETHING_ELSE_HERE>
endif

还有一种不太推荐的方法,涉及检查$(MAKECMDGOALS)的值,其中包含调用make的目标。

ifeq ($(MAKECMDGOALS),gatorgpu)
    GPU := -DG
endif