如何在 Makefile 中使用 notdir、通配符和 patsubst?
How to use notdir, wildcard and patsubst in a 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
这个 makefile 编译得非常好,但是我基本上想用 # 取消对行的注释以使其更简单,但是当我这样做时只
ar rcs lib_eigsolve.a
出现在终端,没有创建目标文件,因此lib_eigsolve.a是空的...
为什么不编译目标文件?
P.S。您可以在此处找到经过一些修改的 Makefile https://github.com/NVIDIA/Eigensolver_gpu
确保 $(SRCDIR) 没有空格:
SRCDIR := $(strip ${SRCDIR})
ifneq (1,$(words ${SRCDIR}))
$(error Not without further fiddling, friend)
endif
在通配符表达式中指定路径看起来很奇怪。当你直接在srcdir(make -C lib_eigsolve
)中执行make时,你应该写
F90SRC = $(notdir $(wildcard *.F90))
或
srcdir = .
F90SRC = $(notdir $(wildcard ${srcdir}/*.F90))
当您想保留树外构建的选项时。
您在 $(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.
我有以下生成文件:
#.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
这个 makefile 编译得非常好,但是我基本上想用 # 取消对行的注释以使其更简单,但是当我这样做时只
ar rcs lib_eigsolve.a
出现在终端,没有创建目标文件,因此lib_eigsolve.a是空的... 为什么不编译目标文件?
P.S。您可以在此处找到经过一些修改的 Makefile https://github.com/NVIDIA/Eigensolver_gpu
确保 $(SRCDIR) 没有空格:
SRCDIR := $(strip ${SRCDIR})
ifneq (1,$(words ${SRCDIR}))
$(error Not without further fiddling, friend)
endif
在通配符表达式中指定路径看起来很奇怪。当你直接在srcdir(make -C lib_eigsolve
)中执行make时,你应该写
F90SRC = $(notdir $(wildcard *.F90))
或
srcdir = .
F90SRC = $(notdir $(wildcard ${srcdir}/*.F90))
当您想保留树外构建的选项时。
您在 $(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.