How to use notdir, wildcard and patsubst in a Makefile?

时间:2019-03-17 22:28:49

标签: makefile gnu-make pgi makefile-errors

I have the following makefile:

#.SUFFIXES:
#.SUFFIXES: .F90 .cuf .o

ROOT = /home/ccevallos/finalMIT

SRCDIR := $(ROOT)/external/lib_eigesolve

#F90SRC = $(notdir $(wildcard $(SRCDIR)/*.F90))
#F90OBJS = $(patsubst %.F90,%.o,$(F90SRC))
F90OBJS = eigsolve_vars.o toolbox.o zhegst_gpu.o zhemv_gpu.o zhetd2_gpu.o zhetrd_gpu.o zheevd_gpu.o zhegvdx_gpu.o \
          dsygst_gpu.o dsymv_gpu.o dsytd2_gpu.o dsytrd_gpu.o dsyevd_gpu.o dsygvdx_gpu.o
#CUFSRC = $(notdir $(wildcard $(SRCDIR)/*.cuf))
#CUFOBJS = $(patsubst %.cuf,%.o,$(CUFSRC))
CUFOBJS = cusolverDn_m.o

FLAGS = -O3 -mp -pgf90libs -Mcuda=cc60,cuda9.1,ptxinfo -Mlarge_arrays
FLAGS2 = -O3 -mp -pgf90libs -Mcuda=cc60,cuda9.1,ptxinfo,maxregcount:64 -Mlarge_arrays
FLAGS3 = -O3 -mp -pgf90libs -Mcuda=cc60,cuda9.1,ptxinfo,nordc,maxregcount:255  -Mlarge_arrays

.PHONY: all
all: lib_eigsolve.a

zhetd2_gpu.o : zhetd2_gpu.F90
    pgf90 -c ${FLAGS2} ${OPTFLAGS} $*.F90 -o $*.o 
zhemv_gpu.o : zhemv_gpu.F90
    pgf90 -c ${FLAGS3} ${OPTFLAGS} $*.F90 -o $*.o
dsytd2_gpu.o : dsytd2_gpu.F90
    pgf90 -c ${FLAGS2} ${OPTFLAGS} $*.F90 -o $*.o
dsymv_gpu.o : dsymv_gpu.F90
    pgf90 -c ${FLAGS3} ${OPTFLAGS} $*.F90 -o $*.o
cusolverDn_m.o: cusolverDn_m.cuf
    pgf90 -c ${FLAGS}  ${OPTFLAGS} $*.cuf -o $*.o
%.o: %.F90
    pgf90 -c ${FLAGS}  ${OPTFLAGS} $*.F90 -o $*.o

lib_eigsolve.a: $(F90OBJS) $(CUFOBJS)
    ar rcs $@ $^


PHONY: clean
clean:
    rm -f lib_eigsolve.a *.mod *.o

This makefile compiles perfectly well, however I basically want to uncomment the lines with # to make this simpler, but when I do that only

ar rcs lib_eigsolve.a 

appears in the terminal, with no object file created, and thus lib_eigsolve.a is empty... Why is it not compiling the object files?

P.S. You can find this Makefile with some modifications here https://github.com/NVIDIA/Eigensolver_gpu

3 个答案:

答案 0 :(得分:2)

您在$(SRCDIR)中有一个简单的错字:Eigensolver_gpu中的源目录称为lib_eigsolve而不是lib_eigesolve

$ cd ~workarea/playground
$ git clone https://github.com/NVIDIA/Eigensolver_gpu.git
$ ls Eigensolver_gpu/
lib_eigsolve  LICENSE  README.md  test_driver

然后我通过复制并粘贴您问题中的相关行来创建虚拟的makefile:

ROOT   := $(HOME)/workarea/playground/Eigensolver_gpu
ifndef FIXED
    SRCDIR := $(ROOT)/lib_eigesolve
else
    SRCDIR := $(ROOT)/lib_eigsolve
endif

F90SRC = $(notdir $(wildcard $(SRCDIR)/*.F90))
$(info F90SRC '$(F90SRC)')
F90OBJS = $(patsubst %.F90,%.o,$(F90SRC))
$(info F90OBJS '$(F90OBJS)')

CUFSRC = $(notdir $(wildcard $(SRCDIR)/*.cuf))
$(info CUFSRC '$(CUFSRC)')
CUFOBJS = $(patsubst %.cuf,%.o,$(CUFSRC))
$(info CUFOBJS '$(CUFOBJS)')

lib_eigsolve.a: $(F90OBJS) $(CUFOBJS)
    echo ar rcs $@ $^

测试运行:

$ make
F90SRC ''
F90OBJS ''
CUFSRC ''
CUFOBJS ''
echo ar rcs lib_eigsolve.a 
ar rcs lib_eigsolve.a

$ make FIXED=1
F90SRC 'dsyevd_gpu.F90 ... zhemv_gpu.F90'
F90OBJS 'dsyevd_gpu.o ... zhemv_gpu.o'
CUFSRC 'cusolverDn_m.cuf'
CUFOBJS 'cusolverDn_m.o'
make: *** No rule to make target 'dsyevd_gpu.o', needed by 'lib_eigsolve.a'.  Stop.

答案 1 :(得分:0)

确保$(SRCDIR)没有空格:

SRCDIR := $(strip ${SRCDIR})
ifneq (1,$(words ${SRCDIR}))
  $(error Not without further fiddling, friend)
endif

答案 2 :(得分:0)

在通配符表达式中指定路径看起来很奇怪。直接在srcdir(make -C lib_eigsolve)中执行make时,应编写

F90SRC = $(notdir $(wildcard *.F90))

srcdir = .
F90SRC = $(notdir $(wildcard ${srcdir}/*.F90))

当您希望保留针对树外构建的选项时。