1

I've got a project with a few files (.cu, .cpp, .h) and I'd like to compile and link it.

My files are as follow:

1) Graph.cpp - just c++ code

2) Graph.h - header to the above (works fine)

3) Common.h - __host__ __device__ functions

#ifndef COMMON_CUH
#define COMMON_CUH

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

__host__ __device__ unsigned int fun1(int, int);
__host__ __device__ int fun2(int);
__host__ __device__ int fun3(int);
__host__ __device__ unsigned int fun4(int, int);

#endif

4) Common.cu - implementation of the above

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include "Common.h"


__host__ __device__ unsigned int fun1(int a, int n) 
{
    ...
}

...other functions...

5) kernel.cu - main file

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include "Graph.h"
#include "LogCreate.h"
#include "Common.h"

some __global__ functions. c++ functions, main etc.

One of my makefiles that I try to use:

CUDA_INSTALL_PATH ?= /usr/local/cuda

# Compilers
CXX := g++
CC := gcc
LINK := g++ -fPIC
NVCC  := nvcc -ccbin /usr/bin

# Includes
INCLUDES = -I. -I$(CUDA_INSTALL_PATH)/include

# Common flags
COMMONFLAGS += $(INCLUDES)
NVCCFLAGS += $(COMMONFLAGS)
NVCCFLAGS += -arch=sm_35
# Debug mode
NVCCFLAGS += --compiler-options -Wall -G
CXXFLAGS += $(COMMONFLAGS)
CFLAGS += $(COMMONFLAGS)

LIB_CUDA := -L$(CUDA_INSTALL_PATH)/lib64 -lcudart

OBJS = Common.cuh.o Graph.cpp.o LogCreate.cpp.o kernel.cu.o
TARGET = main
LINKLINE = $(LINK) -o $(TARGET) $(OBJS) $(LIB_CUDA)

.SUFFIXES: .c .cpp .h .cu .cuh .o

%.cuh.o: %.cu %.cuh
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

%.cu.o: %.cu
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

%.cpp.o: %.cpp %.h
    $(CXX) $(CXXFLAGS) -c $< -o $@

$(TARGET): $(OBJS) Makefile
    $(LINKLINE)

clean: 
    rm -rf *.o

which gives me:

Common.cuh.o: In function `__sti____cudaRegisterAll_41_tmpxft_0000107c_00000000_6_Common_cpp1_ii__Z3Powii()':
tmpxft_0000107c_00000000-3_Common.cudafe1.cpp:(.text+0x1c1): undefined reference to `__cudaRegisterLinkedBinary_41_tmpxft_0000107c_00000000_6_Common_cpp1_ii__Z3Powii'
kernel.cu.o: In function `__sti____cudaRegisterAll_41_tmpxft_000010ad_00000000_6_kernel_cpp1_ii_filename()':
tmpxft_000010ad_00000000-3_kernel.cudafe1.cpp:(.text+0x2f33): undefined reference to `__cudaRegisterLinkedBinary_41_tmpxft_000010ad_00000000_6_kernel_cpp1_ii_filename'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1

I guess it (Here's a link) could be a desription of my problem but I don't know how to deal with it.

Another try of writing makefile is (less generic):

setting like before and main part:
all:
    $(NVCC) $(NVCCFLAGS) -dc Common.cu kernel.cu
    $(NVCC) $(NVCCFLAGS) -dlink Common.o kernel.o -o link.o
    $(CXX) $(CXXFLAGS) -c Graph.cpp Graph.h -o graph.o
    $(LINK) -o main Common.o kernel.o link.o graph.o $(LIB_CUDA)

which gives me:

g++ -fPIC -o main Common.o kernel.o link.o graph.o -L/usr/local/cuda/lib64 -lcudart
graph.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
make: *** [all] Error 1

I've searched so many websites and still don't know how to fix it. I read some part of link I placed before, but maybe I've missed something or just didn't understand.

Please, explain what is a correct approach to dealing with many files (with host and device code) while compiling/linking in Makefile. Thanks

db_k
  • 364
  • 1
  • 5
  • 19

1 Answers1

4

Your first method didn't handle CUDA separate compilation correctly (you had no device-link step).

Your second method is closer to the mark.

This is wrong:

$(CXX) $(CXXFLAGS) -c Graph.cpp Graph.h -o graph.o

it should be:

$(CXX) $(CXXFLAGS) -c Graph.cpp -o graph.o
Robert Crovella
  • 143,785
  • 11
  • 213
  • 257
  • In the future, to avoid wasted hours, and perhaps even having to post a question, try googling something like ["g++ file not recognized: File format not recognized"](https://www.google.com/?gws_rd=ssl#q=g%2B%2B+file+not+recognized:+File+format+not+recognized) then [take the first hit](http://stackoverflow.com/questions/17126384/g-output-file-not-recognized-file-format-not-recognized). Perhaps I should mark this question as a duplicate of that one. – Robert Crovella Jul 02 '15 at 02:41
  • In other words, to generalize the advice, if you have a compile error you don't understand, you could try googling for the exact compile error output. There's a pretty good chance that others have run into that error, and may already have documented what is wrong and how to fix it. In this case, it likely would have led you to a very similar question to yours, possibly saving you "wasted few hours". – Robert Crovella Jul 02 '15 at 06:55
  • I've searched many sites by googling many combination of questions and haven't found anything. Of course I haven't tried this one you typed. So it's not about not trying (I've tried even output with no matching result) it's about not knowing what kind of error it could be :) anyway thanks for advice. – db_k Jul 02 '15 at 08:14