Can not link libmysqlclient.a? - mysql

I'm using Ubuntu 14.04, and I installed libmysqlclient-dev package already. But I always get link error because mysql_init symbol missing.
My source code, Makefile, run-time result and symbol info are as follows:
igsrd#naivechou/~/project/m01/uuid_sign>cat main.cpp
#include <cstdio>
#include <cstdlib>
#include "mysql/mysql.h"
int main(int argc,char** argv)
{
auto con = mysql_init(nullptr);
//printf("mysql client version : %s\n",mysql_get_client_info());
exit(EXIT_SUCCESS);
}
igsrd#naivechou/~/project/m01/uuid_sign>LANG= && make -B
g++ -o main.o -c main.cpp -std=c++11 -ggdb
g++ -o uuid_sign -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -ldl main.o
main.o: In function `main':
/home/igsrd/project/m01/uuid_sign/main.cpp:6: undefined reference to `mysql_init'
collect2: error: ld returned 1 exit status
make: *** [uuid_sign] Error 1
igsrd#naivechou/~/project/m01/uuid_sign>nm -C /usr/lib/x86_64-linux-gnu/libmysqlclient.a | grep mysql_init
0000000000002b10 T mysql_init
0000000000002d30 T mysql_init_character_set
U mysql_init_character_set
Source is very simple, just one line to call mysql_init().
Making process shows every options for compiler and linker, I think there are no missing options.
Error message is undefined reference of linking error, so I dump libmysqlclient.a to grep the mysql_init, and it is not on undefined state.
Now I really have no idea. What's wrong with this ?

Change your second command, try this (change the position of main.o):
g++ -o uuid_sign main.o -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -ldl

Related

mysql.h compile, but not its functions

I am trying to see how to embed sql code in a C program, but I have an issue I am not able to understand when I compile this code :
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
MYSQL *mysql;
MYSQL_RES *results;
MYSQL_ROW record;
int main() {
mysql = mysql_init(NULL);
if (mysql == NULL) {
fprintf(stderr, "%s\n", mysql_error(mysql));
return 1;
}
if (mysql_real_connect(mysql, "localhost", "root", "PassWord",
NULL, 0, NULL, 0) == NULL) {
fprintf(stderr, "%s\n", mysql_error(mysql));
mysql_close(mysql);
return 1;
}
mysql_query(mysql, "SHOW DATABASES");
return 0;
}
this is what the compiler tell me when I compile it :
clang++ -g -c testSql.cc
clang++ testSql.o -o testSql
/usr/bin/ld: testSql.o: in function `main':
/home/antoine/Documenti/L3/Information Management II/code/testSql.cc:12: undefined reference to `mysql_init'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:15: undefined reference to `mysql_error'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:19: undefined reference to `mysql_real_connect'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:21: undefined reference to `mysql_error'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:22: undefined reference to `mysql_close'
/usr/bin/ld: /home/antoine/Documenti/L3/Information Management II/code/testSql.cc:26: undefined reference to `mysql_query'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:25: testSql] Errore 1
I have check in the mysql.h file, those function are implemented, so I do not understand why I have this "undifined reference" error, do any onehave an idea on the origin of this error ?
Thank you all for the answer. I had to provide a linker in my compilation.
I am now compiling with
clang++ -g -c testSql.cc
clang++ testSql.o -o testSql `mysql_config --cflags --libs`
instead of
clang++ -g -c testSql.cc
clang++ testSql.o -o testSql
and it compile correctly.
Thank you !

PTX kernel name mangling

I cannot link my Cuda program when a kernel is compiled from ptx file.
main.cu:
extern
__global__ void kernel(int, float*);
int main()
{
...
kernel<<<...>>>(...);
...
}
kernel.cu
__global__
void kernel(int n, float* p)
{
...
}
If I compile like below, I have no problems and I get an executable:
nvcc -dc main.cu kernel.cu --gpu-architecture=sm_70
nvcc -dlink main.o kernel.o --gpu-architecture=sm_70 -o dlink.o
g++ dlink.o main.o kernel.o -lcudart
If I compile like below (by generating ptx), I get errors:
nvcc -ptx kernel.cu --gpu-architecture=sm_70
nvcc -dc main.cu kernel.ptx --gpu-architecture=sm_70
nvcc -dlink main.o kernel.o --gpu-architecture=sm_70 -o dlink.o
g++ dlink.o main.o kernel.o -lcudart
Error:
main.o: In function `main':
tmpxft_0000b5ce_00000000-5_main.cudafe1.cpp:(.text+0x4789): undefined reference to `kernel(int, float*)'
tmpxft_0000b5ce_00000000-5_main.cudafe1.cpp:(.text+0x497e): undefined reference to `kernel(int, float*)'
collect2: error: ld returned 1 exit status
I am following an example from CUDA_Compiler_Driver_NVCC.pdf.
What do I need to do to fix the error?
(This is CUDA 10.2).
If you want to write your own PTX (or modify PTX), the proper CUDA methodology to use is the CUDA driver API and associated compilation flow.
The CUDA vectorAddDrv sample code has all the plumbing and workflow that you need.

