You can compile C++ file without CUDA related code with g++.
And you can compile CUDA code with nvcc.
Then, you can link them with nvcc to output executable file.
My Makefile is looks like this:
CXX := g++
NVCC := nvcc
CCFLAGS := -std=c++11 -Wall -Wextra
NVCCFLAGS := -std c++11
$(PROGNAME) : $(OBJS)
$(NVCC) --linker-options --gc-sections -o $@ $^
%.o : %.cpp
$(CXX) $(CCFLAGS) -o $@ -c $<
%.o : %.cu
$(NVCC) $(NVCCFLAGS) -dc -o $@ $^
My .cu files have both device functions and host functions.
Device functions in the .cu files are not accessible from other .cu or .cpp file.
But host functions in the .cu files can be called from other .cpp files.
I use thrust library.
It is similar to STL and in C++.
If you define a class which have thrust::device_vector or thrust::host_vector and it is used in .cpp files, they need to be invisible to .cpp.
You can use Pimpl Idiom to hide them.