I'm trying to freeze and distribute among my Solaris11 machines the following python code which makes use of multiprocessing module:
import multiprocessing
def f(name):
print 'hello', name
if __name__ == '__main__':
p = multiprocessing.Process(target=f, args=('fer',))
p.start()
p.join()
However, even if the executable works fine under the compiler machine (Solaris11) ...
[root@zgv-wodbuild01 pyinstaller]# testfer/dist/testfer
hello fer
[root@zgv-wodbuild01 pyinstaller]# echo $?
0
...complains about multiprocessing library in any other machine (Solaris11):
root@dest01a # ./testfer.r004
Traceback (most recent call last):
File "testfer.py", line 1, in <module>
File "/root/pyinstaller/PyInstaller/loader/pyimod03_importers.py", line 389, in load_module
File "multiprocessing/__init__.py", line 84, in <module>
File "/root/pyinstaller/PyInstaller/loader/pyimod03_importers.py", line 546, in load_module
ImportError: ld.so.1: testfer.r004: fatal: relocation error: file /tmp/_MEIlBa4uh/_multiprocessing.so: symbol __xnet_sendmsg: referenced symbol not found
Failed to execute script testfer
root@dest01a # echo $?
255
PyInstaller command has been launched with --onefile
flag so every needed library should be included inside final ELF file (multiprocessing too). But I have also tried to include explicitly multiprocessing library by editing hidden-import
section in the .spec file.
I have also tried to freeze the source in an older Solaris 10 machine to ensure backwards compatibility. Compiling the PyInstaller bootloaders both with and without special LDFLAGS like -lrt
. Using --debug
flag. But so far nothing worked nor gave me a clue.
Apparently the binary is properly built for the right architecture and there is no library issues:
root@dest01a # file testfer.r004
testfer.r004: ELF 32-bit MSB executable SPARC32PLUS Version 1, V8+ Required, UltraSPARC1 Extensions Required, dynamically linked, stripped
root@dest01a # crle
Platform: 32-bit MSB SPARC
Default Library Path (ELF): /lib:/usr/lib (system default)
Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default)
root@dest01a # ldd -r testfer.r004
libdl.so.1 => /lib/libdl.so.1
libm.so.2 => /lib/libm.so.2
libz.so.1 => /lib/libz.so.1
librt.so.1 => /lib/librt.so.1
libc.so.1 => /lib/libc.so.1
root@dest01a # ldd -r /lib/libsocket.so.1
libnsl.so.1 => /lib/libnsl.so.1
libc.so.1 => /lib/libc.so.1
libmp.so.2 => /lib/libmp.so.2
libmd.so.1 => /lib/libmd.so.1
libsoftcrypto.so.1 => /lib/libsoftcrypto.so.1
libelf.so.1 => /lib/libelf.so.1
libcryptoutil.so.1 => /lib/libcryptoutil.so.1
libz.so.1 => /lib/libz.so.1
libm.so.2 => /lib/libm.so.2
So I ran out of ideas. Thanks in advance for any insight.
Update: Thanks to Andrew Henle comments I've been able to make some progress. I have recompiled the PyInstaller bootloaders again but this time establishing LDFLAGS environment variable to LDFLAGS="-lsocket -lrt"
.
Now it's not complaining about __xnet
symbols anymore but symbol get_fips_mode
instead. As you can see:
root@lnrep01a # ./testfer.r004
ld.so.1: testfer.r004: fatal: relocation error: file /lib/libsoftcrypto.so.1: symbol get_fips_mode: referenced symbol not found
Killed
So probably I just need to add some extra flags to compiling process. I will look for them across the internet but if someone knows what is missing, that would be more than welcome.
Turned out it wasn't a gcc bug. After analysing in depth both environments, I realized the /lib/libsoftcrypto.so.1
libraries differs a lot. As a matter of fact, the library in the compiler machine contains get_fips_mode
symbol...
[root@zgv-wodbuild01 pyinstaller]# nm /lib/libsoftcrypto.so.1 | grep -i get_fips_mode
[3438] | 623016| 212|FUNC |GLOB |0 |18 |get_fips_mode
...while the destination machine does not:
root@dest01a # nm /lib/libsoftcrypto.so.1 | grep -i get_fips_mode
[3755] | 0| 0|FUNC |GLOB |0 |UNDEF |get_fips_mode
After trying another compiler machine with similar library version, compiling the pyinstaller bootloaders with -lsocket
ldflag was enough:
root@dest01a # ./testferv3
hello fer
root@dest01a # echo $?
0