gnu-makepgimakefile

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


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


Solution

  • You have a simple typo in $(SRCDIR): the source directory inside Eigensolver_gpu is called lib_eigsolve not lib_eigesolve.

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

    I then proceeded to create a dummy makefile by copy & pasting the relevant lines from your question:

    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 $@ $^
    

    Test runs:

    $ 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.