makefile for C++/CUDA project - cuda

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

Related

meson incorrect handling cuda nvcc flags

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.

variable expansion in subshell in makefile fails

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.

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!

jade output path directory using the makefile

I'm using the makefile to compile jade file into html. How should I amend this line with jade options so that my ultimate index.html is one level up in the directory and not in the same folder as the jade files? Currently, I'm having the index.html inside the folder jade.
%.html: %.jade
jade < $< --out $< --path $< --pretty > $#
I would want the folder structure to be like this:
|--jade
|--index.jade
|--index.html
I do not want my folder structure to be like this:
|--jade
|--index.jade
|--index.html
my entire makefile includes:
JADE = $(shell find jade/*.jade)
HTML = $(JADE:.jade=.html)
all: $(HTML)
%.html: %.jade
jade < $< --out $< --path $< --pretty > $#
clean:
rm -f $(HTML)
.PHONY: clean
If you want all html files to go into the directory one level up:
JADE = $(shell find jade/*.jade)
HTML = $(patsubst jade/%.jade, %.html, $(JADE))
all: $(HTML)
%.html: jade/%.jade
jade < $< --out $< --path $< --pretty > $#
If you want index.html to go into the upper directory, but all other html files to go into jade/:
JADE = $(shell find jade/*.jade)
HTML := $(JADE:.jade=.html)
HTML := $(subst jade/index.html, index.html, $(HTML))
all: $(HTML)
%.html: %.jade
jade < $< --out $< --path $< --pretty > $#
index.html: jade/index.jade
jade < $< --out $< --path $< --pretty > $#
If there are many html files which should go into the upper directory, you can construct the HTML list any way you like, and then:
%.html: %.jade
jade < $< --out $< --path $< --pretty > $#
%.html: jade/%.jade
jade < $< --out $< --path $< --pretty > $#

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