How to write this Makefile? Linking fails... Makefile issue

Hi guys,

Could someone help me with this compilation bug? Have been spent almost the whole Sunday on it, but still cant get it working. It really drives me crazy! Have to admit that I am not very good at writing Makefile like this in Linux.

So what I am trying to do is to write a convolution cuda codes just for practising. There are 4 files created, 2 of which are in .c (ConvTest.c and Croutines.c) and the other two are in .cu (subroutines.cu and RunKernel.cu). The main function is in ConvTest.c. The dependencies of those files look as follow, and the Makefile is also attached here. When I start compiling, all the four .o objective files are successfully created, but for some reason, the main() function in ConvTest.c just can “see” the runTest() in linking stage! This is the err msg that I got from compilation:

gcc -o ConvTest RunKernel.o subroutines.o Croutines.o ConvTest.o -lcutil -lm -lcudart -L/usr/local/cuda/lib64 -L/home/orangejuice/NVIDIA_GPU_Computing_SDK/C/lib/ -L/home/orangejuice/NVIDIA_GPU_Computing_SDK/C/common/lib

ConvTest.o: In function `main’:

ConvTest.c:(.text+0x17): undefined reference to `runTest’

collect2: ld returned 1 exit status

make: *** [ConvTest] Error 1

I am sure I must mess up something here, but I can’t figure out myself. Could someone here kindly guide me how to correct this bug? I’d really appreciate it!

[codebox]/////////////// ConvTest.c ///////////////

#include “subroutines.h”

#include “Croutines.h”

#include “RunKernel.h”

int main()

{

runTest();

}

/////////////// RunKernel.cu ///////////////

#include “RunKernel.h”

#include <cutil_inline.h>

void runTest()

{

Kernel_1<<<grid, blocks>>>();

}

/////////////// subroutines.cu ///////////////

#include “subroutines.h”

global void Kernel_1()

{

}

[/codebox]

########### Makefile script #####################

[codebox]#

This is the Makefile, you need to change the “filename” correspondingly.

the “filename” is the name of the file where your main function resides in.

######## Object 1

filename = ConvTest

executable = $(filename)

objects = $(filename).o

source = $(filename).c

######## Object 2

subfilename2 = Croutines

subobject2 = $(subfilename2).o

subsource2 = $(subfilename2).c

subheader2 = $(subfilename2).h

######## Object 3

subfilename3 = subroutines

subobject3 = $(subfilename3).o

subsource3 = $(subfilename3).cu

subheader3 = $(subfilename3).h

######## Object 4

subfilename4 = RunKernel

subobject4 = $(subfilename4).o

subsource4 = $(subfilename4).cu

subheader4 = $(subfilename4).h

(executable) : (subobject4) (objects) (subobject2) $(subobject3)

gcc  -o $(executable) $(subobject4) $(subobject3) $(subobject2) $(objects) -lcutil -lm -lcudart -L/usr/local/cuda/lib64 -L/home/orangejuice/NVIDIA_GPU_Computing_SDK/C/lib/  -L/home/orangejuice/NVIDIA_GPU_Computing_SDK/C/common/lib

(objects) : (source) (subheader3) (subheader2) $(subheader4)

gcc -c $(source) 

(subobject2): (subsource2) $(subheader2)

gcc -c $(subsource2)	

(subobject3): (subsource3) $(subheader3)

/usr/local/cuda/bin/nvcc -o $(subobject3) -c -arch=sm_11 -I/home/orangejuice/NVIDIA_GPU_Computing_SDK/C/common/inc/ $(subsource3)

(subobject4): (subsource4) $(subheader4)

/usr/local/cuda/bin/nvcc -o $(subobject4) -c -arch=sm_11 -I/home/orangejuice/NVIDIA_GPU_Computing_SDK/C/common/inc/ $(subsource4)[/codebox]

A. RunTest must be defined as extern “C”.
B. There’s no linker for CUDA kernels, so Kernel_1 has to be inside the same compilation unit as RunTest.

Hi tmurray,

Thanks for the quick reply! According to your points, I made some corrections.

I redeclare the runTest() in its head file (RunKernel.h) as,

#ifdef __cplusplus

extern “C”

{

#endif

void runTest(int, char**);

#ifdef __cplusplus

}

#endif

Is this what you mean?

Unfortunately, the same error message is still there if I replace my original codes with the above. :confused:

I am not sure if I am following you about this point, so you mean, the Kernel_1() has to be in the same source file as the runTest() function? Specifically, here in my project, I should move the declaration and definition of Kernel_1() to the files RunKernel.h and RunKernel.cu?

Thanks!