Hi I'm developing CGI which is written in C and trying to use Mysql.
When I try to use it, I got those undefined reference errors for symbols that start with mysql_, such as those shown here:
/usr/bin/ld: Warning: type of symbol `password' changed from 2 to 1 in ../../lib /libcgi_module.a(users.o)
../../lib/libcgi_module.a(users.o): In function `save':
/home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/users.c:18: multiple definition of `save'
../../lib/libcgi_module.a(mode.o):/home/jitcomm/intern_GUI/jit24_test_v2/cgi_src/cgi_module/mode.c:56: first defined here
../../lib/libcgi_module.a(users.o): In function `saveUser':
users.c:(.text+0x192): undefined reference to `mysql_init'
users.c:(.text+0x1e4): undefined reference to `mysql_real_connect'
users.c:(.text+0x1f5): undefined reference to `mysql_error'
users.c:(.text+0x267): undefined reference to `mysql_query'
users.c:(.text+0x278): undefined reference to `mysql_error'
users.c:(.text+0x2ab): undefined reference to `mysql_close'
So I write some sample code and I can run well when I use my program with this line
gcc -o saveUser $(mysql_config --cflags) saveUser.c $(mysql_config --libs)
It works well.
So next step, I try to put my coding in CGI.
I still got those undefined reference again.
Here is my Makefile.basic
CC=/usr/bin/gcc
#CC=powerpc-linux-gcc
CP=/usr/bin/cp
CFLAGS = -g -Wall $(mysql_config --cflags) $(mysql_config --libs)
www=/var/www
htdocs=/htdocs
cgi_bin=/cgi-bin
config=/etc/apache2/sites-available/default
What should I do ? Where it goes wrong ? Help me please. I have been searching on the internet for a week but still can't get the solution. I guess it's in makefile.basic and the linking to mysql is wrong.
Thanks
Update :
here is my top level Makefile
ROOT=.
CURDIR=$(shell /bin/pwd)
JITCOMM_INSTALL=$(ROOT)/install
include $(ROOT)/Makefile.basic
#set root directory
SUB_DIRS = cgi_src
SUB_DIRS += check_update
SUB_DIRS += loadconfig
SUB_DIRS += keepalive
SUB_DIRS += script
SUB_DIRS += server
SUB_DIRS += startproxy
SUB_DIRS += net_stats
#SUB_DIRS += ../sniffer_gui
#SUB_DIRS += java
all:
ifneq ($(SUB_DIRS), )
#for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make || exit; cd $(CURDIR); done
endif
clean:
#rm -f $(ROOT)/lib/*
#rm -rf $(JITCOMM_INSTALL)
ifneq ($(SUB_DIRS), )
#for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make clean || exit; cd $(CURDIR); done
endif
install: all
#rm -rf $(JITCOMM_INSTALL)
#mkdir $(JITCOMM_INSTALL)
#mkdir $(JITCOMM_INSTALL)/etc
#mkdir $(JITCOMM_INSTALL)/etc/acpro
#mkdir $(JITCOMM_INSTALL)/etc/syslog-ng
#mkdir $(JITCOMM_INSTALL)/etc/apache2
#mkdir $(JITCOMM_INSTALL)/etc/apache2/sites-available
#mkdir $(JITCOMM_INSTALL)/var
#mkdir $(JITCOMM_INSTALL)/var/www
#mkdir $(JITCOMM_INSTALL)/var/www/cgi-bin
Here is my Makefile in cgi-src folder
ROOT=../
CURDIR=$(shell /bin/pwd)
include $(ROOT)/Makefile.basic
#set root directory
SUB_DIRS = util
SUB_DIRS += cgi_util
SUB_DIRS += cgi_module
#Must be last
SUB_DIRS += cgi_main
all:
ifneq ($(SUB_DIRS), )
#for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make || exit; cd $(CURDIR); done
endif
clean:
ifneq ($(SUB_DIRS), )
#for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make clean || exit; cd $(CURDIR); done
endif
install:
ifneq ($(SUB_DIRS), )
#for i in $(SUB_DIRS) ; do if [ ! -d $(CURDIR)/$${i} ]; then continue; fi; \
cd $(CURDIR)/$${i}; make install || exit; cd $(CURDIR); done
endif
Here is my Makefile.basic
CC=/usr/bin/gcc
#CC=powerpc-linux-gcc
CP=/usr/bin/cp
CFLAGS=-g -Wall $(shell mysql_config --cflags) $(shell mysql_config --libs)
www=/var/www
htdocs=/htdocs
cgi_bin=/cgi-bin
config=/etc/apache2/sites-available/default
INSTALL_DIR=$(pwd)/.install
Latest Update :
Makefile in cgi_module
#set common variant
.SUFFIXES: .c .h .o
ROOT=../../
include $(ROOT)/Makefile.basic
#LINK_NAME = changepass.cgi login.cgi network.cgi reboot.cgi shutdown.cgi
LINK_NAME = login.cgi
INCS = -I../include
INCS += -I../../cgi_src/util/include
OBJES=../../lib/
TARGET = libcgi_module.a
#don't change below
LIB_OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
CLEAN_OBJS = $(LIB_OBJS) $(TARGET)
INST_OBJ = $(TARGET)
%.o: %.c
$(CC) -c $(CFLAGS) $(INCS) -o $# $<
all: $(TARGET)
$(TARGET): $(LIB_OBJS)
$(AR) -vsur $# $^
#cp $(TARGET) $(OBJES)
clean:
-#rm -rf $(CLEAN_OBJS)
install:
Try this
CC=/usr/bin/gcc
#CC=powerpc-linux-gcc
CP=/usr/bin/cp
CFLAGS = -g -Wall $(shell mysql_config --cflags) $(shell mysql_config --libs)
foo:
#echo "CFLAGS are $(CFLAGS)"
and launch make foo
Related
I have to a build cuda library with meson and the flags I need to provide are:
NVCCFLAGS = -ccbin g++ --threads 0 -std=c++17 -c -arch=sm_86 -gencode arch=compute_61,code=sm_61 -m64
the meson.build is
# Builds lib-gpu as a dependency called "lib_gpu_dep".
add_languages('cuda')
subdir('src')
project_source_files = [
source_files_src,
]
build_args_common = [
'-ccbin',
'g++',
'-c',
'-arch=sm_86',
'-gencode arch=compute_61,code=sm_61',
'-m64',
]
if (get_option('unit_test'))
build_args = [build_args_common,
'-g',
'-G',
'-DDEBUG=1'
]
else
build_args = [
build_args_common,
'-src-in-ptx',
' -keep',
# '--keep-dir=build/$(BUILD_TYPE)',
' --use_fast_math',
' -lineinfo'
]
endif
cuda_src_dir = '/usr/local/cuda'
inc_dir_cuda = include_directories(cuda_src_dir + '/include')
lib_gpu_incdir = include_directories('inc', is_system : true)
lib_gpu_name = 'lib_gpu'
lib_gpu = static_library(
lib_gpu_name,
project_source_files,
cuda_args : build_args,
gnu_symbol_visibility : 'default',
include_directories : [lib_gpu_incdir, inc_dir_cuda])
lib_gpu_dep = declare_dependency(
include_directories : lib_gpu_incdir,
link_with : lib_gpu
)
in the generated ninja file I have
ARGS = -Ilib-gpu/liblib_gpu.a.p -Xcompiler=-Wall,-Winvalid-pch,-Wnon-virtual-dtor,-Wextra,-Wpedantic -Xcompiler=-fPIC -I/usr/local/cuda/include -I/usr/local/cuda/include -isystem=../lib-gpu/inc -ccbin g++ -c -arch=sm_86 '-gencode$ arch=compute_61,code=sm_61' -m64 -Wno-pedantic -g -G -DDEBUG=1 -I../lib-gpu -Ilib-gpu -Ilib-gpu/liblib_gpu.a.p
but the flags '-gencode$ arch=compute_61,code=sm_61' is not correct
and in order to compile I need to modify it with a script to
-gencode arch=compute_61,code=sm_61
is there a way to solve this problem?
the version used is
meson --version
0.59.1
instead to use
'-gencode arch=compute_61,code=sm_61',
is it possible to write
'-gencode=arch=compute_61,code=sm_61',
in this case the flag generated by meson is correct.
I have a makefile function inside a makefile (myfunction.mk):
.ONESHELL:
define call_script
set +x
mkdir -p $$(dirname $(2))
if [ ! -f $(2) ]; then
echo "" > $(2)
fi
REDIRECT='| tee -a'
echo '>> $(1)'
($(1) ???????? $(2))
RET_CODE=$$?
echo "exit_code is: $$RET_CODE"
if [ ! $$RET_CODE = 0 ]; then
echo "$(3) terminated with error $$RET_CODE"
exit $$RET_CODE
else
if [ ! -z "$(strip $(3))" ]; then
echo "$(3) done"
fi
fi
endef
this function call a script and append result to a log (which is created with its folder if non existing), the result of the script is append only if the makefile variable given as the 4th ($(4)) argument is equal to 'yes'.
you call it like this:
include myfunction.mk
OUTPUT_ENABLED ?= yes
target:
$(call call_script, echo "test", reports/mylog.log, "doing test", OUTPUT_ENABLED)
This works for the most part:
if i replace '????????' by '| tee -a', it works.
if i replace '????????' by $(REDIRECT), it fails.
if i replace '????????' by $$REDIRECT, it fails.
why?
note: running it from a shell /bin/sh: symbolic link to dash
note: of course i want to add a ifeq that allows me to check for $(4) and replace | tee -a by &>>
I'll assume that you use call in a recipe, not flat in your Makefile. There are few problems with your shell script. First, if you try the following on the command line:
mkdir -p reports
REDIRECT='| tee -a'
echo '>> echo "test"'
(echo "test" $REDIRECT reports/mylog.log)
you'll see that echo considers:
"test" $REDIRECT reports/mylog.log
as its arguments. They are expanded and echoed, which prints:
test | tee -a reports/mylog.log
on the standard output, not the effect you expected, I guess. You could, for instance, use eval. On the command line:
eval "echo "test" $REDIRECT reports/mylog.log"
Which, in your Makefile, would become:
eval "$(1) $$REDIRECT $(2)"
Next you should not quote the third parameter of call because the quotes will be passed unmodified and your script will be expanded by make as:
echo " "doing test" terminated with error $RET_CODE"
Again probably not what you want.
Third, you should avoid useless spaces in the parameters of call because they are preserved too (as you can see above between the first 2 double quotes):
.PHONY: foo
foo:
$(call call_script,echo "test",reports/mylog.log,doing test,OUTPUT_ENABLED)
And for your last desired feature, it would be slightly easier to pass the value of OUTPUT_ENABLED to call instead of its name, but let's go this way:
$ cat myfunction.mk
define call_script
set +x
mkdir -p $$(dirname $(2))
if [ ! -f $(2) ]; then
echo "" > $(2)
fi
if [ "$($(4))" = "yes" ]; then
REDIRECT='| tee -a'
else
REDIRECT='&>>'
fi
echo '>> $(1)'
eval "$(1) $$REDIRECT $(2)"
RET_CODE=$$?
echo "exit_code is: $$RET_CODE"
if [ ! $$RET_CODE = 0 ]; then
echo "$(3) terminated with error $$RET_CODE"
exit $$RET_CODE
else
if [ ! -z "$(strip $(3))" ]; then
echo "$(3) done"
fi
fi
endef
$ cat Makefile
.ONESHELL:
include myfunction.mk
OUTPUT_ENABLED ?= yes
target:
$(call call_script,echo "test",reports/mylog.log,doing test,OUTPUT_ENABLED)
Note that I moved the .ONESHELL: in the main Makefile because it is probably better to not hide it inside an included file. Up to you.
The most problematic issue here is that if you pipe your commands, the exit code is the exit code of the last command in a pipe, e.g false | tee foo.log will exit with 0 as tee will most probably succeed. Note also that pipe only redirects stdout, so your log will not contain any stderr messages unless explicitly redirected.
Considering that piping commands influence exit code and lack of portability of $PIPESTATUS (most specifically not being supported in dash), I would try to avoid piping commands and use a temporary file for gathering output, i.e.:
$ cat Makefile
# $(1) - script to execute
# $(2) - log file
# $(3) - description
define call_script
echo '>> $(1)'
$(if $(OUTPUT_ENABLED), \
$(1) > $#.log 2>&1; RET_CODE=$$?; mkdir -p $(dir $(2)); cat $#.log >> $(2); cat $#.log; rm -f $#.log, \
$(1); RET_CODE=$$? \
); \
echo "EXIT_CODE is: $${RET_CODE}"; \
if [ $${RET_CODE} -ne 0 ]; then $(if $(3),echo "$(3) terminated with error $${RET_CODE}";) exit $${RET_CODE}; fi; \
$(if $(3), echo "$(3) done.")
endef
good:
$(call call_script,echo "test",reports/mylog.log,doing test)
bad:
$(call call_script,mkdir /root/foo,reports/mylog.log,intentional fail)
ugly:
$(call call_script,bad_command,reports/mylog.log)
Regular call will not create the logs and will stop on errors:
$ make good bad ugly
echo '>> echo "test"'
>> echo "test"
echo "test"; RET_CODE=$? ; echo "EXIT_CODE is: ${RET_CODE}"; if [ ${RET_CODE} -ne 0 ]; then echo "doing test terminated with error ${RET_CODE}"; exit ${RET_CODE}; fi; echo "doing test done."
test
EXIT_CODE is: 0
doing test done.
echo '>> mkdir /root/foo'
>> mkdir /root/foo
mkdir /root/foo; RET_CODE=$? ; echo "EXIT_CODE is: ${RET_CODE}"; if [ ${RET_CODE} -ne 0 ]; then echo "intentional fail terminated with error ${RET_CODE}"; exit ${RET_CODE}; fi; echo "intentional fail done."
mkdir: cannot create directory ‘/root/foo’: Permission denied
EXIT_CODE is: 1
intentional fail terminated with error 1
make: *** [Makefile:19: bad] Error 1
Note that ugly was not built due to failure on bad. Now the same with the log:
$ make good bad ugly OUTPUT_ENABLED=1
echo '>> echo "test"'
>> echo "test"
echo "test" > good.log 2>&1; RET_CODE=$?; mkdir -p reports/; cat good.log >> reports/mylog.log; cat good.log; rm -f good.log; echo "EXIT_CODE is: ${RET_CODE}"; if [ ${RET_CODE} -ne 0 ]; then echo "doing test terminated with error ${RET_CODE}"; exit ${RET_CODE}; fi; echo "doing test done."
test
EXIT_CODE is: 0
doing test done.
echo '>> mkdir /root/foo'
>> mkdir /root/foo
mkdir /root/foo > bad.log 2>&1; RET_CODE=$?; mkdir -p reports/; cat bad.log >> reports/mylog.log; cat bad.log; rm -f bad.log; echo "EXIT_CODE is: ${RET_CODE}"; if [ ${RET_CODE} -ne 0 ]; then echo "intentional fail terminated with error ${RET_CODE}"; exit ${RET_CODE}; fi; echo "intentional fail done."
mkdir: cannot create directory ‘/root/foo’: Permission denied
EXIT_CODE is: 1
intentional fail terminated with error 1
make: *** [Makefile:19: bad] Error 1
$ cat reports/mylog.log
test
mkdir: cannot create directory ‘/root/foo’: Permission denied
Note that this time ugly was also not run. But if run later, it will correctly append to the log:
$ make ugly OUTPUT_ENABLED=1
echo '>> bad_command'
>> bad_command
bad_command > ugly.log 2>&1; RET_CODE=$?; mkdir -p reports/; cat ugly.log >> reports/mylog.log; cat ugly.log; rm -f ugly.log; echo "EXIT_CODE is: ${RET_CODE}"; if [ ${RET_CODE} -ne 0 ]; then exit ${RET_CODE}; fi;
/bin/sh: 1: bad_command: not found
EXIT_CODE is: 127
make: *** [Makefile:22: ugly] Error 127
$ cat reports/mylog.log
test
mkdir: cannot create directory ‘/root/foo’: Permission denied
/bin/sh: 1: bad_command: not found
Personally I am not fan of implementing logging in this way. It is complicated and it only logs output of commands, not make output itself, and only of those commands which are explicitly called to do so. I'd rather keep Makefile clean and simple and just run make 2>&1 | tee log instead to have the output logged.
I cannot get the gnu parallel function to implement a custom function that I built.
My function is:
function run_cuffLinks() {
inputBAM="${HOME}/Analyses/P_miniata/CleanUpPipeline/TH_${1}/${1}.realigned.bam"
if [[ ! -f $inputBAM ]]; then echo -e "$inputBAM could not be found\nexit 1" ; fi
WORKING_DIR="${HOME}/data/CuffLinks/TH_$1"
if [[ ! -d $WORKING_DIR ]]; then mkdir -p $WORKING_DIR; fi
REF="${HOME}/ReferenceSequences/GATK_pmin.scaf.fa"
if [[ ! -f $REF ]]; then echo -e "$inputBAM could not be found\nexit 1" ; exit 1; fi
GTF_FILE="${HOME}/ReferenceSequences/genes.sorted.gff3"
if [[ ! -f $GTF_FILE ]]; then echo -e "$inputBAM could not be found\nexit 1" ; exit 1; fi
cufflinks \
--output-dir $WORKING_DIR \
--num-threads 2 \
--frag-len-mean 100 \
--GTF-guide $GTF_FILE \
--frag-bias-correct $REF \
-L "HH" \
$inputBAM ;
}
When I enter:
parallel --no-notice -j+2 run_cuffLinks {} ::: sample1 sample2 sample3
I get the output:
/bin/bash: run_cuffLinks: command not found
/bin/bash: run_cuffLinks: command not found
/bin/bash: run_cuffLinks: command not found
If I include a '$' symbol in front of the function name, I get:
/bin/bash: sample1: command not found
/bin/bash: sample2: command not found
/bin/bash: sample3: command not found
I have also tried using the -pipe --recend and --rrs options, but without a positive result.
Is GNU parallel not able to process user-defined functions?
You do not write whether you have walked through the tutorial (man parallel_tutorial). In that it shows that you must export -f the function, and since you do not write that, I believe you might have forgotten that:
export -f run_cuffLinks
parallel ...
Since version 20180522 you can also use env_parallel:
env_parallel --session
[define functions and variables here that you want parallel to see]
# Use env_parallel like you would parallel
env_parallel run_cuffLinks ...
PS: Use --bibtex once to avoid --no-notice in the future.
I try to write a GPU program using CUDA. Below is my function:
__global__ static void
histogram_gpu(int * hist_out, unsigned char * img_in, int img_size, int nbr_bin){
int i;
const int bid = blockIdx.x;
const int tid = threadIdx.x;
// for ( i = 0; i < img_size; i ++){
// hist_out[img_in[i]] ++;
// }
for (i = bid*THREAD_NUM + tid; i < img_size; i += BLOCK_NUM*THREAD_NUM) {
hist_out[img_in[i]]++;
}
}
When I call this function in the main function, there's an error occurs:
error: ‘blockIdx’ was not declared in this scope
I use the CUDA 5.0 on my MAC machine, and below is the Makefile:
OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:])
OSLOWER = $(shell uname -s 2>/dev/null | tr [:upper:] [:lower:])
# Flags to detect 32-bit or 64-bit OS platform
OS_SIZE = $(shell uname -m | sed -e "s/i.86/32/" -e "s/x86_64/64/")
OS_ARCH = $(shell uname -m | sed -e "s/i386/i686/")
# These flags will override any settings
ifeq ($(i386),1)
OS_SIZE = 32
OS_ARCH = i686
endif
ifeq ($(x86_64),1)
OS_SIZE = 64
OS_ARCH = x86_64
endif
# Flags to detect either a Linux system (linux) or Mac OSX (darwin)
DARWIN = $(strip $(findstring DARWIN, $(OSUPPER)))
# Location of the CUDA Toolkit binaries and libraries
CUDA_PATH ?= /Developer/NVIDIA/CUDA-5.0
CUDA_INC_PATH ?= $(CUDA_PATH)/include
CUDA_BIN_PATH ?= $(CUDA_PATH)/bin
ifneq ($(DARWIN),)
CUDA_LIB_PATH ?= $(CUDA_PATH)/lib
else
ifeq ($(OS_SIZE),32)
CUDA_LIB_PATH ?= $(CUDA_PATH)/lib
else
CUDA_LIB_PATH ?= $(CUDA_PATH)/lib64
endif
endif
# Common binaries
NVCC ?= $(CUDA_BIN_PATH)/nvcc
GCC ?= g++
# Extra user flags
EXTRA_NVCCFLAGS ?=
EXTRA_LDFLAGS ?=
# CUDA code generation flags
GENCODE_SM10 := -gencode arch=compute_10,code=sm_10
GENCODE_SM20 := -gencode arch=compute_20,code=sm_20
GENCODE_SM30 := -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35
GENCODE_FLAGS := $(GENCODE_SM10) $(GENCODE_SM20) $(GENCODE_SM30)
GENCODE_FLAGS := $(GENCODE_SM10) $(GENCODE_SM20) $(GENCODE_SM30)
# OS-specific build flags
# ifneq ($(DARWIN),)
# LDFLAGS := -Xlinker -rpath $(CUDA_LIB_PATH) -L$(CUDA_LIB_PATH) -lcudart -lcublas -lcuda -lcufft -ltlshook
# CCFLAGS := -arch $(OS_ARCH)
# else
# ifeq ($(OS_SIZE),32)
# LDFLAGS := -L$(CUDA_LIB_PATH) -lcudart
# CCFLAGS := -m32
# else
LDFLAGS := -L$(CUDA_LIB_PATH) -lcudart -lcublas -lcuda -lcufft -ltlshook
CCFLAGS := -m64
# endif
# endif
# OS-architecture specific flags
ifeq ($(OS_SIZE),32)
NVCCFLAGS := -m32
else
NVCCFLAGS := -m64
endif
# Debug build flags
ifeq ($(dbg),1)
CCFLAGS += -g
NVCCFLAGS += -g -G
TARGET := debug
else
TARGET := release
endif
# Common includes and paths for CUDA
INCLUDES := -I$(CUDA_INC_PATH) -I. -I.. -I../../common/inc
# Add source files here
EXECUTABLE := 5kk70-assignment-gpu
# Cuda source files (compiled with cudacc)
CUFILES :=
# C/C++ source files (compiled with gcc / c++)
CCFILES := main.cpp histogram-equalization.cu contrast-enhancement.cu
################################################################################
# Rules and targets
# All Phony Targets
.PHONY : everything clean
# Default starting position
everything : $(EXECUTABLE)
# Common includes and paths for CUDA
# INCLUDES := -I$(CUDA_INC_PATH) -I. -I.. -I$(CUDA_INC_PATH)/samples/common/inc/
# Clean OBJECTS
clean :
rm -f $(EXECUTABLE) $(OBJ)
$(EXECUTABLE) : $(CCFILES)
$(NVCC) -o $# $^ $(INCLUDES) $(LDFLAGS) $(EXTRA_LDFLAGS) $(GENCODE_FLAGS)
What's the problem with my code?
This problem will occur when you are writing cuda code that is inside a file named .cpp, and you go to compile it. Rename the file to .cu, and the compiler will not complain at you.
In a bazel build rule, try putting the .cu.cc file in the hdrs rather than srcs.
I've read almost all questions about CUDA, C++ & makefiles here, but still can't figure solution to my problem.
I have a some .cpp files & some .cu files inside src/ directory of my project (along with .h & .cuh), and I'd like to build my application with a makefile.
I have tried to do it this way:
SRC_DIR = src
OBJ_DIR = obj
CPP_FILES = $(wildcard $(SRC_DIR)/*.cpp)
CU_FILES = $(wildcard $(SRC_DIR)/*.cu)
H_FILES = $(wildcard $(SRC_DIR)/*.h)
CUH_FILES = $(wildcard $(SRC_DIR)/*.cuh)
OBJ_FILES = $(addprefix $(OBJ_DIR)/,$(notdir $(CPP_FILES:.cpp=.o)))
CUO_FILES = $(addprefix $(OBJ_DIR)/,$(notdir $(CU_FILES:.cu=.cu.o)))
$(TARGET) : $(OBJ_FILES) $(CUO_FILES)
$(LD) $(LDFLAGS) $(LIB_CUDA) -o $# $?
$(CUO_FILES) : $(CU_FILES) $(CUH_FILES)
$(NVCC) $(NVCCFLAGS) $(INCLUDES) -c -o $# $<
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp $(H_FILES)
$(NVCC) $(NVCCFLAGS) $(INCLUDES) -c -o $# $<
And it was OK until I've got a second .cu file.
And then I tried:
<... previous part stays the same ...>
OBJS = $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(notdir $(CPP_FILES)))
OBJS += $(patsubst %.cu,$(OBJ_DIR)/%.cu.o,$(notdir $(CU_FILES)))
$(TARGET) : $(OBJS)
$(LD) $(LDFLAGS) $(LIB_CUDA) -o $# $?
$(OBJ_DIR)/%.cu.o : $(SRC_DIR)/%.cu $(CUH_FILES)
$(NVCC) $(NVCCFLAGS) $(INCLUDES) -c -o $# $<
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp $(H_FILES)
$(NVCC) $(NVCCFLAGS) $(INCLUDES) -c -o $# $<
But make can't figure out how to make any of the .cu.o files now.
How should I modify this thing to build my application?
Thanks in advance!
Upd - output of make with second makefile:
/usr/local/cuda/bin/nvcc -I/usr/local/cuda/include -c -o obj/main.o src/main.cpp
/usr/local/cuda/bin/nvcc -I/usr/local/cuda/include -c -o obj/util.o src/util.cpp
make: *** No rule to make target `obj/thrust.cu.o', needed by `DCG'. Stop.
project files (src/):
main.cpp
utils.h
util.cpp
thrust.cu
thrust.cuh
cuda-utils.cu
cuda-utils.cuh
Either you have a syntax error in your Makefile somewhere you are not showing, or the layout of your project isn't as you have described. If I take this model of your Makefile:
TARGET = nothing
SRC_DIR = src
OBJ_DIR = obj
CPP_FILES = $(wildcard $(SRC_DIR)/*.cpp)
CU_FILES = $(wildcard $(SRC_DIR)/*.cu)
H_FILES = $(wildcard $(SRC_DIR)/*.h)
CUH_FILES = $(wildcard $(SRC_DIR)/*.cuh)
OBJ_FILES = $(addprefix $(OBJ_DIR)/,$(notdir $(CPP_FILES:.cpp=.o)))
CUO_FILES = $(addprefix $(OBJ_DIR)/,$(notdir $(CU_FILES:.cu=.
OBJS = $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(notdir $(CPP_FILES)))
OBJS += $(patsubst %.cu,$(OBJ_DIR)/%.cu.o,$(notdir $(CU_FILES)))
$(TARGET) : $(OBJS)
echo "linking rule : " -o $# $?
$(OBJ_DIR)/%.cu.o : $(SRC_DIR)/%.cu $(CUH_FILES)
echo ".cu.o rule : " $# $<
touch $#
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp $(H_FILES)
echo ".o rule : " $# $<
touch $#
and then I make a model of what you have described:
$ mkdir src
$ mkdir obj
$ touch src/main.cpp
$ touch src/cuda-utils.cuh
$ touch src/thrust.cu
$ touch src/cuda-utils.cu
$ touch src/util.cpp
$ touch src/main.cpp
$ ls
Makefile obj src
$ ls src
cuda-utils.cu cuda-utils.cuh main.cpp thrust.cu util.cpp
$ ls obj
and then I run make:
$ make
echo ".o rule : " obj/main.o src/main.cpp
.o rule : obj/main.o src/main.cpp
touch obj/main.o
echo ".o rule : " obj/util.o src/util.cpp
.o rule : obj/util.o src/util.cpp
touch obj/util.o
echo ".cu.o rule : " obj/cuda-utils.cu.o src/cuda-utils.cu
.cu.o rule : obj/cuda-utils.cu.o src/cuda-utils.cu
touch obj/cuda-utils.cu.o
echo ".cu.o rule : " obj/thrust.cu.o src/thrust.cu
.cu.o rule : obj/thrust.cu.o src/thrust.cu
touch obj/thrust.cu.o
echo "linking rule : " -o nothing obj/main.o obj/util.o obj/cuda-utils.cu.o obj/thrust.cu.o
linking rule : -o nothing obj/main.o obj/util.o obj/cuda-utils.cu.o obj/thrust.cu.o
$ ls obj
cuda-utils.cu.o main.o thrust.cu.o util.o
I get exactly what is expected. So if you are having a problem, it is not coming from what you have posted in your question (after the several "typos" in the original version were fixed).