Cuda compiling error when coming to g++ compiling step

nvcc -D_DEBUG --use_fast_math -I"/usr/local/cuda-9.0//include" -I"/usr/include/eigen3" -I"/home/xingfu/NVIDIA_CUDA-9.0_Samples/common/inc" -dlink --machine 64 -arch=sm_50 -c -o kernel_cuda.o ../CudaTest/kernel.cu
g++ -c -pipe -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_CORE_LIB -I../CudaTest -I. -I/usr/local/cuda-9.0/include -isystem /usr/include/eigen3 -I../NVIDIA_CUDA-9.0_Samples/common/inc -isystem /usr/local/include -I../Qt5.11.0/5.11.0/gcc_64/include -I../Qt5.11.0/5.11.0/gcc_64/include/QtCore -I. -I../Qt5.11.0/5.11.0/gcc_64/mkspecs/linux-g++ -o LBDM.o ../CudaTest/LBDM.cpp
The two steps above have passed, however, when run the following step, the error occured:
g++ -Wl,-rpath,/home/xingfu/Qt5.11.0/5.11.0/gcc_64/lib -o CudaTest kernel_cuda.o LBDM.o -L/usr/local/cuda-9.0//lib64/ -lcuda -lcudart -lcublas -L/home/xingfu/CudaTest/../../../usr/local/lib/ -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -L/home/xingfu/Qt5.11.0/5.11.0/gcc_64/lib -lQt5Core -lpthread
The compiler error shows:
kernel_cuda.o: In function `__sti____cudaRegisterAll()':
tmpxft_00000e7d_00000000-5_kernel.cudafe1.cpp:(.text+0x177e): undefined reference to `__cudaRegisterLinkedBinary_41_tmpxft_00000e7d_00000000_6_kernel_cpp1_ii_channel'
How can I fix the error?
What's more,
I add the -dlink, because it shows the error when dealing the following step:
nvcc -D_DEBUG --use_fast_math -I"/usr/local/cuda-9.0//include" -I"/usr/include/eigen3" -I"/home/xingfu/NVIDIA_CUDA-9.0_Samples/common/inc" --machine 64 -arch=sm_50 -c -o kernel_cuda.o ../CudaTest/kernel.cu
and the error is:
ptxas fatal : Unresolved extern function 'cublasCreate_v2'
However, when I add -dlink, the error occured like I said above.
BTW, before I add -dlink, I can run a simple function in another test project like this:
__global__ void add(float* x, float * y, float* z, int n)
{
int index = threadIdx.x + blockIdx.x * blockDim.x;
int stride = blockDim.x * gridDim.x;
for (int i = index; i < n; i += stride)
{
z[i] = x[i] + y[i];
}
}
After I add -dlink, the test project shows an error:
cuda_code_cuda.o: In function `__sti____cudaRegisterAll()':
tmpxft_000017db_00000000-5_cuda_code.cudafe1.cpp:(.text+0x861): undefined reference to `__cudaRegisterLinkedBinary_44_tmpxft_000017db_00000000_6_cuda_code_cpp1_ii_5b538d80'
which is very similar to the above error.
For relocatable device code linking, which seems to be what you're after, the recommended sequence would be as follows. In addition, it appears your code is attempting to use the cublas device interface, so for good measure we'll add those libraries to the link steps:
#replace -dlink -c with -dc
nvcc -D_DEBUG --use_fast_math -I"/usr/local/cuda-9.0//include" -I"/usr/include/eigen3" -I"/home/xingfu/NVIDIA_CUDA-9.0_Samples/common/inc" -dc --machine 64 -arch=sm_50 -o kernel_cuda.o ../CudaTest/kernel.cu
#generate device-linked object with cublas device libraries
nvcc -D_DEBUG --use_fast_math -dlink --machine 64 -arch=sm_50 -o kernel_dlink.o kernel_cuda.o -lcublas -lcublas_device -lcudadevrt
#no change to this line
g++ -c -pipe -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_CORE_LIB -I../CudaTest -I. -I/usr/local/cuda-9.0/include -isystem /usr/include/eigen3 -I../NVIDIA_CUDA-9.0_Samples/common/inc -isystem /usr/local/include -I../Qt5.11.0/5.11.0/gcc_64/include -I../Qt5.11.0/5.11.0/gcc_64/include/QtCore -I. -I../Qt5.11.0/5.11.0/gcc_64/mkspecs/linux-g++ -o LBDM.o ../CudaTest/LBDM.cpp
#add device-linked object to final link phase plus cublas device libraries
g++ -Wl,-rpath,/home/xingfu/Qt5.11.0/5.11.0/gcc_64/lib -o CudaTest kernel_cuda.o LBDM.o kernel_dlink.o -L/usr/local/cuda-9.0//lib64/ -lcuda -lcudart -lcublas -lcublas_device -lcudadevrt -L/home/xingfu/CudaTest/../../../usr/local/lib/ -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -L/home/xingfu/Qt5.11.0/5.11.0/gcc_64/lib -lQt5Core -lpthread

