Search code examples
pythonpostgresqlshared-librariespsycopg2cx-freeze

cx_freeze fails to import psycopg2 shared lib at runtime


I have built an executable using cxfreeze (inside a python3.2 virtualenv) on my local machine. The executable runs correctly on the local machine.

I'm trying to run the executable on a separate target machine (of identical OS and architecture), but get the following error:

  ...
  File "/home/chris/.virtualenvs/python3env/lib/python3.2/site-packages/psycopg2/__init__.py", line 67, in <module>
  File "ExtensionLoader_psycopg2__psycopg.py", line 18, in <module>
  ImportError: No module named None

All the shared library dependencies are met on the target machine (according to ldd).

Based on the trace my guess is that psycopg2 is trying to load the shared library _psycopg.cpython-32mu.so (locally python3.2/site-packages/psycopg2/_psycopg.cpython-32mu.so) but can't find it at runtime.

I tried placing the library in the same directory as the executable and setting LD_LIBRARY_PATH, but neither solved the (assumed) problem.


Solution

  • After running strace on each process, it appears that the pure python version is looking for the file _psycopg.cpython-32mu.so

    open("/home/chris/.virtualenvs/python3env/lib/python3.2/site-packages/psycopg2/_psycopg.cpython-32mu.so", O_RDONLY|O_CLOEXEC) = 8
    

    Whereas the binary built by cxfreeze is looking for the file psycopg2._psycopg.so

    open("/path/to/psycopg2._psycopg.so", O_RDONLY|O_CLOEXEC) = 3
    

    md5sum reveals these files to be identical, so it appears that the cxfreeze process changes the expected name of the dynamic library. It's worth noting that a version of this library correctly name for the target is included in the dist directory output by cxfreeze.