meson incorrect handling cuda nvcc flags - cuda

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.

Related

Octave: how to specify arguments for mkoctfile

Im am using octave under windows (native) and try to compile a c++ program into a mex file and link some libraries to it:
% compile for octave
cmd = sprintf("mex main.cpp -I\"%s\\Winnt\\Include\" -L\"%s\\Winnt\\lib_x64\\msc\" -lvisa64.lib", ...
getenv('VXIPNPPATH'), getenv('VXIPNPPATH'))
eval(cmd);
When run, the output of the command is:
>> mex main.cpp -I'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\Include' -L'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\lib_x64\msc' -lvisa64.lib
g++: error: Files: No such file or directory
g++: error: (x86)\IVI: No such file or directory
g++: error: Foundation\VISA\\Winnt\lib_x64\msc: No such file or directory
warning: mkoctfile: building exited with failure status
I also tried to run the string directly from the command line:
mex main.cpp -I'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\Include' -L'C:\Program Files (x86)\IVI Foundation\VISA\\Winnt\lib_x64\msc' -lvisa64.lib
with the same result.
While the -I command appears to work well, why does the -L argument causes problems? What would be the right way to escape the path names with spaces?
Double quotes also won't work.
EDIT
Based on the answers, I am using mex() in its functional form, but the result is still the same:
vxipath = getenv('VXIPNPPATH');
params={};
params{1} = sprintf('-I%s', fullfile(vxipath, 'Winnt', 'Include'));
params{2} = sprintf('-L%s', fullfile(vxipath, 'Winnt', 'lib_x64', 'msc'));
params{3} = sprintf('-lvisa64.lib');
% replace \ with /
for i1=1:length(params)
s = params{i1};
s(s=='\') = '/';
params{i1} = s;
end
params
mex("main.cpp", params{:});
Gives the output:
params =
{
[1,1] = -IC:/Program Files (x86)/IVI Foundation/VISA/Winnt/Include
[1,2] = -LC:/Program Files (x86)/IVI Foundation/VISA/Winnt/lib_x64/msc
[1,3] = -lvisa64.lib
}
g++: error: Files: No such file or directory
g++: error: (x86)/IVI: No such file or directory
g++: error: Foundation/VISA/Winnt/lib_x64/msc: No such file or directory
warning: mkoctfile: building exited with failure status
Which is the same result as before. Additional observations are:
'/' or '\' does not make a difference
if I omit all parameters, I get a missing-include-file-error: OK
if I omit the '-L' argument, I get a missing-lib-file-error: OK
if I add the '-L' argument, I get the error shown above: It appears that the -L argument behaves differently than the -I argument.
I also tried it directly from the bash shell with the corresponding command with the same result.
Replace backslashes with slashes and place each argument inside single quotes.
mex 'main.cpp' '-IC:/Program Files (x86)/IVI Foundation/VISA//Winnt/Include' '-LC:/Program Files (x86)/IVI Foundation/VISA//Winnt/lib_x64/msc' '-lvisa64.lib'
or
mex ('main.cpp', '-IC:/Program Files (x86)/IVI Foundation/VISA//Winnt/Include', '-LC:/Program Files (x86)/IVI Foundation/VISA//Winnt/lib_x64/msc', '-lvisa64.lib')
This doesn't answer the how to fix it, as rahnema1 already did that. But I'll show you how to simplify your code.
Do not use eval. eval is evil.
Instead of evaluating a string function paramA paramB, call function directly with string input arguments. function paramA paramB is translated by the interpreter to a call function('paramA','paramB'). But it is a lot easier to generate the latter form, and you get to avoid eval to boot:
params = {};
params{1} = '-IC:/Program Files (x86)/IVI Foundation/VISA//Winnt/Include';
params{2} = '-LC:/Program Files (x86)/IVI Foundation/VISA//Winnt/lib_x64/msc';
params{2} = '-lvisa64.lib';
mex('main.cpp', params{:});
Properly generate paths using fullfile. It adds / or \ depending on which platform you're on, plus I find it easier to read:
include_path = fullfile(getenv('VXIPNPPATH'), 'Winnt', 'Include');
params{1} = ['-I', include_path];
mkoctfile does not escape the arguments properly if they contain spaces and it does not like backslashes in Octave's own paths.
It creates the following two commands:
g++ -c -I/release/mxe-octave-w64/usr/x86_64-w64-mingw32/include -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave\.. -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave -IC:\Octave\OCTAVE~1.0\\mingw64\include -fopenmp -g -O2 -I. "-IC:\Program Files (x86)\IVI Foundation\VISA\Winnt\Include" -DMEX_DEBUG main.cpp -o C:\Octave\OCTAVE~1.0\tmp/oct-u4r15I.o
g++ -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave\.. -IC:\Octave\OCTAVE~1.0\\mingw64\include\octave-5.1.0\octave -IC:\Octave\OCTAVE~1.0\\mingw64\include -fopenmp -g -O2 -shared -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols -o main.mex C:\Octave\OCTAVE~1.0\tmp/oct-u4r15I.o -lvisa64.lib -LC:\Program Files (x86)\IVI Foundation\VISA\Winnt\lib_x64\msc -LC:\Octave\OCTAVE~1.0\\mingw64\lib\octave\5.1.0 -LC:\Octave\OCTAVE~1.0\\mingw64\lib -LC:\Octave\OCTAVE~1.0\\mingw64\lib\octave\5.1.0 -loctinterp -loctave -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols
When I change it to the following:
replace \ with /
specify the library name without .lib extension
escape -LC:\Program Files... to "-LC:\Program Files..."
g++ -c -I/release/mxe-octave-w64/usr/x86_64-w64-mingw32/include -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave/.. -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave -IC:/Octave/OCTAVE~1.0//mingw64/include -fopenmp -g -O2 -I. "-IC:/Program Files (x86)/IVI Foundation/VISA/Winnt/Include" -DMEX_DEBUG main.cpp -o C:/Octave/OCTAVE~1.0/tmp/oct-u4r15I.o
g++ -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave/.. -IC:/Octave/OCTAVE~1.0//mingw64/include/octave-5.1.0/octave -IC:/Octave/OCTAVE~1.0//mingw64/include -fopenmp -g -O2 -shared -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols -o main.mex C:/Octave/OCTAVE~1.0/tmp/oct-u4r15I.o "-LC:/Program Files (x86)/IVI Foundation/VISA/Winnt/lib_x64/msc" -lvisa64 -LC:/Octave/OCTAVE~1.0//mingw64/lib/octave/5.1.0 -LC:/Octave/OCTAVE~1.0//mingw64/lib -LC:/Octave/OCTAVE~1.0//mingw64/lib/octave/5.1.0 -loctinterp -loctave -Wl,-rpath-link,/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/lib -L/release/mxe-octave-w64/usr/x86_64-w64-mingw32/qt5/lib -Wl,--export-all-symbols
It will compile without error.

CUDA separable compilation and CMake

I have a large library project that contains both cpp and cu source files. I'd like to compile it in a standalone shared object, but since I have some device functions I decided to split it in a shared object containing the majority of the functions and an archive file containing the device functions only. Here's part of the Makefile I wrote for it - all the (non-template) device functions have been put in the file device.cu:
Makefile
LIB_NAME = libexample.so
CUDA = /usr/local/cuda/include
CXX = g++
CXXFLAGS = -c -O2 -fPIC -Wall -I. -I./code -I./code/header -I$(CUDA)
SOURCES = src1.cpp src2.cpp src3.cpp
OBJECTS = $(SOURCES:.cpp=.o)
NVCC = nvcc
CU_SOURCES = src1_cu.cu src2_cu.cu src3_cu.cu device.cu
CU_OBJECTS = $(CU_SOURCES:.cu=.o)
BUILDDIR = .
VPATH = code/src/common_src code/src/src_CUDA
DEVICE_LINK = dev_link.o
GENCODE_FLAGS := -gencode arch=compute_20,code=sm_20
NVCCFLAGS = -x cu -O2 --compiler-options '-fPIC' $(GENCODE_FLAGS) -I. -I./code -I./code/header -I$(CUDA) -dc
NVCCLINK = --compiler-options '-fPIC' $(GENCODE_FLAGS) -dlink
all: lib/$(LIB_NAME)
lib/$(LIB_NAME): $(OBJECTS) $(CU_OBJECTS) $(DEVICE_LINK)
$(CXX) -shared -Wl,-soname,libexample.so $^ -o $#
ar rcs lib/device.a device.o
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
%.o: %.cu
$(NVCC) $(NVCCFLAGS) $< -o $#
$(DEVICE_LINK): $(CU_OBJECTS)
$(NVCC) $(NVCCLINK) $^ -o $#
I decided to change my build system and I switched to CMake to produce both Makefiles and Visual Studio projects. It's obvious how to write a working CMakeLists.txt file without separable compilation, but I couldn't find a solution that works in my case (I read some proposed solutions here on S.O. but they don't seem to work for me!). Can you help me to write said CMakeLists.txt file? Here's what I did so far:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.10)
# Set Library & project name
set(LIB_NAME example)
project(${LIB_NAME})
message("LIBRARY ${LIB_NAME}")
enable_language(CXX)
# Check if CUDA is installed on this system
find_package(CUDA REQUIRED)
# Set source directories
set(COMMON_SRCS_DIR ${CMAKE_SOURCE_DIR}/code/src/common_src)
set(CUDA_SRCS_DIR ${CMAKE_SOURCE_DIR}/code/src/src_CUDA)
# Set source files
set(COMMON_SRCS ${COMMON_SRCS_DIR}/src1.cpp
${COMMON_SRCS_DIR}/src2.cpp
${COMMON_SRCS_DIR}/src3.cpp
)
# Set CUDA device library name
set(DEVICE_LIB "device")
# Set CUDA objects
cuda_compile(SRC1_CU_O ${CUDA_SRCS_DIR}/src1_cu.cu)
cuda_compile(SRC2_CU_O ${CUDA_SRCS_DIR}/src2_cu.cu)
cuda_compile(SRC3_CU_O ${CUDA_SRCS_DIR}/src3_cu.cu)
cuda_compile(DEVICE_CU_O ${CUDA_SRCS_DIR}/device.cu)
# Set header file directories
include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/code)
include_directories(${CMAKE_SOURCE_DIR}/code/header)
include_directories(${CUDA_INCLUDE_DIRS})
# Get CUDA compute capability - contains CUDA_GENCODE define
include(CudaParams.cmake)
# Set include stuff
cuda_include_directories(${CMAKE_SOURCE_DIR})
cuda_include_directories(${CMAKE_SOURCE_DIR}/code)
cuda_include_directories(${CMAKE_SOURCE_DIR}/code/header)
cuda_include_directories(${CUDA_INCLUDE_DIRS})
set(CUDA_SEPARABLE_COMPILATION ON)
# Set compiler flags
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} ${CUDA_GENCODE} --compiler-options '-fPIC' -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -march=native -O2")
# Generate main target
cuda_add_library(${LIB_NAME} SHARED ${COMMON_SRCS}
${SRC1_CU_O} ${SRC2_CU_O} ${SRC3_CU_O} ${DEVICE_CU_O})
cuda_add_library(${DEVICE_LIB} STATIC ${DEVICE_CU_O})
# Install instructions
INSTALL(TARGETS ${LIB_NAME}
LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/lib
ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/lib
)
As you can see, there's no dev_link.o mention in the CMakeLists.txt file because I simply don't know where I could put it!

error: ‘blockIdx’ was not declared in this scope

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.

makefile for C++/CUDA project

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).

Linking error in C and Mysql

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