Why do I get a segmentation fault when calling a CUDA kernel directly from a shared library?

The way I tried it (see question title) it compiled, but I get a segmentation fault. So is it me, CMake or CUDA which doesn't support direct kernel calls from a shared library? The solution doesn't have to be with CMake
Further details:
I have the following file structure:
testKernel.hpp
__global__ void kernelTest( float x );
void callKernel( float x );
testKernel.cu
#include "testKernel.hpp"
__global__ void kernelTest( float x ) {}
void callKernel( float x ) { kernelTest<<<1,1>>>( x ); }
useKernel.cu
#include <cstdio>
#include "testKernel.hpp"
int main( void )
{
kernelTest<<<1,1>>>( 3.0f );
//callKernel( 3.0f );
printf("OK\n");
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.3.1)
project(testKernelCall)
find_package(CUDA REQUIRED)
cuda_add_library( ${PROJECT_NAME} SHARED testKernel.cu testKernel.hpp )
target_link_libraries( ${PROJECT_NAME} ${CUDA_LIBRARIES} )
cuda_add_executable("useKernel" useKernel.cu)
target_link_libraries("useKernel" ${PROJECT_NAME})
Compiling and running this with:
cmake .; make && ./useKernel
results in a segmentation fault. The backtrace with gdb is:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff75726bd in cudart::configData::addArgument(void const*, unsigned long, unsigned long) ()
from ./libtestKernelCall.so
(gdb) bt
#0 0x00007ffff75726bd in cudart::configData::addArgument(void const*, unsigned long, unsigned long) ()
from ./libtestKernelCall.so
#1 0x00007ffff7562eb7 in cudart::cudaApiSetupArgument(void const*, unsigned long, unsigned long) ()
from ./libtestKernelCall.so
#2 0x00007ffff7591ca2 in cudaSetupArgument ()
from ./libtestKernelCall.so
#3 0x00007ffff7556125 in __device_stub__Z10kernelTestf (__par0=3)
at /tmp/tmpxft_00003900_00000000-4_testKernel.cudafe1.stub.c:7
#4 0x00007ffff755616c in kernelTest (__cuda_0=3) at ./testKernel.cu:2
#5 0x000000000040280e in main () at ./useKernel.cu:6
Tested with (which means the segfault appears in those setups):
Setup 1
cmake 3.4.1
CUDA 7.0.27
g++ 4.9.2
Debian
Setup 2
cmake 3.3.1
CUDA 6.5.14
g++ 4.7.1
There are two ways to solve this error:
change SHARED to STATIC in CMakeList.txt
use the wrapper function callKernel instead of calling the kernel directly
I don't really know how to build a CUDA shared library without CMake. I know how to build a CUDA static library, but that case seems to work with CMake, so I didn't test it without CMake.
Here are the relevant CMake commands I got with make VERBOSE=1. I changed absolute paths to relative paths, where possible, but I wasn't sure about all these library paths. Putting these commands in a file and sourcing that file compiles the shared library and the program correctly and "correctly" leads to the segmentation fault. I also added command because for me nvcc is aliased with the `-ccbin`` option.
make.sh
command nvcc "./testKernel.cu" -c -o "./testKernel.cu.o" -ccbin /usr/bin/cc -m64 -DtestKernelCall_EXPORTS -Xcompiler ,\"-fPIC\",\"-g\" -DNVCC -I/opt/cuda-7.0/include -I/opt/cuda-7.0/include
/usr/bin/c++ -fPIC -shared -Wl,-soname,libtestKernelCall.so -o libtestKernelCall.so ./testKernel.cu.o /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so
command nvcc "./useKernel.cu" -c -o "./useKernel.cu.o" -ccbin /usr/bin/cc -m64 -Xcompiler ,\"-g\" -DNVCC -I/opt/cuda-7.0/include -I/opt/cuda-7.0/include
/usr/bin/c++ ./useKernel.cu.o -o useKernel -rdynamic /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so libtestKernelCall.so /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so -Wl,-rpath,"."
Your code compiles and runs correctly for me using ordinary nvcc commands (not CMake) if I add the -cudart shared switch to each nvcc command. Here's a fully-worked sequence:
$ cat testKernel.hpp
__global__ void kernelTest( float x );
void callKernel( float x );
$ cat testKernel.cu
#include "testKernel.hpp"
__global__ void kernelTest( float x ) {}
void callKernel( float x ) { kernelTest<<<1,1>>>( x ); }
$ cat useKernel.cu
#include <cstdio>
#include "testKernel.hpp"
int main( void )
{
kernelTest<<<1,1>>>( 3.0f );
//callKernel( 3.0f );
cudaDeviceSynchronize();
printf("OK\n");
return 0;
}
$ nvcc -shared -cudart shared -o test.so -Xcompiler -fPIC testKernel.cu
$ nvcc -cudart shared -o test test.so useKernel.cu
$ cuda-memcheck ./test
========= CUDA-MEMCHECK
OK
========= ERROR SUMMARY: 0 errors
$
If I omit -cudart shared on either of the above nvcc commands, then the compile will still proceed, but on execution I will witness the aforementioned seg fault. Tested with CUDA 7.5 on Fedora 20.
Regarding your CMake setup, it's necessary to link against the shared cudart, according to my testing. Therefore it's insufficient to add -cudart shared to the -c commands (which are compile commands. Sorry if I was unclear. My "compile" commands above are doing both compiling and linking, at each step.)
When linking with nvcc, the correct switch is -cudart shared. However, your make.sh indicates final link is being done by the host c++ compiler:
command nvcc "./testKernel.cu" -c -o "./testKernel.cu.o" -ccbin /usr/bin/cc -m64 -DtestKernelCall_EXPORTS -Xcompiler ,\"-fPIC\",\"-g\" -DNVCC -I/opt/cuda-7.0/include -I/opt/cuda-7.0/include
/usr/bin/c++ -fPIC -shared -Wl,-soname,libtestKernelCall.so -o libtestKernelCall.so ./testKernel.cu.o /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so
command nvcc "./useKernel.cu" -c -o "./useKernel.cu.o" -ccbin /usr/bin/cc -m64 -Xcompiler ,\"-g\" -DNVCC -I/opt/cuda-7.0/include -I/opt/cuda-7.0/include
/usr/bin/c++ ./useKernel.cu.o -o useKernel -rdynamic /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so libtestKernelCall.so /opt/cuda-7.0/lib64/libcudart_static.a -lpthread /usr/lib/x86_64-linux-gnu/librt.so /usr/lib/x86_64-linux-gnu/libdl.so -Wl,-rpath,"."
In that case, you don't want to link against:
/opt/cuda-7.0/lib64/libcudart_static.a
but instead against libcudart.so:
/opt/cuda-7.0/lib64/libcudart.so
If you were editing your make.sh directly, you would want to make that change in both of the /usr/bin/c++ command lines you have shown. For example, if I were to modify my compile sequence already presented to reflect your usage of the host c++ compiler to do the linking, it would look like this:
$ nvcc -c -Xcompiler -fPIC testKernel.cu
$ g++ -fPIC -shared -o test.so -L/usr/local/cuda/lib64 -lcudart testKernel.o
$ nvcc -c useKernel.cu
$ g++ -o test -L/usr/local/cuda/lib64 -lcudart test.so useKernel.o
$ cuda-memcheck ./test
========= CUDA-MEMCHECK
OK
========= ERROR SUMMARY: 0 errors
$
put set(CUDA_USE_STATIC_CUDA_RUNTIME OFF) before find_package(CUDA REQUIRED) will do the job equivalent to set(CUDA_LIBRARIES "${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcudart.so")
This is an extension to Robert Crovella's answer.
I use the following CMakeLists.txt and it works well.
cmake_minimum_required(VERSION 3.8)
project(cmake_and_cuda LANGUAGES CXX CUDA)
add_library(my_cu SHARED testKernel.cu testKernel.h)
target_link_libraries(my_cu PRIVATE cudart) #MUST!!
set(CMAKE_CUDA_FLAGS "-shared -cudart shared -Xcompiler -fPIC"
CACHE STRING "Use libcudart.dylib" FORCE)
set(CMAKE_MACOSX_RPATH FALSE)
add_executable(app useKernel.cu)
target_link_libraries(app PRIVATE cudart) #MUST!!
target_link_libraries(app PRIVATE my_cu)
I'm using CMake 3.10 and my OS is OS X EI Capitan 10.11.6.
For me, if I don't set CMAKE_MACOSX_RPATH to FALSE, I will get a Library not loaded error. Maybe it is not necessary for you.
Note that since CMake 3.8, the FindCUDA is superseded, so setting CUDA_USE_STATIC_CUDA_RUNTIME affects nothing.
You can check this post and this document for details.
In addition, this post provides a good example about how to deal with CUDA after CMake 3.8.

