Sto lavorando a un progetto che utilizza i file .c e .cu. Il pacchetto originale era interamente scritto in C e aveva il suo Makefile (funzionava perfettamente). Ho aggiunto il file .cu al progetto e ora voglio modificare il Makefile in modo che compili tutto insieme.Makefile per CUDA e C
Ecco il mio tentativo:
CC = nvcc
SOURCEDIR = ../sourcedir
EXE = it
#C_SOURCES = $(wildcard $(SOURCEDIR)/*.c)
#CU_SOURCES = $(wildcard $(SOURCEDIR)/*.cu)
SOURCES = $(SOURCEDIR)/it.c \
$(SOURCEDIR)/em.c \
$(SOURCEDIR)/art.c \
$(SOURCEDIR)/cg.c \
$(SOURCEDIR)/amatrix.c \
$(SOURCEDIR)/itreadargs.c \
$(SOURCEDIR)/sparse.c \
$(SOURCEDIR)/misc.c \
$(SOURCEDIR)/eval.c \
$(SOURCEDIR)/imgtools.c \
$(SOURCEDIR)/calc.c \
$(SOURCEDIR)/egif_lib.c \
$(SOURCEDIR)/dgif_lib.c \
$(SOURCEDIR)/gif_err.c \
$(SOURCEDIR)/gif_hash.c
CU_SOURCES = $(SOURCEDIR)/cg_cuda.cu
H_FILES = $(wildcard $(IDIR)/*.h)
IDIR = -I../include
OBJS = $(SOURCES:.c=.o)
CU_OBJS = $(CU_SOURCES:.cu=.o)
CFLAGS = -O3
#-finline-functions -Winline -Wall -falign-loops=2 -falign-jumps=2 -falign-functions=2 -Wstrict-prototypes
NVCCFLAGS = -arch=sm_20
#CFLAGS = -g -Wstrict-prototypes -Winline -Wall
LFLAGS = -lm
$(EXE) : $(OBJS) $(CU_OBJS)
$(CC) $(CFLAGS) $(NVCCFLAGS) -o [email protected] $?
$(SOURCEDIR)/%.o : $(SOURCEDIR)/%.c $(H_FILES)
$(CC) $(CFLAGS) $(IDIR) -c -o [email protected] $<
$(SOURCEDIR)/%.o : $(SOURCEDIR)/%.cu $(H_FILES)
$(CC) $(NVCCFLAGS) $(IDIR) -c -o [email protected] $<
clean:
rm -f $(OBJS) $(EXE)
La struttura del progetto è la seguente:
- Progetto
- includono
- sourcedir
- si
altre cartelle
dove includere ha tutti i file .he sourcedir ha il file .CU (c'è un solo file di .cu) .c e; it ha il Makefile.
Il problema con il mio Makefile è che quando faccio rendere nella cartella si ricevo un sacco di errori che mi dice che il file che ha la funzione main() (it.c in sourcedir cartella) non viene collegato a nessuna delle funzioni di altre librerie. Lo stesso vale per il mio file .cu.
Potete per favore darmi qualche suggerimento su cosa potrebbe essere sbagliato con il mio Makefile? Ho usato come riferimento il seguente post StackOverflow: makefile for C++/CUDA project
Grazie per il vostro aiuto,
Vlad
EDIT:
Ecco l'originale Makefile, quella che ha lavorato sui file .c. Puoi aiutarmi con quello che devo aggiungere in modo che il file .cu sia compilato insieme agli altri? Grazie ancora. EDIT
CC = gcc
SOURCEDIR = ../sourcedir
EXE = it
SOURCES = $(SOURCEDIR)/it.c \
$(SOURCEDIR)/em.c \
$(SOURCEDIR)/art.c \
$(SOURCEDIR)/cg.c \
$(SOURCEDIR)/amatrix.c \
$(SOURCEDIR)/itreadargs.c \
$(SOURCEDIR)/sparse.c \
$(SOURCEDIR)/misc.c \
$(SOURCEDIR)/eval.c \
$(SOURCEDIR)/imgtools.c \
$(SOURCEDIR)/calc.c \
$(SOURCEDIR)/egif_lib.c \
$(SOURCEDIR)/dgif_lib.c \
$(SOURCEDIR)/gif_err.c \
$(SOURCEDIR)/gif_hash.c
IDIR = -I../include
OBJS = $(SOURCES:.c=.o)
CFLAGS = -O3 -finline-functions -Winline -Wall -falign-loops=2 -falign-jumps=2 -falign-functions=2 -Wstrict-prototypes
#CFLAGS = -g -Wstrict-prototypes -Winline -Wall
LFLAGS = -lm
$(EXE) : $(OBJS)
$(CC) $(CFLAGS) -o $(EXE) $(OBJS) $(LFLAGS)
%.o : %.c
$(CC) -c $(IDIR) $(CFLAGS) $< -o [email protected]
clean:
rm -f $(OBJS) $(EXE)
DOPO:
ho cambiato il Makefile ancora un po ', ripulito un po', e ora ho solo un paio di errori che sono legati al fatto che il br non è sempre legata alla .c file e viceversa.
CC := gcc
SOURCEDIR := ../sourcedir
EXE := it
SOURCES := $(SOURCEDIR)/it.c \
$(SOURCEDIR)/em.c \
$(SOURCEDIR)/art.c \
$(SOURCEDIR)/cg.c \
$(SOURCEDIR)/amatrix.c \
$(SOURCEDIR)/itreadargs.c \
$(SOURCEDIR)/sparse.c \
$(SOURCEDIR)/misc.c \
$(SOURCEDIR)/eval.c \
$(SOURCEDIR)/imgtools.c \
$(SOURCEDIR)/calc.c \
$(SOURCEDIR)/egif_lib.c \
$(SOURCEDIR)/dgif_lib.c \
$(SOURCEDIR)/gif_err.c \
$(SOURCEDIR)/gif_hash.c
CU_SOURCES := $(SOURCEDIR)/cg_cuda.cu
IDIR := ../include
INCLUDES := -I../include
H_FILES := $(IDIR)/analyze.h \
$(IDIR)/calc.h \
$(IDIR)/eval.h \
$(IDIR)/gif_hash.h \
$(IDIR)/gif_lib.h \
$(IDIR)/imgtools.h \
$(IDIR)/iradon.h \
$(IDIR)/iradoninc.h \
$(IDIR)/it.h \
$(IDIR)/itini.h \
$(IDIR)/misc.h \
$(IDIR)/sparse.h
CFLAGS := -g -O3
NVCCFLAGS := -g -G -O3 -arch=sm_20
LDFLAGS := -lGL -lGLU -lglut -lpthread -lcuda
HOST_OBJ := $(SOURCES:.c=.c.o)
DEVICE_OBJ := $(CU_SOURCES:.cu=.cu.o)
%.c.o : %.c $(HFILES)
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o [email protected]
%.cu.o : %.cu $(H_FILES)
nvcc -c $(INCLUDES) $(NVFLAGS) $< -o [email protected]
$(EXE): $(HOST_OBJ) $(DEVICE_OBJ)
nvcc $(NVFLAGS) $(LDFLAGS) $(INCLUDES) -o [email protected] $^
clean:
rm -f $(OBJS) $(EXE)
Così ora sto ottenendo questi errori:
nvcc -lGL -lGLU -lglut -lpthread -lcuda -I../include -o it ../sourcedir/it.c.o ../sourcedir/em.c.o ../sourcedir/art.c.o ../sourcedir/cg.c.o ../sourcedir/amatrix.c.o ../sourcedir/itreadargs.c.o ../sourcedir/sparse.c.o ../sourcedir/misc.c.o ../sourcedir/eval.c.o ../sourcedir/imgtools.c.o ../sourcedir/calc.c.o ../sourcedir/egif_lib.c.o ../sourcedir/dgif_lib.c.o ../sourcedir/gif_err.c.o ../sourcedir/gif_hash.c.o ../sourcedir/cg_cuda.cu.o
../sourcedir/it.c.o: In function `main':
/home/vburca/CUDA_Research_2012/Recon2D/it/../sourcedir/it.c:280: undefined reference to `CG_CUDA'
../sourcedir/cg_cuda.cu.o: In function `CGUpdateAddVector(Vector*, Vector*, Vector*, float)':
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x44): undefined reference to `Error(char*, ...)'
../sourcedir/cg_cuda.cu.o: In function `CG_CUDA(SparseMatrix*, Vector*, Vector*)':
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x15f): undefined reference to `Print(int, char*, ...)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x18c): undefined reference to `ReadFIF(char*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x1a2): undefined reference to `ImageToVector(Image*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x1b8): undefined reference to `FreeImage(Image*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x1c7): undefined reference to `DeviationVector(Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x248): undefined reference to `Print(int, char*, ...)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x255): undefined reference to `InitVector(int)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x269): undefined reference to `InitVector(int)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x27d): undefined reference to `InitVector(int)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x291): undefined reference to `InitVector(int)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x2a5): undefined reference to `InitVector(int)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x2c0): undefined reference to `Print(int, char*, ...)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x2e0): undefined reference to `MultSparseMatrixVector(SparseMatrix*, Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x328): undefined reference to `MultSparseTMatrixVector(SparseMatrix*, Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x37c): undefined reference to `MultSparseMatrixVector(SparseMatrix*, Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x395): undefined reference to `MultVectorVector(Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x3b1): undefined reference to `Print(int, char*, ...)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x3fb): undefined reference to `Print(int, char*, ...)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x414): undefined reference to `MultVectorVector(Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x47b): undefined reference to `ConstrainVector(Vector*, float, float)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x4ce): undefined reference to `MultSparseTMatrixVector(SparseMatrix*, Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x4e7): undefined reference to `MultVectorVector(Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x55b): undefined reference to `MultSparseMatrixVector(SparseMatrix*, Vector*, Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x581): undefined reference to `SaveIteration(Vector*, int, char*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x5ab): undefined reference to `L2NormVector(Vector*, Vector*, float)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x602): undefined reference to `Print(int, char*, ...)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x61f): undefined reference to `VectorToImage(Vector*, int, int)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x650): undefined reference to `L2NormVector(Vector*, Vector*, float)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x66a): undefined reference to `Print(int, char*, ...)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x679): undefined reference to `FreeVector(Vector*)'
tmpxft_00004e1d_00000000-1_cg_cuda.cudafe1.cpp:(.text+0x69c): undefined reference to `RenameImage(Image*, char*)'
collect2: ld returned 1 exit status
make: *** [it] Error 1
Grazie per la vostra pazienza leggendo il mio post.
Sei sicuro che questo ha funzionato prima di aver introdotto il file '.cu'? Ad ogni modo, ti suggerisco di provare a cambiare '$?' In '$ ^'. – Beta
Beh, l'ho cambiato; Posso anche postare il Makefile originale ... forse questo mi aiuterebbe con quello che dovrei aggiungere in modo che anche i file .cu si compilino. – vburca
Non ci hai fornito abbastanza informazioni (ad es. Il messaggio di errore) per essere sicuri del problema esatto, ma hai apportato molte piccole modifiche tra questi due makefile. Prova una ricerca binaria: scrivi un makefile con solo metà di questi cambiamenti e verifica se funziona. Se trovi * un cambiamento * che fa la differenza, e non ha ancora senso, faccelo sapere. – Beta