How correctly to link program against library - shared-libraries

I run ./myprogram and it gives me a warning:
Warning: Your program was compiled with SimGrid version 3.13.90, and then linked against SimGrid 3.13.0. Proceeding anyway.
Tryldd myprogram and it gives following:
libsimgrid.so.3.13.90 => /usr/lib/libsimgrid.so.3.13.90 (0x00007f338ef47000)
Then I go to usr/lib and type ll *sim* in terminal:
lrwxrwxrwx 1 ken ken 21 июл 28 19:29 libsimgrid.so -> libsimgrid.so.3.13.90*
-rwxrwxr-x 1 ken ken 12307480 июл 28 19:29 libsimgrid.so.3.13.90*
In CMakeLists.txt I link library simgrid in such way:
target_link_libraries(CSim2Sim simgrid)
Why myprogram still links against SimGrid 3.13.0 (it doesn't exist in /usr/lib while SimGrid 3.13.90 does)?
UPDATE:
Command locate libsimgrid.so in ternimal gives:
/home/ken/Downloads/simgrid-master/lib/libsimgrid.so
/home/ken/Downloads/simgrid-master/lib/libsimgrid.so.3.13.90
/home/ken/SimGrid/lib/libsimgrid.so
/home/ken/SimGrid/lib/libsimgrid.so.3.13.90
/usr/lib/libsimgrid.so
/usr/lib/libsimgrid.so.3.13.90

The message seems buggy, it looks like your application was actually compiled with 3.13.0, and linked to libsimgrid 3.13.90. The order was inverted in the message, I will fix that.
It could be a problem with your includes when you compile your code, I think. Please check that you don't use old versions of msg.h/simgrid_config.h files when you compile your app (maybe there are still one in /usr/include ?).
To check, you can look for SIMGRID_VERSION_PATCH in simgrid_config.h. it should be 90 in a recent one, not 0.

Related

Why would a cross-compiled DLL export symbols already defined in MSVCRT?

I'm using MXE to build my own cross-compiler toolchain (this specific version). Only I don't use the default gcc 5.5 but gcc 6.3.0 instead.
I'm not specifically tied to that version - I just picked it because it was also used to generate the latest portaudio binaries
It appears that for some reason, some MSVCRT symbols have been included in and are exported by the portaudio DLL:
dumpbin /exports libportaudio64bit.dll
992 3DF 00032F30 mbrlen
993 3E0 00032D90 mbrtowc
994 3E1 00032E00 mbsrtowcs
1112 457 00033180 wcrtomb
1113 458 000331C0 wcsrtombs
I only found out because I was trying to cross-compile and build bzip2 1.0.8
This is pretty old and it doesn't have all the infrastructure in place to support cross-compiling. However it can be done by hand in a couple of very simple steps:
make CC=x86_64-w64-mingw32.shared-gcc AR=x86_64-w64-mingw32.shared-ar RANLIB=x86_64-w64-mingw32.shared-ranlib libbz2.a
x86_64-w64-mingw32.shared-gcc *.o -s -shared -o libbz2-1.dll
Alike the portaudio DLLs, the above exports the same symbols:
dumpbin /exports libbz2-1.dll
36 23 00012B60 mbrlen
37 24 000129F0 mbrtowc
38 25 00012A60 mbsrtowcs
39 26 00012DC0 wcrtomb
40 27 00012E00 wcsrtombs
Needless to say, this is causing issues at link time, due to multiple definitions of the same symbol (mingw-w64-v8.0.0/mingw-w64-crt/misc/mbrtowc.c:98: multiple definition of 'mbrtowc' - x86_64-w64-mingw32.shared/lib/../lib/libmsvcrt.a(lib64_libmsvcrt_os_a-mbrtowc.o): first defined here)
My question is not how to avoid this issue. That can be done by using a DEF file when building the DLLs, to control the exact list of exported functions.
My question is more fundamental: why would these symbols be exported in the first place ? Is this a bug somewhere ?

Guile foreign-library-function fails

In running an example from the guile handbook I stumbled upon an error while running foreign-library-function. It fails and prints a backtrace stating dlopen failed, because of an invalid elf format of the library. But the library is both present and working in other contexts.
The details to reproduce the issue:
test.scm (taken straight from the manual at https://www.gnu.org/software/guile/manual/guile.html#Foreign-Functions)
(define-module (math bessel)
#:use-module (system foreign)
#:use-module (system foreign-library)
#:export (j0))
(define j0)
(foreign-library-function "libm" "j0"
#:return-type double
#:arg-types (list double))
If I execute guile -s test.scm I get the following output:
;;; note: source file /home/max/projects/guile-tests/test.scm
;;; newer than compiled /home/max/.cache/guile/ccache/3.0-LE-8-4.5/home/max/projects/guile-tests/test.scm.go
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;; or pass the --no-auto-compile argument to disable.
;;; compiling /home/max/projects/guile-tests/test.scm
;;; compiled /home/max/.cache/guile/ccache/3.0-LE-8-4.5/home/max/projects/guile-tests/test.scm.go
Backtrace:
In ice-9/boot-9.scm:
1752:10 8 (with-exception-handler _ _ #:unwind? _ # _)
In unknown file:
7 (apply-smob/0 #<thunk 7f57b930ef60>)
In ice-9/boot-9.scm:
724:2 6 (call-with-prompt _ _ #<procedure default-prompt-handle…>)
In ice-9/eval.scm:
619:8 5 (_ #(#(#<directory (guile-user) 7f57b9307c80>)))
In ice-9/boot-9.scm:
2835:4 4 (save-module-excursion _)
4380:12 3 (_)
In system/foreign-library.scm:
240:6 2 (foreign-library-function "libm" "j0" #:return-type _ # …)
190:25 1 (load-foreign-library _ #:extensions _ # _ #:search-path …)
In unknown file:
0 (dlopen "/usr/lib64/libm.so" 1)
ERROR: In procedure dlopen:
In procedure dlopen: file "/usr/lib64/libm.so", message "/usr/lib64/libm.so: Ungültiger ELF-Header"
To ensure the file in question is actually there here's the output of ls -la /usr/lib64/libm.so:
-rw-r--r-- 1 root root 110 20. Jun 19:52 /usr/lib64/libm.so
The problem also occured for all other libraries I tried to adapt the snippet to.
My current system is running on
openSUSE Tumbleweed 20210723
with Linux kernel 5.22.3
I installed the guile-package using zypper in guile from the official repositories. (currently version 3.0.7)
I heavily suspect that openSUSEs compilation/linking settings could be at fault here, but can neither confirm nor invalidate that theory. - It would be ideal to both know why the issue occurs as well as knowing a workaround.
dlopen: file "/usr/lib64/libm.so"
I don't know anything about Guile, but the problem appears to be that it is trying to dlopen libm.so.
On Linux with GLIBC, libm.so is a linker script, not an ELF file. The real ELF library (and the library guile should be dlopening) is libm.so.6.
You can see that your libm.so (at 110 bytes) is way too small to be an ELF file. If you run file -L /usr/lib64/libm.so*, you should see something like this:
/usr/lib64/libm.so: ASCII text
/usr/lib64/libm.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=07ae52cfc7f4eda1d13383c04564e3236e059993, for GNU/Linux 3.2.0, stripped
Possibly you need to fix system/foreign-library.scm so it dlopens correct library.
The solution to the problem was that libm.so is a linker script, just like the other answer says.
The problem is resolved, if instead of "libm" one passes "libm.so.6" to the function.
The following is the corrected, working snippet.
(define-module (math bessel)
#:use-module (system foreign)
#:use-module (system foreign-library)
#:export (j0))
(define j0)
(foreign-library-function "libm.so.6" "j0"
#:return-type double
#:arg-types (list double))

CDLL can not find find shared object

I have shared object file libalgo.so in /usr/lib. ls -al /usr/lib gives
-rwxr-xr-x 1 root root 14264 Jul 6 06:57 libalgo.so
-rwxr-xr-x 1 root root 403496 Oct 8 12:07 libnlopt.so.0
I have to import this shared library in python
from ctypes import *
try:
lib = '/usr/lib/libalgo.so'
algo_lib = CDLL(lib)
print('algo_lib loaded')
except Exception as e:
print(e)
when running this code I get an error message saying could not read the shared object. No such file...
I have also added /usr/lib in LD_LIBRARY_PATH. This error only occurs in remote in which I am sshing into not in my local machine.
TL;DR The libalgo.so was compiled for arm.
We are developing for an arm system on x86 machines. One of the deb packages ended up with wrong shared object. Also error message given by python were misleading at best . instead of showing something like invalid object file , the message led me to believe that python could not find the file. I am not sure why such error message was given and any more information on this will be appreciated.

Writing `configure` file for an r package

I am writing an r package which provides a wrapper around the libSBML C library.
I am using the rcppgsl package as a reference, which looks for the location of header files and the library files for GNU Scientific Library GSL and uses that information to write the configure script and Makevars and Makevars.in. I am not building for Windows currently. On my machine (macOS), libsbml (SBML C library) is installed in usual locations, i.e.
header files are at - /usr/local/include/sbml
and library files at - /usr/local/lib. Indeed, if in my package Makevars file I use the following, I can build my package.
CXX=clang++
PKG_CPPFLAGS= -I/usr/local/include
PKG_LIBS= $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) /usr/local/lib/libsbml-static.a
However, I want to learn how to use the configure script to find the library and use that information to build the package. The relevant portion of configure.ac from rcppgsl is
## Check for non-standard programs: gsl-config(1)
AC_PATH_PROG([GSL_CONFIG], [gsl-config])
## If gsl-config was found, let's use it
if test "${GSL_CONFIG}" != ""; then
# Use gsl-config for header and linker arguments
GSL_CFLAGS=`${GSL_CONFIG} --cflags`
GSL_LIBS=`${GSL_CONFIG} --libs`
else
AC_MSG_ERROR([gsl-config not found, is GSL installed?])
fi
I replaced GSL_CONFIG with LIB_SBML at relevant places, i.e., the entire configure.ac file I am using is pasted below (at the end).
However, I don't see configure, Makevars and Makevars.in being generated (which I see in rcppgsl). Any help here would be highly appreciated!
For the sake of completion, the output of
ls -l | grep sbml (in usr/local/include) is
drwxrwxr-x 58 root admin 1856 Aug 1 2016 sbml
and ls -l | grep sbml (in usr/local/lib) is
-rw-r--r-- 1 root wheel 7970584 Aug 2 2016 libsbml-static.a
-rwxr-xr-x 1 arcadmin staff 10453624 Nov 25 2014 libsbml.5.11.0.dylib
-rwxr-xr-x 1 root wheel 3813572 Aug 2 2016 libsbml.5.13.0.dylib
lrwxr-xr-x 1 root wheel 20 Aug 1 2016 libsbml.5.dylib -> libsbml.5.13.0.dylib
-rw-r--r-- 1 root wheel 13907656 Feb 26 2015 libsbml.a
lrwxr-xr-x 1 arcadmin staff 15 Mar 27 2015 libsbml.dylib -> libsbml.5.dylib
-rwxr-xr-x 1 root wheel 828 Feb 26 2015 libsbml.la
-rwxrwxr-x 1 root admin 13362732 Nov 25 2014 libsbmlj.jnilib
My configure.ac file --
## Process this file with autoconf to produce a configure script.
##
## Configure.ac for RcppSBML
##
## Copyright (C) 2010 Romain Francois and Dirk Eddelbuettel
## Copyright (C) 2014 - 2015 Dirk Eddelbuettel
##
## Licensed under GNU GPL 2 or later
# The version set here will propagate to other files from here
AC_INIT([Rcppsbml], 0.1.0)
# Checks for common programs using default macros
AC_PROG_CC
## Use gsl-config to find arguments for compiler and linker flags
##
## Check for non-standard programs: gsl-config(1)
AC_PATH_PROG([LIB_SBML], [libsbml])
## If gsl-config was found, let's use it
if test "${LIB_SBML}" != ""; then
# Use gsl-config for header and linker arguments
SBML_CFLAGS=`${LIB_SBML} --cflags`
SBML_LIBS=`${LIB_SBML} --libs`
else
AC_MSG_ERROR([libsbml not found, is SBML installed?])
fi
# Now substitute these variables in src/Makevars.in to create src/Makevars
AC_SUBST(LIB_SBML)
AC_SUBST(LIB_SBML)
AC_OUTPUT(src/Makevars)
Here a minimal setup:
Remove src/Makevars and create src/Makevars.in with content
PKG_CPPFLAGS= #SBML_INCLUDE#
PKG_LIBS= $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) #SBML_LIBS#
I am not setting CXX since you cannot change that in src/Makevars, c.f. Package build ignores Makevars flags.
Create a minimal configure.ac file:
AC_INIT([Rcppsbml], 0.1.0)
AC_LANG(C++)
AC_REQUIRE_CPP
AC_PROG_CXX
# default values
AC_SUBST([SMBL_INCLUDE], "-I/usr/local/include")
AC_SUBST([SMBL_LIBS], "/usr/local/lib/libsbml-static.a")
# allow for override
AC_ARG_WITH([smbl],
AC_HELP_STRING([--with-smbl=PREFIX],
[path to where smbl is installed]),
[
SMBL_INCLUDE="-I${with_smbl}/include"
SMBL_LIBS="${with_smbl}/lib/libsbml-static.a"
],
[])
# create and report output
AC_CONFIG_FILES([src/Makevars])
AC_OUTPUT
echo
echo "Final src/Makevars"
cat src/Makevars
Call autoconf to create a configure file from your configure.ac template. You might want to check the script with ./configure and ./configure --with-smbl=/some/path.
Call
R CMD build ...
R CMD check [--install-args=--configure-args=--with-smbl=/some/path] ...
R CMD INSTALL [--configure-args=--with-smbl=/some/path]...
to build, check and install the package.
Possible extensions:
Allow for switching between static and dynamic linking.
Check that SMBL can be found in a usable state at the specified location.
I see three issues here:
The generation of configure from configure.ac is not automatic. You have to call autoconf.
Similarly, Makevars.in is not generated by the system. You have to provide it as template from which Makevars is generated by configure.
The GSL ships with gsl-config, other libraries make use of the general pkg-config. If your library does not support this, you can use the more traditional way to use default locations or those provided with --with-... arguments. For example in RcppArrayFire I use:
AC_SUBST([AF_INCLUDE], "")
AC_SUBST([AF_LIBS], "-laf")
AS_IF([test -e "${with_arrayfire}"],
[
AF_INCLUDE="-I${with_arrayfire}/include ${AF_INCLUDE}"
AF_LIBS="-L${with_arrayfire}/lib ${AF_LIBS} -Wl,-rpath,${with_arrayfire}/lib"
])
If a directory is supplied as --with-arrayfire=/relevant/path, then appropriate sub directories are searched for headers and dynamic libraries.

Errors after Theano upgrade from 0.7 to bleeding edge

I installed and used Theano 0.7 and everything was working perfectly. But now for the purpose of my future works, I need the bleeding edge version, and the installation went fine.
But when I run this little test (found into the Theano documentation), it generates many errors (see here for the full list).
We can observe that the GPU is detected and used, but cuDNN is not found anymore:
Using gpu device 0: GeForce GT 650M (CNMeM is enabled with initial size: 65.0% of memory, CuDNN not available)
And then I have an import error, I think it is also about cuDNN:
ImportError: ('The following error happened while compiling the node', <theano.sandbox.cuda.DnnVersion object at 0x114d32710>(), '\n', 'dlopen(/Users/FiReTiTi/.theano/compiledir_Darwin-13.4.0-x86_64-i386-64bit-i386-2.7.11-64/tmpwmA_hw/265abc51f7c376c224983485238ff1a5.so, 2): Library not loaded: #rpath/libcudnn.4.dylib\n Referenced from: /Users/FiReTiTi/.theano/compiledir_Darwin-13.4.0-x86_64-i386-64bit-i386-2.7.11-64/tmpwmA_hw/265abc51f7c376c224983485238ff1a5.so\n Reason: image not found', '[<theano.sandbox.cuda.DnnVersion object at 0x114d32710>()]')
I've checked and cudnn.h is still in /Developer/NVIDIA/CUDA-7.5/include/, in /Developer/NVIDIA/CUDA-7.5/lib/ we still find libcudnn.dylib which is a symbolic link to libcudnn.4.dylib, and everything in /usr/local/cuda points to /Developer/NVIDIA/CUDA-7.5/
Any idea?
[EDIT] In my .profile we find:
export DYLD_LIBRARY_PATH=/Developer/NVIDIA/CUDA-7.5/lib:$DYLD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH
In /usr/local/cuda/lib there is a symbolic link to the cudnn library that is actually in /Developer/NVIDIA/CUDA-7.5/lib.
Here is the result from the command tool -L libcudnn.4.dylib:
libcudnn.4.dylib:
#rpath/libcudnn.4.dylib (compatibility version 0.0.0, current version 4.0.7)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.14.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
And here is the link between: /usr/local/cuda/lib/libcudnn.dylib -> /Developer/NVIDIA/CUDA-7.5/lib/libcudnn.dylib, and in /Developer/NVIDIA/CUDA-7.5/lib I have libcudnn.dylib -> libcudnn.4.dylib
[EDIT 2]
$ echo $DYLD_LIBRARY_PATH
/usr/local/xuggler/lib:/usr/local/cuda/lib:/Applications/IMOD/lib:
$ echo $LD_LIBRARY_PATH
/usr/local/cuda/lib:
[EDIT 3] Here is the last error displayed. At least one part, because this error appears at each epoch.
With ls -la /usr/local/cuda/lib:
lrwxr-xr-x 1 root wheel 45B 22 fév 11:42 libcudnn.dylib -> /Developer/NVIDIA/CUDA-7.5/lib/libcudnn.dylib
lrwxr-xr-x 1 root wheel 48B 26 fév 01:01 libcudnn_static.a -> /Developer/NVIDIA/CUDA-7.5/lib/libcudnn_static.a
This looks like a bug in Theano. It probably would work if they added ["-Wl,-rpath,%s" % l for l in c_lib_dirs()] to the compile args. You should report that upstream here.
It might work as a workaround if you add the path of libcudnn.4.dylib to your LD_LIBRARY_PATH (or maybe DYLD_LIBRARY_PATH) environment variable, because that is where #rpath will also look at, so that the path #rpath/libcudnn.4.dylib can be resolved.

Resources