Newbie makefile question

Hi all,

I’m retooling a program for CUDA but just discovered that I have no experience with makefiles which is less than I need. So my problem is that ‘make all’ does not recognize .cu files. I’ve set the default compiler to nvcc but it’s still not reading files appropriately (make[1]: *** No rule to make target file.o', needed by compile’. Stop.). That error happens when I change a file that I was going to leave as .C to .cu – it compiles fine before. So lets assume the file structure is src/extras, with file.o being in extras. There’s a makefile in src and another in extras, created by ./configure from Makefile.in templates. Here are what I think are the relevant parts of each:

/src/Makefile

#object files

EXTRAS_OBJ = extras/file.o \

#macro definitions

BIN = ${EXEDIR}folder

EXEDIR = ../bin/

SRC = $(ALL_OBJ:.o=.c)

#implicit rules

.c.o:

	${CC} ${CFLAGS} -c $<

#targets

all:	compile

.PHONY: compile

compile: ${BIN}

${BIN}: ${ALL_OBJ}

	${LDR} $(OPT) -o ${EXEDIR}folder ${ALL_OBJ} ${LIB}

/src/extras/Makefile

#object files

CORE_OBJ = extras.o \

OBJ = $(CORE_OBJ)

#macro definitions

SRC = $(OBJ:.o=.c)

#implicit rules

.c.o:

	${CC} ${CFLAGS} -c $<

#targets

all:	compile

.PHONY: compile

compile: ${OBJ}

I’ve tried adding

%.cu.o: %.cu

  $(NVCC) $(NVCCFLAGS) -c $< -o

To implicit rules in both files (with and without the percent signs)

and

SRC = $(OBJ:.o=.cu)

to macro definitions. All that I can change is that when I add the .cu implicit rule to both files (with or without percent signs) the error changes to ‘Makefile:36: *** missing separator. Stop.’ where line 36 is $(NVCC) $(NVCCFLAGS) -c $< -o in src/extras/Makefile.

I’m not sure where to go with this; any help would be greatly appreciated.

Thanks!

S

That’s the right approach. The trick is that the second line needs to start with a tab, no spaces.

That’s obviously only going to work if you rename all .c files to .cu. If you keep some .c files, you can take the opposite approach and derive $(OBJ) from $(SRC).

I fixed the spaces/tabs problem but that just returned my error to ‘*** No rule to make target file.o', needed by compile’.’

I’m not sure what you meant by reversing the derivation (I really am completely new to makefiles) so I tried to do it more explicitly (assuming two files in /src/extras, file.cu and regularfile.c):

regularfile.o : regularfile.c

	$(CC) $(CFLAGS) –c $(.SOURCE) 

file.o : file.cu

	$(NVCC) $(NVCCFLAGS) –c $(.SOURCE)

I left

%.cu.o: %.cu

	$(NVCC) $(NVCCFLAGS) -c $< -o $@

but deleted

SRC = $(OBJ:.o=.cu)

.

I now get

make[1]: Entering directory `/src/extras’

make[1]: Circular file.cu.o ← file.cu dependency dropped.

c

make[1]: c: Command not found

make[1]: [file.o] Error 127 (ignored)

nvcc -O3 -c

nvcc fatal : No input files specified; use option --help for more information

make[1]: *** [regularfile.o] Error 255

make[1]: Leaving directory `/src/extras’

make: *** [compile] Error 2

This error recurs for various permutations of having and not having ‘-c’ for NVCC and CC in those definitions above. EDIT: I mention this because I sometimes also get an error from nvcc not recognizing ‘-c’, but just this second I’m having trouble reproducing it so maybe that’s no longer a problem.

Thanks again

Ah yes. That is because the extension for object files is .cu.o in some places and .o in others. Either name the file as file.cu.o in $(OBJ), or change the CUDA rule to

%.o: %.cu

	$(NVCC) $(NVCCFLAGS) -c $< -o $@

(you may drop the “-o $@” in that case because it’s the default)

Sorry, my explanation was a bit short as I was in a hurry. Suppose your source files are a.c, b.c, c.cu, and d.cu. Then writing

OBJ = a.o b.o c.o d.o

SRC = $(OBJ:.o=.cu)

obviously would not work, but you could write

SRC_C = a.c b.c

SRC_CU = c.cu d.cu

SRC = $(SRC_C) $(SRC_CU)

OBJ = $(SRC_C:.c=.o) $(SRC_CU:.cu=.o)