Can not compile simple mysql program

cblog.c:
#include "html.h"
#include "config.h"
#include <mysql/mysql.h>
//#include <my_global.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
conn = mysql_init(NULL);
// Connect to database
if (!msyql_real_connect(conn, server, username, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
// Query the DB
if (mysql_query(conn, "show tables")) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res = mysql_use_result(conn);
htmlf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(res)) != NULL)
htmlf("%s \n", row[0]);
mysql_free_result(res);
mysql_close(conn);
html("Hello World!");
return 0;
}
Makefile:
all:
# gcc -Wall cblog.c html.c -o cblog `mysql_config --cflags --libs`
# gcc -Wall cblog.c html.c -L/usr/lib -lmysqlclient -o cblog
gcc cblog.c html.c -Wall $(shell mysql_config --cflags) -o cblog $(shell mysql_config --libs)
test: all
./cblog
Output:
ttouch cblog$ make
gcc cblog.c html.c -g -Wall -I/usr/include/mysql -fPIC -pipe -fstack-protector --param=ssp-buffer-size=4 -fno-strict-aliasing -DBIG_JOINS=1 -fomit-frame-pointer -g -DNDEBUG -o cblog -L/usr/lib -lmysqlclient -lpthread -lz -lm -lssl -lcrypto -ldl
cblog.c: In function ‘main’:
cblog.c:16:2: warning: implicit declaration of function ‘msyql_real_connect’ [-Wimplicit-function-declaration]
if (!msyql_real_connect(conn, server, username, password, database, 0, NULL, 0)) {
^
/tmp/ccs1WQsi.o: In function `main':
/media/files/Lab/cblog/cblog.c:16: undefined reference to `msyql_real_connect'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
I know this question has been answered over a thousand times, I've searched all over the internet, I've tested putting mysql_config at the beginning or at the end. I know that it gives the right paths (checked)
ls /usr/lib/ | grep mysql:
libmysqlclient.a
libmysqlclient_r.a
libmysqlclient_r.so
libmysqlclient_r.so.18
libmysqlclient_r.so.18.0.0
libmysqlclient.so
libmysqlclient.so.18
libmysqlclient.so.18.0.0
libmysqld.a
libmysqld.so
libmysqld.so.18
libmysqlservices.a
mysql
tdbcmysql1.0.0
ls /usr/include/mysql | grep mysql:
mysql_com.h
mysqld_ername.h
mysqld_error.h
mysql_embed.h
mysql.h
mysql_time.h
mysql_version.h
Sorry for the noobish question, but I've been banging my head for about 4-5 hours
You have a typo in the function name, msyql_real_connect should be mysql_real_connect