I need to develop a program using MySQL C API. I will develop it on my CentOS virtual machine and run it on RedHat servers. I compiled a some kind of Hello World program and transferred it to the server. But I get an error about shared libraries.
$ ./test1
./test1: error while loading shared libraries: libssl.so.10: cannot open shared object file: No such file or directory
I see that this library exists but with a slightly different name:
$ ls -l /usr/lib/libssl*
-rw-r--r-- 1 root root 458752 Aug 13 17:27 /usr/lib/libssl.a
lrwxrwxrwx 1 root root 26 Sep 14 01:26 /usr/lib/libssl.so -> ../../lib/libssl.so.0.9.8er
-rwxr-xr-x 1 root root 217560 Nov 9 12:22 /usr/lib/libssl3.so
Since I am not root on the server, I can't simply make a symbolic link. I will distribute my program to many people without root privilege and system administration skills. Is there a safe way of compiling my program to avoid such errors?
here is my simple program:
#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv)
{
printf("MySQL client version: %s\n", mysql_get_client_info());
}
and, this is how I compiled it:
gcc version.c -o version `mysql_config --cflags --libs`
output of ldd ./test1:
linux-gate.so.1 => (0x00685000)
libmysqlclient.so.16 => /usr/lib/mysql/libmysqlclient.so.16 (0x00a8c000)
libz.so.1 => /lib/libz.so.1 (0x00110000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x00240000)
libnsl.so.1 => /lib/libnsl.so.1 (0x002b7000)
libm.so.6 => /lib/libm.so.6 (0x00f5a000)
libssl.so.10 => /usr/lib/libssl.so.10 (0x00e0c000)
libcrypto.so.10 => /usr/lib/libcrypto.so.10 (0x002d1000)
libc.so.6 => /lib/libc.so.6 (0x004d3000)
libfreebl3.so => /lib/libfreebl3.so (0x00686000)
/lib/ld-linux.so.2 (0x00977000)
libgssapi_krb5.so.2 => /lib/libgssapi_krb5.so.2 (0x006ea000)
libkrb5.so.3 => /lib/libkrb5.so.3 (0x00123000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x00804000)
libk5crypto.so.3 => /lib/libk5crypto.so.3 (0x001f4000)
libresolv.so.2 => /lib/libresolv.so.2 (0x0021b000)
libdl.so.2 => /lib/libdl.so.2 (0x00dbf000)
libkrb5support.so.0 => /lib/libkrb5support.so.0 (0x00234000)
libkeyutils.so.1 => /lib/libkeyutils.so.1 (0x00f0b000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00e72000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00862000)
output of mysql_config --cflags --libs:
-I/usr/include/mysql -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -fasynchronous-unwind-tables -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fno-strict-aliasing -fwrapv -fPIC -DUNIV_LINUX
-rdynamic -L/usr/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -lssl -lcrypto
Your binary is compiled against openssl version 1.0.x and therefore requires openssl major version 1. The target machine has version 0.9.8, which is major version 0. Different major versions are considered incompatible, hence the error.
Read up on ld.so and its variables such as LD_LIBRARY_PATH and LD_PRELOAD-- you can install, say libssl.so in your own ~/lib/ and have the dynamic linker find that.
Needless to say, you are much better off doing this via the package management system.
Related
I am using this workflow: cmake_build.yaml
Here is my toplevel CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
project(
container
VERSION 0.1.0
DESCRIPTION "An extension to the standard container library in c++"
HOMEPAGE_URL ""
LANGUAGES CXX
)
add_executable(${PROJECT_NAME} src/main.cpp)
set_target_properties(
${PROJECT_NAME}
PROPERTIES
LINKER_LANGUAGE CXX
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}"
)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
target_include_directories(
${PROJECT_NAME}
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
install(
DIRECTORY
include/${PROJECT_NAME_LOWERCASE}
DESTINATION
include
)
enable_testing()
add_subdirectory(test)
and test/CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(my_project)
# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 17)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
add_executable(
hello_test
hello_test.cc
)
target_link_libraries(
hello_test
GTest::gtest_main
)
include(GoogleTest)
gtest_discover_tests(hello_test)
I am using the example from gtest docs:
test/hello_test.cc:
#include <gtest/gtest.h>
TEST(HelloTest, BasicAssertions) {
// Expect two strings not to be equal.
EXPECT_STRNE("hello", "world");
// Expect equality.
EXPECT_EQ(7 * 6, 42);
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
It builds fine on Windows MSVC, Macos Clang, Linux GCC, but fails using Mingw GCC, here is error shown:
FAILED: test/hello_test.exe test/hello_test[1]_tests.cmake D:/a/tsst/tsst/build/test/hello_test[1]_tests.cmake
cmd.exe /C "cd . && C:\ProgramData\chocolatey\bin\g++.exe -O3 -DNDEBUG test/CMakeFiles/hello_test.dir/hello_test.cc.obj -o test\hello_test.exe -Wl,--out-implib,test\libhello_test.dll.a -Wl,--major-image-version,0,--minor-image-version,0 lib/libgtest_main.a lib/libgtest.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cmd.exe /C "cd /D D:\a\tsst\tsst\build\test && D:\a\tsst\tsst\cmake-3.24.3-windows-x86_64\bin\cmake.exe -D TEST_TARGET=hello_test -D TEST_EXECUTABLE=D:/a/tsst/tsst/build/test/hello_test.exe -D TEST_EXECUTOR= -D TEST_WORKING_DIR=D:/a/tsst/tsst/build/test -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=hello_test_TESTS -D CTEST_FILE=D:/a/tsst/tsst/build/test/hello_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_XML_OUTPUT_DIR= -P D:/a/tsst/tsst/cmake-3.24.3-windows-x86_64/share/cmake-3.24/Modules/GoogleTestAddTests.cmake""
CMake Error at D:/a/tsst/tsst/cmake-3.24.3-windows-x86_64/share/cmake-3.24/Modules/GoogleTestAddTests.cmake:112 (message):
Error running test executable.
Path: 'D:/a/tsst/tsst/build/test/hello_test.exe'
Result: Exit code 0xc0000139
Output:
Call Stack (most recent call first):
D:/a/tsst/tsst/cmake-3.24.3-windows-x86_64/share/cmake-3.24/Modules/GoogleTestAddTests.cmake:225 (gtest_discover_tests_impl)
ninja: build stopped: subcommand failed.
Build works fine without building gtest, and it fails when building test executable with gtest
Getting below error while compiling Valgrind for Cavium MIPS
/opt/cavium-64bit/tools-3535/bin/mips64-octeon-linux-gnu-gcc -std=c99
-msoft-float -Wall -mabi=64 -G 0 -fPIC -mips64r2 -mplt -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I../include -I../VEX/pub -I../VEX/pub -DVGA_mips64=1 -DVGO_linux=1 -DVGP_mips64_linux=1 -DVGPV_mips64_linux_vanilla=1 -DVGABI_64 -I../coregrind -DVG_LIBDIR="\"/usr/local/lib/valgrind"\" -DVG_PLATFORM="\"mips64-linux\"" -O2 -g -Wall -Wmissing-prototypes -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations -Wcast-align -Wcast-qual -Wwrite-strings -Wempty-body -Wformat -Wformat-security -Wignored-qualifiers -Wmissing-parameter-type -Wlogical-op -Wold-style-declaration -finline-functions -fno-stack-protector -fno-strict-aliasing -fno-builtin -march=octeon2 -mabi=64 -MT libnolto_coregrind_mips64_linux_a-m_main.o -MD -MP -MF .deps/libnolto_coregrind_mips64_linux_a-m_main.Tpo -c -o
libnolto_coregrind_mips64_linux_a-m_main.o test -f 'm_main.c' || echo
'./'m_main.c m_main.c:2885:1: error: expected declaration specifiers
or ‘...’ before string constant Makefile:8044: recipe for target
'libnolto_coregrind_mips64_linux_a-m_main.o' failed make[3]: *
[libnolto_coregrind_mips64_linux_a-m_main.o] Error 1 make[3]: Leaving
directory '/home/ankit/Desktop/valgrind/valgrind-3.15.0/coregrind'
Makefile:1914: recipe for target 'all' failed make[2]: [all] Error
2 make[2]: Leaving directory
'/home/ankit/Desktop/valgrind/valgrind-3.15.0/coregrind' Makefile:841:
recipe for target 'all-recursive' failed make[1]: [all-recursive]
Error 1 make[1]: Leaving directory
'/home/ankit/Desktop/valgrind/valgrind-3.15.0' Makefile:710: recipe
for target 'all' failed make: * [all] Error 2
Procedure to build Valgrind binary for MIPS Architecture
Get latest Valgrind source code from (https://valgrind.org/downloads/)
wget
https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2
Extract the tarball
tar -xvf valgrind-3.15.0.tar.bz2
On Bash prompt export below makefile defines
CC=/opt/CAVIUMsdk312/OCTEON-SDK/tools/bin/mips64-octeon-linux-gnu-gcc
CXX=/opt/CAVIUMsdk312/OCTEON-SDK/tools/bin/mips64-octeon-linux-gnu-g++
./configure --host=mips64-octeon-linux --target=mips64-octeon-linux
CFLAGS=" -march=octeon2 -mabi=64"
After configure is successfully executed do make in the directory
make
To run Valgrind on target follow the below procedure
Copy the valgrind folder to target machine, Ex: /etc/user/
cd /etc/user/valgrind-3.15.0
touch /etc/user/valgrind-3.15.0/memcheck/default.supp
export VALGRIND_LIB=$PWD/memcheck/
export LD_LIBRARY_PATH=/usr/sbin/user/sharedobj/
./coregrind/valgrind --tool=memcheck --gen-suppressions=yes --leak-check=full -v
--track-origins=yes <Daemon>
Can't install DBD::mysql under macOS Catalina 10.15.1. Mysql 8.0.18 and openssl 1.0.2t are installed through brew.
Here is the module installation log:
cpan[1]> install DBD::mysql
..........
I will use the following settings for compiling and testing:
cflags (mysql_config) = -I/usr/local/Cellar/mysql/8.0.18_1/include/mysql
embedded (guessed ) =
ldflags (guessed ) =
libs (mysql_config) = -L/usr/local/Cellar/mysql/8.0.18_1/lib -L/usr/local/opt/openssl/lib -lmysqlclient -lssl -lcrypto
mysql_config (guessed ) = mysql_config
nocatchstderr (default ) = 0
nofoundrows (default ) = 0
nossl (default ) = 0
testdb (default ) = test
testhost (default ) =
testpassword (default ) =
testport (default ) =
testsocket (default ) =
testuser (guessed ) = dmitry
To change these settings, see 'perl Makefile.PL --help' and
'perldoc DBD::mysql::INSTALL'.
Checking if libs are available for compiling...
Looks good.
Checking if your kit is complete...
Looks good
Using DBI 1.631 (for perl 5.018004 on darwin-thread-multi-2level) installed in /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI/
Writing Makefile for DBD::mysql
Wide character in print at /System/Library/Perl/5.18/ExtUtils/MakeMaker.pm line 1034.
Wide character in print at /System/Library/Perl/5.18/ExtUtils/MakeMaker.pm line 1034.
Writing MYMETA.yml and MYMETA.json
cp lib/DBD/mysql/GetInfo.pm blib/lib/DBD/mysql/GetInfo.pm
cp lib/Bundle/DBD/mysql.pm blib/lib/Bundle/DBD/mysql.pm
cp lib/DBD/mysql/INSTALL.pod blib/lib/DBD/mysql/INSTALL.pod
cp lib/DBD/mysql.pm blib/lib/DBD/mysql.pm
cc -c -I/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI -I/usr/local/Cellar/mysql/8.0.18_1/include/mysql -DDBD_MYSQL_WITH_SSL -g -g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -fstack-protector -Os -DVERSION=\"4.050\" -DXS_VERSION=\"4.050\" -iwithsysroot "/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE" dbdimp.c
In file included from dbdimp.c:15:
./dbdimp.h:20:10: fatal error: 'DBIXS.h' file not found
#include <DBIXS.h> /* installed by the DBI module */
^~~~~~~~~
1 error generated.
make: *** [dbdimp.o] Error 1
DVEEDEN/DBD-mysql-4.050.tar.gz
/usr/bin/make -- NOT OK
Running make test
Can't test without successful make
Running make install
Make had returned bad status, install seems impossible
Failed during this command:
DVEEDEN/DBD-mysql-4.050.tar.gz : make NO
cpan[2]>
It seems the compiler could not find the DBIXS.h file. find found this file in the system:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI/DBIXS.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI/DBIXS.h
/System/Volumes/Data/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI/DBIXS.h
/System/Volumes/Data/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI/DBIXS.h
/System/Volumes/Data/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI/DBIXS.h
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/auto/DBI/DBIXS.h
How to include this header file during compilation?
UPDATE
My searches led me to build the package using the standard path where there are no header files
/System/Library/Perl/5.18/darwin-thread-multi-2level
And you must use the path
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Perl/5.18/darwin-thread-multi-2level
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Perl/5.18/darwin-thread-multi-2level
But here's how to specify it? I encountered the same problem when installing Mac::SystemDirectory
/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE/EXTERN.h -
file not found
Perl information:
perl -V
Summary of my perl5 (revision 5 version 18 subversion 4) configuration:
Platform:
osname=darwin, osvers=19.0, archname=darwin-thread-multi-2level
uname='darwin osx391.sd.apple.com 19.0 darwin kernel version 18.0.0: tue jul 9 11:12:08 pdt 2019; root:xnu-4903.201.2.100.7~1release_x86_64 x86_64 '
config_args='-ds -e -Dprefix=/usr -Dccflags=-g -pipe -Dldflags= -Dman3ext=3pm -Duseithreads -Duseshrplib -Dinc_version_list=none -Dcc=cc'
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags =' -g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -fstack-protector',
optimize='-Os',
cppflags='-g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing -fstack-protector'
ccversion='', gccversion='4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.32.4) (-macos10.15-objc-selector-opts)', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -fstack-protector'
libpth=/usr/lib /usr/local/lib
libs=
perllibs=
libc=, so=dylib, useshrplib=true, libperl=libperl.dylib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -fstack-protector'
Characteristics of this binary (from libperl):
Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS
PERL_DONT_CREATE_GVSV
PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
PERL_PRESERVE_IVUV PERL_SAWAMPERSAND USE_64_BIT_ALL
USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE
USE_LOCALE_NUMERIC USE_PERLIO USE_PERL_ATOF
USE_REENTRANT_API
Locally applied patches:
/Library/Perl/Updates/<version> comes before system perl directories
installprivlib and installarchlib points to the Updates directory
Built under darwin
Compiled at Aug 23 2019 16:44:31
#INC:
/Library/Perl/5.18/darwin-thread-multi-2level
/Library/Perl/5.18
/Network/Library/Perl/5.18/darwin-thread-multi-2level
/Network/Library/Perl/5.18
/Library/Perl/Updates/5.18.4/darwin-thread-multi-2level
/Library/Perl/Updates/5.18.4
/System/Library/Perl/5.18/darwin-thread-multi-2level
/System/Library/Perl/5.18
/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.18
.
The missing EXTERN.h file you find here:
$ find /Library/Developer/CommandLineTools -name EXTERN.h
A detailed instructions you find here:
DBD::mysql installation on Catalina/Big Sur fail with 'EXTERN.h' file not found?
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
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.