Calling Pardiso 6 in Python - python

I'm trying to use Pardiso 6 sparse solver library in Python. The problem is that I can't seem to load the Pardiso shared object (SO). Here's the error that I get when calling
import ctypes
pardiso = ctypes.CDLL(pardiso_so_address)
Traceback (most recent call last):
File "test.py", line 27, in <module>
pardiso = ctypes.CDLL(lib720)
File "/home/amin/anaconda3/envs/idp/lib/python3.7/ctypes/__init__.py", line 364, in __init__
self._handle = _dlopen(self._name, mode)
OSError: ./libpardiso600-GNU720-X86-64.so: undefined symbol: sgetrf_
I'd really appreciate it if someone could shed some light on this.
PS. I already contacted Pardiso developers and they told me that I need to link against optimized BLAS, but I already have MKL installed via conda.
Update 1: I installed mkl via conda, but it didn't help. Strangely, I added import scipy to the header and the error went away. The same thing happens if I add import mkl. So, for some reason, unless scipy or mkl are manually imported, the .so doesn't know that a lapack installation exists. Anyway, now another error is thrown, which I think might be related the libgfortran library. Here's the error
Traceback (most recent call last):
File "test.py", line 34, in <module>
pardiso = ctypes.CDLL(lib720)
File "/home/amin/anaconda3/envs/test/lib/python3.7/ctypes/__init__.py", line 364, in __init__
self._handle = _dlopen(self._name, mode)
OSError: ./libpardiso600-GNU720-X86-64.so: undefined symbol: _gfortran_st_close
I double-checked to see if libgfortran is installed, and indeed it is:
(test) PyPardisoProject$ ldconfig -p | grep libgfortran
libgfortran.so.5 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgfortran.so.5
libgfortran.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgfortran.so.4
I think something similar might be at play, i.e. the library is there but it needs to be triggered (similar to what import scipy seems to have done for liblapack, but I have no idea how I can trigger it.
Note: I found an example in C on Pardiso website and tested the .so file against it via
$ gcc pardiso_sym.c -o pardiso_sym -L . -lpardiso600-GNU720-X86-64 -llapack -fopenmp -lgfortran
$ OMP_NUM_THREADS=1 ./pardiso_sym
and it worked with no problem (with the existing libraries on my machine). So, the .so works, it's just that I don't know how to inform it of its dependencies in Python.
Update 2: Here's the output of ldd pardiso_sym:
Scripts$ ldd pardiso_sym
linux-vdso.so.1 (0x00007ffe7e982000)
libpardiso600-GNU720-X86-64.so (0x00007f326802d000)
liblapack.so.3 => /lib/x86_64-linux-gnu/liblapack.so.3 (0x00007f3267976000)
libgfortran.so.4 => /lib/x86_64-linux-gnu/libgfortran.so.4 (0x00007f3267795000)
libgomp.so.1 => /lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f326775b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3267568000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3267545000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f32673f6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f32685df000)
libblas.so.3 => /lib/x86_64-linux-gnu/libblas.so.3 (0x00007f3267389000)
libgfortran.so.5 => /lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007f32670e9000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f32670cf000)
libquadmath.so.0 => /lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f3267083000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f326707d000)
So, I added the common path, i.e. /lib/x86_64-linux-gnu and /lib64 to PATH and ran the Python script again via:
PATH=$PATH:/lib/x86_64-linux-gnu:/lib64 python padiso_script.py
but the same error is thrown. I also tried adding to LD_LIBRARY_PATH as well, but didn't work either.

Pardiso 6 sparse solver depends on Lapack functions at least sgetrf, that computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges.
From what we read, libpardiso600-GNU720-X86-64.so is linked dynamically against a shared Lapack library. You need to provide a PATH containing one implementation.
Before launching Python, I would recommend you to play with the LD_LIBRARY_PATH and include the path to the BLAS/Lapack library you are using. It can be the netlib implementation, the ATLAS implementation or the MKL implementation.
LD_LIRARY_PATH=$LD_LIRARY_PATH:/my_path_to_lapack \
python -c"import ctypes; pardiso = ctypes.CDLL(pardiso_so_address)"
If you use conda, you can install with the command
conda install -c anaconda mkl
In this case, the installation may directly solves the problem.

