Compiling .cu and .c files with multiple targets How can I make a Makefile to achieve that

Hello,

My code base contains in essence some Linux kernel code in ./kernel which compiles fine with the Linux kernel make system, some common data structures in ./common/common.h, as well as several c files and one .cu file in ./server. The c files are compiled and linked into different small programs for which I use one Makefile, and they compile successfully. Some of the compiled c files are supposed to be linked to the compiled cu file, but I encounter a few difficulties. I wrote a Makefile.process:

EXECUTABLE	:= process

CUFILES		:= ppe.cu

CCFILES		:= \

	process.c \

	process_spec.c \

	radardata.c

INCLUDES += -I ../common

include common.mk

and when I issue a make -f Makefile.process I get:

  1. common.h in …/common is not found by the preprocessor and the compilation fails. Why is that, even though I have added an extra INCLUDES?

  2. After temorarily copying the common.h file into my ./server directory and modifying the #includes, it nearly compiles. I only get “… was not declared in this scope” errors for open/close/ioctl and sleep calls in one of the .c files. Why is that when it compiles fine in a normal makefile?

  3. I would like to have a single makefile that:

  • compiles c files as c files in objects

  • compiles cu files as cuda files in objects

  • links cuda objects and required object files to target executable

  • links other object files to executables

Any hints and suggestions?

Kind regards,

peter

I would council against trying to use the SDK build system in your own projects. It is byzantine and crippled. If you have an existing functional makefile, just add a rule to compile .cu files with nvcc and add the runtime libraries you need to link (normally libcudart if you are using the runtime API), and you should be good to go.

Hello,

Hmm, this sounds very simple and straightforward. Only my makefile is quite simple, with explicit instructions for all items, no rules. So I guess I have to learn how to setup rules in a Makefile with all its cryptic $@ @< etc. Would be nice to have a template to get started.

Cheers,

peter

In that case even easier, just an an explicit instruction for the .cu files you want to compile and link. Something like this

mycuda.o:	  mycuda.cu

			   nvcc -c mycuda.cu -o mycuda.o

myapp:		 mycuda.o myc.o myfortran.o mycpp.o

			   gcc -o myapp -L/path/to/cuda/libraries mycuda.o myc.o myfortran.o mycpp.o -lmylibs -lcudart

is how simple it can be.

Thanks for the hint; it can be indeed quite simple if you start from a clean slate. In the end this is what I did. Later I incorporated contents as needed from the cmmon.mk found in the SDK, such as flags and a few rules.

Now the compilation nearly works. The linker only complains about undefined references to functions that should actually be in the .cu.o which is linked into an executable, but somehow the linker cannot find. Perhaps it is due to some name mangeling?

Cheers,
peter

Any host functions in your .cu file are compiled using C++ by default, so yes it probably is name mangling. You can either use extern “C” declarations inside the .cu file, or add a flag to tell nvcc to compile host C code using C rather than C++. Either should work.

Many thanks, that was it, declaring the cu functions as extern “C”.
peter

avidday, sorry to bother you. How does one add a flag to tell nvcc to compile host C code using C rather than C++? Specifically, what is the flag and where is it placed?

Thanks, and have a good day.

MMB

P.S. I have searched the documentation, but didn’t find anything!

Off the top of my head you can (or certainly could around CUDA 2.2 and 2.3 time) pass nvcc the --host-compilation flag with either C or C++ as an argument. It still uses g++ to compile the code, but in some sort of C compatibility mode which doesn’t break most C code.

Thank you.

If any of the NVIDIA people can confirm/deny this for CUDA 3.0/3.1 that would be helpful - maybe to a lot of people!

MMB