CUDA compilation errors on Mac - c

I'm using the following Makefile to compile a CUDA C program. This follows pretty much the same pattern that I use in most of my C projects.
TARGET = bfs
GCC = nvcc
CUDA_INSTALL_PATH := /Developer/NVIDIA/CUDA-7.5
LIBS := -I. -I$(CUDA_INSTALL_PATH)/include
CUDA_LIBS := -L$(CUDA_INSTALL_PATH)/lib -lcudart
SRCDIR = src
OBJDIR = obj
BINDIR = bin
INClDIR = includes
SOURCES := $(wildcard $(SRCDIR)/*.cu)
INCLUDES := $(wildcard $(INClDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.cu=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
mkdir -p $(BINDIR)
$(GCC) -o $# $(LIBS) -c $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cu
#$(GCC) $(LIBS) -c *.cu -o $#
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
I get the following error
mkdir -p bin
nvcc -o bin/bfs -I. -I/Developer/NVIDIA/CUDA-7.5/include -c obj/main.o obj/square.o
nvcc fatal : A single input file is required for a non-link phase when an outputfile is specified
make: *** [bin/bfs] Error 1
What am I doing wrong here.

This seemed to work for me:
TARGET = bfs
SRCDIR = src
OBJDIR = obj
BINDIR = bin
INClDIR = includes
CUDA_INSTALL_PATH := /usr/local/cuda
GCC := $(CUDA_INSTALL_PATH)/bin/nvcc
LIBS := -I. -I$(SRCDIR) -I$(CUDA_INSTALL_PATH)/include -I$(INClDIR)
CUDA_LIBS := -L$(CUDA_INSTALL_PATH)/lib64 -lcudart
SOURCES := $(wildcard $(SRCDIR)/*.cu)
INCLUDES := $(wildcard $(INClDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.cu=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET) : $(OBJECTS)
mkdir -p $(BINDIR)
$(GCC) -o $# $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cu
#$(GCC) $(LIBS) -c $(SRCDIR)/*.cu -odir $(OBJDIR)
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
I tested on linux. You will need to change CUDA_INSTALL_PATH back to wherever it is on your machine.
Note that your use of *.cu on the compile step results in a single invocation of nvcc to compile all the source files. There's nothing wrong with this per se, but it will only generate a single "Compiled ... successfully!" message, as there is only one invocation of nvcc to create all the objects.

Related

Makefile: Separated sources and objects

I've been trying for some time to separate the source files of my project from the generated object files.
Indeed, I would like my project to be structured this way:
obj/
main.o
src1.o
[...]
src/
main.c
src1.c
[...]
Makefile
The Makefile I currently have is as follows:
NAME = a.out
OBJ_DIR = "obj"
SRC_DIR = "src"
MAIN_SRC = main.c
PROJ_SRC = src1.c \
src2.c \
src3.c
MAIN_OBJ = $(MAIN_SRC:%.c=%.o)
PROJ_OBJ = $(PROJ_SRC:%.c=%.o)
CC = gcc
RM = rm -rf
$(NAME): $(MAIN_OBJ) $(PROJ_OBJ)
$(CC) $(MAIN_OBJ) $(PROJ_OBJ) -o $(NAME)
all: $(NAME)
clean:
$(RM) $(MAIN_OBJ) $(PROJ_OBJ)
fclean: clean
$(RM) $(NAME)
I tried to use pattern rules, without success.
MAIN_OBJ = $(MAIN_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
PROJ_OBJ = $(PROJ_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
[...]
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
Does anyone have a solution to my problem?
MAIN_SRC and PROJ_OBJ do not have directory prefix, so that expressions
$(MAIN_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
$(PROJ_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
do not replace anything.
Fix:
MAIN_OBJ := $(MAIN_SRC:%.c=$(OBJ_DIR)/%.o)
PROJ_OBJ := $(PROJ_SRC:%.c=$(OBJ_DIR)/%.o)
And then your pattern rule should work.
You may like to have make create that $(OBJ_DIR) for you:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
$(CC) $(CFLAGS) -c -o $# $<
$(OBJ_DIR) :
mkdir -p $#
A more advanced example for you with automatic header dependency generation.
bro!
If your project "main" 's architecture is just liking this:
main
|
|__Makefile
|__obj
|__src
|__main.c
|__src1.c
|__src2.c
[...]
Just add this to your "Makefile" to store your object out of source files directory:
# Object files
# String substituion for every C/C++ file
# e.g: ./src/src1.cpp turns into ./obj/src1.o
OBJS := $(patsubst %.c, ${OBJ_DIR}/%.o, $(notdir $(SRC_DIR)))
And just add this to your "Makefile" to compile:
# Compile: Generate object files from source files
# $# := {NAME}
# $< := THE first file
# $^ all the dependency
# C Sources
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(C_FLAGS) -c $< -o $#
END!

Makefile builds target every time

I have written a makefile to compile all the sources in different directories and build a target. When I run make even when there is no change in the files, it does not re-compiles the unmodified files. But, it always builds the target. Why is the target alone getting built every time when I run make?
CC = gcc
CFLAGS = $(INCLUDES)
TARGET = FinalBin
OUTDIR := obj
INCLUDES = -Isrc/in
S1 = src/s1
S2 = src/s2
S1_SRC = $(wildcard $(S1)/*.c)
S2_SRC = $(wildcard $(S2)/*.c)
SRCS := $(S1_SRC) \
$(S2_SRC)
OBJS := $(patsubst %.c,$(OUTDIR)/%.o,$(SRCS))
SRCDIRS := $(S1) $(S2)
all: $(TARGET)
$(TARGET): builddir $(OBJS)
#echo "Building..." $#
#$(CC) $(OBJS) $(CFLAGS) -o $#
#echo "Build Complete!"
$(OUTDIR)/%.o: %.c
#echo "Compiling.." $(notdir $<)
#$(CC) $(CFLAGS) -MMD -c $< -o $#
clean:
-#rm -rf $(OUTDIR) FinalBin
#echo "Clean complete!"
builddir :
#$(call create-dir)
define create-dir
for dir in $(SRCDIRS); \
do \
mkdir -p $(OUTDIR)/$$dir; \
done
endef
-include $(wildcard $(OBJS:.o=.d))
The $(TARGET) gets built from the object files each time. Please guide me where I'm going wrong.
UPDATE:
CC = gcc
CFLAGS = $(INCLUDES)
TARGET = FinalBin
OUTDIR := obj
INCLUDES = -Isrc/in
S1 = src/s1
S2 = src/s2
S1_SRC = $(wildcard $(S1)/*.c)
S2_SRC = $(wildcard $(S2)/*.c)
SRCS := $(S1_SRC) \
$(S2_SRC)
OBJS := $(patsubst %.c,$(OUTDIR)/%.o,$(SRCS))
SRCDIRS := $(S1) $(S2)
OUTDIRS := $(addprefix $(OUTDIR)/,$(SRCDIRS))
all: $(TARGET)
$(TARGET): $(OBJS)
#echo "Building..." $#
#$(CC) $(OBJS) $(CFLAGS) -o $#
#echo "Build Complete!"
$(OUTDIR)/%.o: $(OUTDIRS) %.c
#echo "Compiling.." $(notdir $(filter %.c,$^))
#$(CC) $(CFLAGS) -MMD -c $(filter %.c,$^) -o $#
clean:
-#rm -rf $(OUTDIR) FinalBin
#echo "Clean complete!"
$(OUTDIRS):
mkdir -p $#
builddir :
#$(call create-dir)
define create-dir
for dir in $(SRCDIRS); \
do \
mkdir -p $(OUTDIR)/$$dir; \
done
endef
-include $(wildcard $(OBJS:.o=.d))
This builds all the files every time.
Final Solution:
CC = gcc
CFLAGS = $(INCLUDES)
TARGET = FinalBin
OUTDIR := obj
INCLUDES = -Isrc/in
S1 = src/s1
S2 = src/s2
S1_SRC = $(wildcard $(S1)/*.c)
S2_SRC = $(wildcard $(S2)/*.c)
SRCS := $(S1_SRC) \
$(S2_SRC)
OBJS := $(patsubst %.c,$(OUTDIR)/%.o,$(SRCS))
SRCDIRS := $(S1) $(S2)
OUTDIRS := $(addprefix $(OUTDIR)/,$(SRCDIRS))
all: $(TARGET)
$(TARGET): $(OUTDIRS) $(OBJS)
#echo "Building..." $#
#$(CC) $(OBJS) $(CFLAGS) -o $#
#echo "Build Complete!"
$(OUTDIR)/%.o: %.c
#echo "Compiling.." $(notdir $<)
#$(CC) $(CFLAGS) -MMD -c $< -o $#
clean:
-#rm -rf $(OUTDIR) FinalBin
#echo "Clean complete!"
$(OUTDIRS):
#mkdir -p $#
-include $(wildcard $(OBJS:.o=.d))
The final solution works as expected!
You can use the debug output of make to look for what it thinks needs rebuilding:
make -d | grep remake
You'll probably see something like this:
No need to remake target `Makefile'.
Must remake target `builddir'.
No need to remake target `src/s1/x.c'.
No need to remake target `obj/src/s1/x.o'.
Must remake target `FinalBin'.
Must remake target `all'.
Which shows that it always thinks that the builddir target needs to be remade. Since that is a dependency of $(TARGET) it rebuilds the latter as well.
If you use a rule to create your build directories instead of a function, make will know whether it needs create them or not. For example, adding the variable $(OUTDIRS), a rule for it, and making this a dependency of compiling:
SRCDIRS := $(S1) $(S2)
OUTDIRS := $(addprefix $(OUTDIR)/, $(SRCDIRS)) # <---------- Add this variable
All: $(TARGET)
$(TARGET): $(OBJS)
#echo "Building..." $#
#$(CC) $(OBJS) $(CFLAGS) -o $#
#echo "Build Complete!"
$(OUTDIR)/%.o: $(OUTDIRS) %.c # <--------------------------- Add dependency to $(OUTDIRS)
#echo "Compiling.." $(notdir $<)
#$(CC) $(CFLAGS) -MMD -c $< -o $#
clean:
-#rm -rf $(OUTDIR) FinalBin
#echo "Clean complete!"
$(OUTDIRS): # <--------------------------------------------- Add rule
mkdir -p $#
-include $(wildcard $(OBJS:.o=.d))

Make: *.h no such file or directory

My project has the following directory structure:
main.cu
FA_kernels/*.cu
FD_kernels/*.cu
MEM_kernels/*.cu
MOD_kernels/*.cu
headers/*.h
Where *.extension means a bunch of files with that extension. I can't seem to get the makefile to work correctly. The error I'm getting is:
FA_kernels/FA_SFD.cu:2:20: fatal error: FA_SFD.h: No such file or directory
#include "FA_SFD.h"
^
My intent was for -I headers to be specified to the compiler, thereby making the headers directory available for searching. Clearly this has not worked. Here is the makefile:
CC := nvcc
LD := nvcc
MODULES := FA_kernels FD_kernels MEM_kernels MOD_kernels .
SRC_DIR := $(MODULES)
BUILD_DIR := $(addprefix build/,$(MODULES))
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cu))
OBJ := $(patsubst src/%.cu,build/%.o,$(SRC))
INCLUDES := $(addprefix -I,headers)
vpath %.cu $(SRC_DIR)
define make-goal
$1/%.o: %.cu
$(CC) $(INCLUDES) -c $$< -o $$#
endef
.PHONY: all checkdirs clean
all: checkdirs build/lem
build/lem: $(OBJ)
$(LD) $^ -o $#
checkdirs: $(BUILD_DIR)
$(BUILD_DIR):
#mkdir -p $#
clean:
#rm -rf build
$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir))))
Any ideas?
UPDATE: Here is the full console output from running make
nvcc FA_kernels/FA_SFD.cu FA_kernels/partition.cu FA_kernels/contribA.cu FA_kernels/parallel-SFD-List.cu FD_kernels/SFD.cu FD_kernels/flow_routines.cu FD_kernels/floodingDriver.cu FD_kernels/watershed.cu MEM_kernels/memory_dev.cu MEM_kernels/Data.cu MEM_kernels/MapInfo.cu MEM_kernels/memory.cu MOD_kernels/erosion.cu MOD_kernels/eroincidep.cu MOD_kernels/updates.cu MOD_kernels/runoffweight.cu MOD_kernels/depo-List.cu lem.cu -o build/lem
FA_kernels/FA_SFD.cu:2:20: fatal error: FA_SFD.h: No such file or directory
#include "FA_SFD.h"
^
compilation terminated.
Makefile:24: recipe for target 'build/lem' failed
make: *** [build/lem] Error 1
From your output, apparently patsubst in OBJ was not successful at all. From the way you define SRC, I assume makefile is directly under src/, then you should change src/%.cu to %.cu in the definition of OBJ as such:
OBJ := $(patsubst %.cu,build/%.o,$(SRC))
Also, if I understand you correctly, you were trying to create a folder structure under build/ that is identical to the folder structure under src/. So, for instance, /src/abc.cu will generate /src/build/abc.o, then you don't need to define functions to get these rules, simply do:
build/%.o: %.cu
$(CC) $(INCLUDES) -c $< -o $#
and you are good to go.
If instead you wish to create build/ on the same level as src/. i.e. XXX/src/abc.cu -> XXX/build/abc.o. Then simply replace all occurrences of build in your makefile with ../build.
If you would rather put makefile at the same level as src/, then you should edit SRC to reflect that:
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard src/$(sdir)/*.cpp))
and change the target to:
build/%.o: src/%.cpp
$(CC) $(INCLUDES) -c $< -o $#
Now you can safely remove vapth ... and the last line $foreach in your makefile.
EDIT: This is what your makefile will look like. I can't test it right now so there may be some mistakes in it, but hopefully it makes you understand the general idea.
CC := nvcc
LD := nvcc
MODULES := FA_kernels FD_kernels MEM_kernels MOD_kernels .
SRC_DIR := $(MODULES)
BUILD_DIR := $(addprefix build/,$(MODULES))
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cu))
OBJ := $(patsubst %.cu,build/%.o,$(SRC))
INCLUDES := $(addprefix -I,headers)
# vpath %.cu $(SRC_DIR)
#define make-goal
build/%.o: %.cu
$(CC) $(INCLUDES) -c $< -o $#
#endef
.PHONY: all checkdirs clean
all: checkdirs build/lem
build/lem: $(OBJ)
$(LD) $^ -o $#
checkdirs: $(BUILD_DIR)
$(BUILD_DIR):
#mkdir -p $#
clean:
#rm -rf build
#$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir))))

Compilation issues between servers

I'm using the following Makefile to compile and run a c program on my local machine
# project name
TARGET = server
CC = gcc
# compiling flags
CFLAGS = -std=c99 -Wall -I. -g
LINKER = gcc -o
# linking flags
LFLAGS = -Wall -I. -lm
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
mkdir -p $(BINDIR)
#$(LINKER) $# $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
.PHONEY: remove
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
This works perfectly on my local environment which is a mac(though there's nothing in the code that's mac specific).
However when I compile this code on a linux server I get the following error.
Build failed. Wrong Architecture.
When I manually compile the source files on this server running gcc file1 file2.... It compiles fine. What am I doing wrong with my Makefile.
Did you make clean before you make? I think there are some files or libraries were built on other architecture

Need help writing a Makefile that creates all the objective files into a new subdir

I am trying to make a Makefile for a big project.
The project structure is (I've ommitted the header files):
root/feature1/feat1.c
root/feature2/feat2.c
root/srcfile1.c
root/srcfile2.c
I wanted to start easy so I created a simpler project with the source files in the root dir.
I need to create all the object files in one directory, let's say, objdir.
The project structure of the simple project is:
root/main.c
root/word.c
By looking in other questions I have come up with this:
CC = gcc
FLAGS = -c
MKDIR_P = mkdir -p
OUT = words
OBJDIR = objdir
SRCDIR = .
_OBJS = main.o word.o
OBJS = $(patsubst %,$(OBJDIR)/%,$(_OBJS))
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $# $<
all: directories program
directories: ${OBJDIR}
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
program: $(OBJS)
$(CC) -o $# $^ $(LIBS)
clean:
rm -f $(OBJS)
When running it with make -f ./myMakefile all (changed the filename as in the same dir, there is Netbeans' Makefile), I am getting this output:
gcc -o objdir/main.o main.c
/tmp/ccatfAHu.o: In function `main':
main.c:(.text+0x15): undefined reference to `CreateWord'
main.c:(.text+0x26): undefined reference to `CreateWord'
collect2: error: ld returned 1 exit status
make: *** [objdir/main.o] Error 1
Giving the make all command, it tries to produce the targes directories and program.
The dir objdir is created and in it, there are the main.o and word.o files.
What am I doing wrong with the makefile of the simpleproject?
EDIT:
Added the -c flag at the $(OBJDIR)/%.o rule.
Removed the $(FLAGS) from $(CC) -o $# $^ $(FLAGS) $(LIBS).
Now, if we move to my project problem, I need to access all the source files from all the directories:
/repo-root
/repo-root/feature1/feat1.c
/repo-root/feature2/feat2.c
In this rule:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -o $# $<
you're missing the -c flag. Instead of building an object file, Make is trying to build an executable named objdir/main.o, and main.c doesn't have all of the needed code. Just do this:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $# $<
Try this
#source files to compile relative to the src dir
CSOURCE = main.c
CSOURCE += func1.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = objdir
BINDIR = bindir
#list of objects
OBJS = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
#output name for executable
APP = example
all: ${OBJDIR} $(OBJS) bin
#rule to create bin and objects dir
${BINDIR}:
${MKDIR_P} ${BINDIR}
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
#rule to compile c files
$(OBJDIR)/%.o: %.c
$(CC) -c $< -o $#
#to create executable
bin: $(BINDIR) $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(BINDIR)/$(APP)
#to clean executable and objects
clean:
rm -rf $(OBJS) $(BINDIR) $(OBJDIR)
Updated root make file, Use this in the root/ directory
WORKDIR = $(shell pwd)
MODULES = feature1 feature2
CSOURCE = main.c
CSOURCE += func1.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = $(WORKDIR)/objdir
BINDIR = $(WORKDIR)/bindir
OBJS = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
APP = example
all: ${OBJDIR} modules $(OBJS) bin
modules:
for mod in $(MODULES); do \
echo "Building $$mod ....."; \
$(MAKE) -C $(WORKDIR)/$$mod all; \
done
${BINDIR}:
${MKDIR_P} ${BINDIR}
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
$(OBJDIR)/%.o: %.c
$(CC) -c $< -o $#
bin: $(BINDIR) $(OBJS)
$(CC) $(CFLAGS) $(OBJDIR)/*.o -o $(BINDIR)/$(APP)
clean:
rm -rf $(OBJS) $(BINDIR) $(OBJDIR)
feature make file, use this in the root/feature1 directory and root/feature2 directory
WORKDIR = $(shell cd ..; pwd)
CSOURCE = func2.c
SRCDIR = .
vpath %.c $(SRCDIR)/
CC = gcc
MKDIR_P = mkdir -p
OBJDIR = $(WORKDIR)/objdir
OBJS = $(addprefix $(OBJDIR)/, $(CSOURCE:.c=.o))
all: ${OBJDIR} $(OBJS)
${OBJDIR}:
${MKDIR_P} ${OBJDIR}
$(OBJDIR)/%.o: %.c
$(CC) -c $< -o $#
clean:
rm -rf $(OBJS) $(OBJDIR)
When you want to add new directory say feature3, you can just add it in main makefile module list and copy the feature1 makefile to feature3 and update source file list
Hope this helps

Resources