The trick is, rather than adding the location of dependencies to system PATHs, you need to explicitly load the dependencies, i.e. lapack, blas, and gfortran in the Python script prior to loading the Pardiso library. Also, it's essential that you explicitly pass the optional mode=ctypes.RLTD_GLOBAL argument to ctypes.CDLL method in order to make the dependencies globally accessible and hence, Pardiso can access them.
import ctypes
import ctypes.util
shared_libs = ["lapack", "blas", "omp", "gfortran"]
for lib in shared_libs:
# Fetch the proper name of the dependency
libname = ctypes.util.find_library(lib)
# Load the dependency and make it globally accessible
ctypes.CDLL(libname, mode=ctypes.RTLD_GLOBAL)
# Finally, load the Pardiso library
pardiso = ctypes.CDLL(pardiso_so_address)
In my experience, if you are inside a conda environment with mkl installed, you only need to list gfortran as dependency and the rest are automatically loaded and accessible, in which case set shared_libs = ["gfortran"].

Pardiso 6 and Intel MKL Pardiso are not compatible as they have different API. You may try to remove MKL from your systems paths, add OpenBLAS, and try to link your example once again.

Related

Cannot find dynamic library when running a Python script from Bazel

I am trying to setup CUDA enabled Python & TensorFlow environment on OSx 10.11.6
Everything went quite smoothly. First I installed following:
CUDA - 7.5
cuDNN - 5.1
I ensured that the LD_LIBRARY_PATH and CUDA_HOME are set properly by adding following into my ~/.bash_profile file:
export CUDA_HOME=/usr/local/cuda
export DYLD_LIBRARY_PATH="$CUDA_HOME/lib:$DYLD_LIBRARY_PATH"
export LD_LIBRARY_PATH="$CUDA_HOME/lib:$LD_LIBRARY_PATH"
export PATH="$CUDA_HOME/bin:$PATH"
Then I used Brew to install following:
python - 2.7.12_2
bazel - 0.3.2
protobuf - 3.1.0
Then I used Pip to install CPU only TensorFlow from:
https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.11.0rc0-py2-none-any.whl
I checked out the Magenta project from: https://github.com/tensorflow/magenta
and run all the test using:
bazel test //magenta/...
And all of them have passed.
So far so good. So I decided to give the GPU enabled version of TensorFlow a shot and installed it from:
https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.11.0rc0-py2-none-any.whl
Now all the tests fail with the following error:
import tensorflow as tf
File "/usr/local/lib/python2.7/site-packages/tensorflow/__init__.py", line 23, in <module>
from tensorflow.python import *
File "/usr/local/lib/python2.7/site-packages/tensorflow/python/__init__.py", line 49, in <module>
from tensorflow.python import pywrap_tensorflow
File "/usr/local/lib/python2.7/site-packages/tensorflow/python/pywrap_tensorflow.py", line 28, in <module>
_pywrap_tensorflow = swig_import_helper()
File "/usr/local/lib/python2.7/site-packages/tensorflow/python/pywrap_tensorflow.py", line 24, in swig_import_helper
_mod = imp.load_module('_pywrap_tensorflow', fp, pathname, description)
ImportError: dlopen(/usr/local/lib/python2.7/site-packages/tensorflow/python/_pywrap_tensorflow.so, 10): Library not loaded: #rpath/libcudart.7.5.dylib
Referenced from: /usr/local/lib/python2.7/site-packages/tensorflow/python/_pywrap_tensorflow.so
Reason: image not found
So obviously the script run from Bazel has trouble locating the libcudart.7.5.dylib library.
I did try running GPU computations from Python without Bazel and everything seems to be fine.
I also did create a test script and run it using Bazel and it seems that the directory containing libcudart.7.5.dylib library is reachable, however the LD_LIBRARY_PATH is not set.
I searched the documentation and found --action_env and --test_env flags, but none of them actually seems to set the LD_LIBRARY_PATH for the execution.
These are the options from loaded from .bazelrc files.
Inherited 'common' options: --isatty=1 --terminal_columns=80
Inherited 'build' options: --define=allow_oversize_protos=true --copt -funsigned-char -c opt --spawn_strategy=standalone
'run' options: --spawn_strategy=standalone
What is the correct way to let Bazel know about the runtime dependencies?
UPDATE
The trouble seems to be caused by the fact that "env" command is part of the execution chain and it does seem to clear both LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environmental variables. Is there a workaround different than disabling the SIP?
It looks like SIP affects the behavior of how the DYLD_LIBRARY_PATH gets propagated to the child processes. I found a similar problem and another similar problem.
I didn't want to turn the SIP off, so I just created symlinks for the CUDA library into a standard location.
ln -s /usr/local/cuda/lib/* /usr/local/lib
Not sure if this is the best solution, but it does work and it does not require the SIP to be disabled.
Use
export LD_LIBRARY_PATH=/usr/local/cuda/lib64/
before launching bazel. Double check in the directory above if there is such a file.
ls /usr/local/cuda/lib64/libcudart.7.5.dylib
Note that in Macosx the name is different:
export DYLD_LIBRARY_PATH=/usr/local/cuda/lib/
See this answer for more information on SuperUser
The problem is indeed SIP, and the solution is to pass --action_env DYLD_LIBRARY_PATH=$CUDA_HOME/lib to the bazel command, e.g.:
bazel build -c opt --config=cuda --action_env DYLD_LIBRARY_PATH=$CUDA_HOME/lib //tensorflow/tools/pip_package:build_pip_package

Using f2py on a Fortran code linked to PETSc

My question is related to this post:
Including a compiled module in module that is wrapped with f2py (Minimum working example)?
in which the poster was trying to compile a Fortran code (Test.f90) with f2py and link that to a pre-compiled library (or in my case, object, myex44f.o). The answer enabled me to compile the Fortran code and generated the python module.
My problem is different from the above posters problem in that my object is linked to PETSc. When I try to import my f2py-generated library into python, I get the error that it cannot locate 'VecDestroy', a PETSc subroutine. My most recent attempt was:
f2py -c --fcompiler=gfortran -I. myex44f.o ../../../Codes/third_party/petsc/include/petsc/finclude/petscdef.h -m test Test.f90
Here is the code Test.f90:
subroutine test
USE petsctest
call mainsub
end subroutine test
which calls mainsub from the module petsctest:
module petsctest ! Solves the linear system J x = f
#include <petsc/finclude/petscdef.h>
contains
subroutine mainsub
use petscksp; use petscdm
Vec x,f
Mat J
DM da
KSP ksp
PetscErrorCode ierr
call PetscInitialize(PETSC_NULL_CHARACTER,ierr)
call DMDACreate1d(MPI_COMM_WORLD,DM_BOUNDARY_NONE,8,1,1, &
& PETSC_NULL_INTEGER,da,ierr)
call DMCreateGlobalVector(da,x,ierr)
call VecDuplicate(x,f,ierr)
call DMSetMatType(da,MATAIJ,ierr)
call DMCreateMatrix(da,J,ierr)
call ComputeRHS(da,f,ierr)
call ComputeMatrix(da,J,ierr)
call KSPCreate(MPI_COMM_WORLD,ksp,ierr)
call KSPSetOperators(ksp,J,J,ierr)
call KSPSetFromOptions(ksp,ierr)
call KSPSolve(ksp,f,x,ierr)
call MatDestroy(J,ierr)
call VecDestroy(x,ierr)
call VecDestroy(f,ierr)
call KSPDestroy(ksp,ierr)
call DMDestroy(da,ierr)
call PetscFinalize(ierr)
end
The error that I get is:
import test Traceback (most recent call last): File "", line 1, in ImportError: ./test.so: undefined symbol: vecdestroy_
Does anyone have any suggestions? Thank you very much for any help you can provide me.
UPDATE:
I generated the original myex44f.o object using the makefile provided with the PETSc examples. Looking at the link line, I reasoned that I might need to link the petsc library when compiling with f2py. My current attempt is:
f2py -c --fcompiler=gfortran -m test Test.f90 -I. myex44f.o -I/home/costoich/Documents/AFPWork/Codes/third_party/petsc/include -I/home/costoich/Documents/AFPWork/Codes/third_party/petsc/arch-linux2-c-debug/include -L/home/costoich/Documents/AFPWork/Codes/third_party/petsc/arch-linux2-c-debug/lib -lpetsc
This seems to be linking correctly during the compile steps (if I just write -lpetsc without the path the compiler fails). However, when I type ldd test.so, I get:
linux-vdso.so.1 => (0x00007ffe09886000)
libpetsc.so.3.7 => not found
libgfortran.so.3 => /usr/lib/x86_64-linux-gnu/libgfortran.so.3 (0x00007fc315be5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc31581b000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007fc3155dc000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc3152d3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc3150bc000)
/lib64/ld-linux-x86-64.so.2 (0x000055a3fad27000)
Do I need two use the link flags Wl,rpath? f2py seems to not understand these. Thank you for any comments.
RESOLVED
I found my issue. I can't get f2py to accept the -Wl,rpath options, but if I define the environment variable LD_LIBRARY_PATH=/home/costoich/Documents/AFPWork/Codes/third_party/petsc/arch-linux2-c-debug/lib everything works out. Thank you for your help.
#VladimirF, has a point.
It looks like if the VecDestrou is not in the PETSC module you are using.
Seems to me following parts of PETSc are required in your module.
#include <petsc/finclude/petscsysdef.h>
#include <petsc/finclude/petscvecdef.h>
! Optional
#include <petsc/finclude/petscdef.h>
#include <petsc/finclude/petscdm.h>
#include <petsc/finclude/petscvec.h>
#include <petsc/finclude/petscvec.h90>
#include <petsc/finclude/petscmat.h>
#include <petsc/finclude/petscmat.h90>
! might be not completed
! Or
use petscksp
use petscdm
use petscvec
use petscmat
!might be not completed
How to use PETSc with Fortran is diccussed here, personally I go for option 2 in that page. Most of the existing PETSc examples are following option 2 as well.
Please let me clarify that I am not encouraging you to use include over use, that's the way I am used to do only. PETSc documentation has an example that using Fortran modules, for example here. So you can choose any of these methods/or have both optionally (please realize that preprocessor option in that example, PETSC_USE_FORTRAN_MODULES), but still need to add required modules depends on what you are using.

boost_python3 missing from ubuntu 16.04

I am trying to install boost.numpy in y Ubuntu 16.04. I tried these commnads to install boost.numpy
**git clone https://github.com/ndarray/Boost.NumPy.git
cd Boost.NumPy && mkdir build && cd build
cmake -DPYTHON_LIBRARY=$HOME/anaconda3/lib/libpython3.5m.so ../**
After doing cmake i am facing this error:
Detected architecture 'x86_64'
-- Using Python3
CMake Error at /usr/share/cmake-3.5/Modules/FindBoost.cmake:1677 (message):
Unable to find the requested Boost libraries.
Boost version: 1.59.0
Boost include path: /home/sumit/Documents/Software/boost_1_59_0
Could not find the following static Boost libraries:
boost_python3
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the
directory containing Boost libraries or BOOST_ROOT to the location of
Boost.
Call Stack (most recent call first):
CMakeLists.txt:48 (find_package)
Boost Paths:
Include : /home/sumit/Documents/Software/boost_1_59_0
**Libraries**: /home/sumit/Documents/Software/boost_1_59_0/libs
Configuring incomplete, errors occurred!
See also "/home/sumit/Documents/Software/Boost.NumPy/build/CMakeFiles/CMakeOutput.log".
Previously it was not able to find the boost libraries sp i manualy changed the CmakeList.txt library path with the path of boost_1_59_0 lib path. This path comes up in library option when i do cmake. But still boost_python3 is missing. I am new into this what i tried is just the result of google.
Please help.
On Ubuntu the library names for boost are:
libboost_python, libboost_python-py35, or libboost_python-py27
This means that in cmake you'll need to refer to them as python-py35 instead of python3. Alternatively, if you don't control the CMakeLists.txt you can create a symlink:
/usr/lib/x86_64-linux-gnu/libboost_python-py35.so -> /usr/lib/x86_64-linux-gnu/libboost_python3.so
In my CMakeLists.txt file I have the following:
if(UNIX)
set( BOOST_PYTHONLIB python-py35)
else()
set( BOOST_PYTHONLIB python3)
endif()
find_package (Boost 1.58 REQUIRED COMPONENTS
coroutine
context
filesystem
program_options
system
thread
${BOOST_PYTHONLIB}
chrono
)
Simple answer for this is that wherever boost_python3 is specified,
you replace it with boost_python-py35.
I tried this when I was setting up caffe for python 3.5 . In the Makefile.config file, I only made the above changes and it worked fine for me.

MIDI on Python / PyGame, Ubuntu 12.04

Trying to get a MIDI interface to work with pygame on Ubuntu 12.04. I know the keyboard works because it can control vkeybd and works with PyGame on OSX, so the issue with with MIDI in python.
$ python -m pygame.examples.midi --list
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/usr/lib/python2.7/dist-packages/pygame/examples/midi.py", line 820, in <module>
print_device_info()
File "/usr/lib/python2.7/dist-packages/pygame/examples/midi.py", line 25, in print_device_info
pygame.midi.init()
File "/usr/lib/python2.7/dist-packages/pygame/midi.py", line 71, in init
import pygame.pypm
ImportError: /usr/lib/libportmidi.so.0: undefined symbol: snd_seq_event_input_pending
python-pygame installed through the package manager, as is python-pm.
Any ideas? :)
Although this won't exactly answer your question, it may help you debug the problem yourself.
The error is this :
ImportError: /usr/lib/libportmidi.so.0: undefined symbol: snd_seq_event_input_pending
The undefined symbol is a failure of the dynamic linker to find the code required for the snd_seq_event_input_pending function.
On an example 32 bit Oneiric system we can do this to look at some symbols of libportmidi.so.0.
nm -DC /usr/lib/libportmidi.so.0 | grep snd_seq_event_input_pending
U snd_seq_event_input_pending
This tells us that the libportmidi library requires the code for snd_seq_event_input_pending but the symbol is undefined. So for libportmidi to function it must also load an additional library which contains this function.
On Oneiric I've found that this symbol is defined in libasound2.so.2.
nm -DC /usr/lib/i386-linux-gnu/libasound.so.2 | grep snd_seq_event_input_pending
000a0fa0 T snd_seq_event_input_pending
The T indicates that the function exists and is in the text (code) segment.
Usually, linking of associated libraries occurs automatically as libasound.so.2 should be referenced by libportmidi. On the same system.
ldd /usr/lib/libportmidi.so.0
....
libasound.so.2 => /usr/lib/i386-linux-gnu/libasound.so.2 (0x00e35000)
which shows that libmidi depends on libasound. In the ldd output list in your comments there is no reference to libasound, and so it won't try to automatically dynamically link libasound.so.2 when it is loaded, resulting in your error.
There's a few reasons why there may be an error:
The way linking from libportmidi may have change from Oneiric to Precise. eg libportmidi may attempt to find its own dependencies for libasound. (Unlikely).
There is a bug in packaging of libportmidi where it doesn't reference libasound.so.2 as it should. This may be platform specific (eg only an error on 64 bit systems).
I'd suggest that you try to find out the library on your system that contains the snd_seq_event_input_pending function and then work backwards to try and determine why it has not been linked with libportmidi.
The following bash command will help you find the libaries implementing snd_seq_event_input_pending. If you don't find anything, there's a problem with the libraries installed on your machine.
find /lib /usr/lib -name "lib*.so.*" | while read f; do
if nm -DC "$f" | grep -q 'T snd_seq_event_input_pending'; then
echo "$f"
fi
done
I have exactly the same problem (on Ubuntu 12.04.1), using e.g. the MIDI playback tool in Frescobaldi (which is a Python application). This used to work fine, but doesn't anymore.
This is quite obviously a miscompiled portmidi package which was pushed out on on 2013-01-25, see https://launchpad.net/ubuntu/+source/portmidi/1:200-0ubuntu1.12.04.1. Downgrading to the previous 1:200-0ubuntu1 package solved the issue for me.
I guess that the proper course of action would be to file a bug report against the 1:200-0ubuntu1.12.04.1 version on Launchpad at https://bugs.launchpad.net/ubuntu/+source/portmidi/+bugs. If it doesn't get fixed, we might also ask falkTX if he would be willing to provide a working package in his KXStudio PPAs instead.
Just for the record, here's what ldd gives for the 1:200-0ubuntu1 libportmidi on my system:
linux-vdso.so.1 => (0x00007fffe9bff000)
libasound.so.2 => /usr/lib/x86_64-linux-gnu/libasound.so.2 (0x00007f26264cb000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f26262ae000)
libporttime.so.0 => /usr/lib/libporttime.so.0 (0x00007f26260ab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2625cec000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f26259f0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f26257eb000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f26255e3000)
/lib64/ld-linux-x86-64.so.2 (0x00007f26269f4000)
And the broken 1:200-0ubuntu1.12.04.1 version:
linux-vdso.so.1 => (0x00007fff9e3ff000)
libporttime.so.0 => /usr/lib/libporttime.so.0 (0x00007fb84ac71000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb84a8b2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb84a694000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb84b0af000)
So any application which doesn't happen to link in libasound2 by itself will be hosed. Specifically, that seems to be the case for the Python portmidi module. (This kind of error is also aggravated by the fact that, at least from Ubuntu 12.04 onwards, gcc uses the --as-needed linker flag by default. I bet that there are still quite a few packages in the Ubuntu repos which are broken because of that.)
If you want fix it now you can checkout the latest version of portmidi and build the library as follows (assuming you've checked out or unpacked portmidi into a dir called portmidi):
cd portmidi
make -f pm_linux/Makefile
The default install doesn't build a dynamic version of library so you need to build one like this:
gcc -shared -Wl,-soname,libportmidi.so.0 -o pm_linux/libportmidi.so.0 pm_common/pmutil.o pm_linux/pmlinuxalsa.o pm_linux/pmlinux.o pm_common/portmidi.o -lasound
Then you can make a copy of the old library (just in case), and then copy this new one in its place:
sudo cp /usr/lib/libportmidi.so.0 /usr/lib/libportmidi.so.0.orig
sudo cp pm_linux/libportmidi.so.0 /usr/lib/libportmidi.so.0
Your apps should now work...

Undefined symbol TLSv1 with python+perforce

I installed the p4 library on my local archlinux machine and everything works smoothly.
I was now trying to do the same on a couple of virtual machines (with same OS also 64 bits) but can't get it running...
The installation goes well and doesn't complain, but when I try to import it I get:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "P4.py", line 312, in <module>
import P4API
ImportError: /usr/lib/python2.7/site-packages/P4API.so: undefined symbol: TLSv1_method
If I look in the symbols with
nm -A /usr/lib/python2.7/site-packages/P4API.so
I can see that in fact all the SSL-related symbols are undefined (while being defined on the working one), but why on earth?
I have openssl installed and Python is installed in exactly the same way, I can't find any other library that should be useful.
Any idea?
EDIT:
apparently the only difference is that in the wrong installation of P4 P4API.so is missing librt from the "ldd" output (and librt is actually there).
Not sure how it would relate to the TLS problem, and trying to reinstall glibc and then
p4python but no luck still..
Rebuilding the P4Python against the "rt" and "ssl" libraries fixes this.
Take the P4 API off the perforce site (e.g. for Linux take this: http://filehost.perforce.com/perforce/r13.2/bin.linux26x86_64/p4api.tgz)
Take the source code of P4Python off http://public.perforce.com/guest/robert_cowham/perforce/API/python/main/p4python.zip
tar xf the P4 API archive
Unzip the p4pthon archive
Edit setup.cfg to point to the P4API directory
Edit setup.py and go to line 120 and add "ssl" and "rt" so it looks like this
else: # Assume Linux
libraries = ["client", "rpc", "supp", "ssl", "rt"] # P4API libs
extra_compile_args = ["-DOS_LINUX", "-D%s" % p4_api_ver]
Do sudo python setup.py install

Categories