The executable should not depend directly on libpython. (it is loaded
dinamically).
>
> so I guess it is something the generated binary loads dynamically.
> However, there is no 'libpython<anything>.so' on my AIX box, only
> something called libpython2.6.a and I am not sure whether this is a
> static library or a shared library. But simply copying it to my
> PyInstaller generated folder and renaming it to libpython2.6.so.1.0
> does not help.
libpython2.6.a is not a dynamic library and it can't be used with
pyinstaller.
>
> --------------
> Error loading Python lib './libpython2.6.so.1.0': 0509-022
> Cannot load module ./libpython2.6.so.1.0.
> 0509-103 The module has an invalid magic number.
> --------------
>
> Now, I am a bit stuck.
>
> Any help or pointers are highly appreciated.
PyInstaller is not made to work with statically linked python. The
bootloader is searching for any libpython*.so in your dist folder.
That's also the reason why pyinstaller does not work with activestate
python - activestate python is also statically linked.
I don't know much about C/C++ (bootloader code) but you would have to
add python interpreter to dist folder and modify bootloader to somehow
use python interpreter to run the python code with it.
Maybe you could try link the libpython.a statically when compiling the
bootloader.
I'm by no means expert on bootloader code, but you should find place in
the code where the python code is actually executed. See how it works
and how it could be changed to run python code with statically linked
python.
That sounds great.
Maybe your changes would make it possible to use ActiveState python with
pyinstaller. I think it is also statically linked.
I ran the tests like this:
bash-3.00$ buildtests/runtests.py
The results were:
{'failed': [],
'passed': ['test1',
'test2',
'test5',
'test6',
'test7',
'test8',
'test9',
'test10',
'test11',
'test12',
'test13',
'test14',
'test-email',
'test-encoders',
'test_f_option',
'test_filename',
'test-celementtree',
'test-nestedlaunch0',
'test-nestedlaunch1',
'test-relative-import',
'test-relative-import2',
'test-relative-import3',
'test_error_during_import',
'test_getfilesystemencoding'],
'skipped': ['test15',
'test-wx',
'test-numpy',
'test-pycrypto',
'test-zipimport1',
'test-zipimport2',
'test-ctypes-cdll-c',
'test-ctypes-cdll-c2']}
Nothing failed, so that's good.
I am not sure why some tests were skipped and whether that is expected or not?
/Martin
Please consider the environment before printing.
</pre>
<div style="FONT-FAMILY: arial;color:#525759;font-size:9pt; margin-top:15px">This e-mail and any attachments are intended only for the named recipient(s) and may contain information that is legally privileged, confidential, or exempt from disclosure under applicable law. This message may be logged for archival purposes, may be reviewed by parties at Deltek other than those named in the message header, and may not necessarily constitute an official representation of Deltek. If you have received this message in error, or are not the named recipient(s), you may not retain copy or use this e-mail or any attachment for any purpose or disclose all or any part of the contents to any other person. Any such dissemination, distribution or copying of this e-mail or its attachments is strictly prohibited. Please immediately notify the sender and permanently delete this e-mail and any attachment from your computer.</div>
This is expected. For some tests they are needed some additional
modules. If these modules are not present then those tests are skipped.
Like: test-numpy - you need 'numpy' module.
Could you please attach your patches to the following ticket?
http://www.pyinstaller.org/ticket/343
If you are happy with your changes could you please try backport your
changes for the svn version?
Thanks in advance.
Test if tcl/tk is available in python. Run the following import in
python console:
>>> import Tkinter
If it does not work then python was not built with tcl/tk or this
support is not installed (I don't know how installing sw on aix works.).
And I think that in this case you don't need to bother with it.
Thanks.
I hope to look at it soon.
I hope to look at it over the weekend.
Look at them if they contain platform specific code like:
if is_lin
elif is_win
elif is_mac
in the case of multipackage look at files
trunk/buildtests/multipackage/*.toc
I think we could remove the pattern
'(?i).*python.*'
since libpython is not available when it is linked statically.
We could simply remove it. Because if bootloader is linked dynamically
and libpython is missing then other test cases would fail. So we do not
need to check it in multipackage tests.
No, it does not. On my linux box it's the same (No module 'named'). I
also wonder why it is failing.
Thanks
That sounds good.
>
> 3) import/test_zipimport2
>
> Do you have a good idea what to do about this test that now fails for
> me?
> Or should I ignore it since it has to do with installation of
> setuptools?
I will add it to the list of skipped when setuptools is not installed.
does it mean that AIX uses *.a extension for shared libraries name?
>
> /opt/freeware/lib/libpython2.6.a[libpython2.6.so]:
>
> ***Object Module Header***
> # Sections Symbol Ptr # Symbols Opt Hdr Len Flags
> 4 0x001da39e 16588 72 0x3002
> Flags=( EXEC DYNLOAD SHROBJ DEP_SYSTEM )
> Timestamp = "02 sep 00:55:27 2009"
> Magic = 0x1df (32-bit XCOFF)
> <..snip..>
>
> Also, the produced binary (bootloader) depends on dynamic libraries:
The bootloader should depend on some standard dynamic libraries. That is
normal. Only the libpython should not be there.
Is the /opt/freeware/lib/libz.a available by default on every AIX
installation?
>
> bash-3.00$ ldd test
> test needs:
> /opt/freeware/lib/libz.a(libz.so.1)
> /opt/freeware/lib/libpython2.6.a(libpython2.6.so)
> /usr/lib/libc.a(shr.o)
> /usr/lib/librtl.a(shr.o)
> /usr/lib/libc.a(shr_64.o)
> /usr/lib/libpthreads.a(shr_xpg5.o)
> /usr/lib/libpthreads.a(shr_comm.o)
> /unix
> /usr/lib/libcrypt.a(shr.o)
> /usr/lib/libcrypt.a(shr_64.o)
>
> So I guess I need to dive deeper into linking the bootloader
> correctly... :-(
If the python library is dynamic library then you could just try the
same approach what's pyinstaller doing for linux:
Copy the libpython2.6.a to dist folder and update the bootloader to be
also looking for libpython with *.a extension.
Does environment variable LD_LIBRARY_PATH work on AIX?
Maybe we should try to update the wscript to tell gcc to try linking
libpython statically.
Gcc has some options how to do that.
If the libpython would be statically linked with bootloader then the
size of bootloader equals size(bootloader) + size(libpython26.a)
>
>
then the libz.a should be also present in the dist folder.
It seems to me that you will have to modify in bootloader source the
usage of dlopen() function. According to
http://stromberg.dnsalias.org/~strombrg/AIX-shared-libs.html
You will have to use dlopen like
dlopen('libpython2.6.a(libpython2.6.so)')
Explicitly saing what file should be imported from the *.a archive.
That's a hook how bootloader works.
If the libpython would be simply linking to this library you then need
libpython available in fixed location -
like: /opt/freeware/lib/libpython2.6.a
But for it to work you need libpython available at the default location
before running your binary created by pyinstaller.
Using dlopen for libpython solves this issue that you don't need
libpython in default location before executing your app - you are thus
able to run your app on system without python installed.
If the libz.a is not available as static for bootloader we should then
try to use the bundled libz used for windows platform.
Remember that you changed the wscript file to always link the bootloader
with libpython on aix.
I only commited the changes
> * Keep the code I wrote for statically linking Python. It could be
> used in the future maybe for
> linking ActiveState Python.
Could you submit the patch with code for statical linking to a new
ticket? like 'support statical linking of python library'?
> * Keep the code you have added to the 1.5 branch in change 1586
> regarding static linking of Python.
> * Remove my comments regarding AIX in connection with static linking.
> * In launch.c function "int loadPython()" add code for AIX to load the
> shared lib correctly as
> "libpython<ver>.a(libpythonx<ver>.so)".
I think we would need to modify the bindepend.py for resolving binary
dependencies for AIX. There should be a function which uses 'ldd'
command to do this. Maybe it should be modified for aix if id does not
work.
>
> After that I will have to address the problems with libc and libz.
You don't need to bother with libc.(in case you do not use your own
version). Every binary in system is dependent on system libc.
Let me know if should link libz statically with loader for aix. It
should be trivial to make such changes to wscript.
>
> Does it sound reasonable?
If possible against ./branches/1.5
Done
any progress with that?
Martin Gamwell Dawids píše v Čt 22. 09. 2011 v 08:38 -0700:
It is similar to solaris support. Patch for solaris is merged in trunk
and in 1.5 branch and it includes hook for the mkdtemp function.
Maybe it is similar for AIX. Look at
http://www.pyinstaller.org/changeset/1610
It seems like the bootloader is working now.
>
> So it seems I have (at least) two problems left to resolve:
>
> 1) I should prevent libc.a and libpthreads.a from being packaged along
> with the application. I guess it is the regexes in bindepend.py which
> does not work for AIX, as they incorrectly assume all shared libs ends
> with ".so".
yes, that's correct. Maybe there are more libraries with .a which should
be also ignored.
>
> 2) Python cannot find packages to import unless the current working
> dir contains the shared objects. Any ideas how to fix this?
You should try to use ArchiveViewer.py to inspect created binaries what
python modules get included.
Look for linux specific python code which is not adjusted for AIX.
Add some print statements to the code where python module dependencies
are analyzed.
look at tools 'ldd' and 'objdump' if these are available on your AIX
devel. machine and look how these are used in pyinstaller if their
output is properly parsed by pyinstaller.
(maybe their output could is formatted differently and thus is not
properly parsed by pyinstaller)
>
> Thank you for your invaluable help so far!
Some hints:
- i would recommend focusing on --onedir mode only for now (onefile is
harder)
- use option --debug for ./Makespec.py to get more debug messages
- in iu.py at the top in debug(msg) function enable debugging to see at
runtime what modules are loaded
- do not worry about trunk, I can do the backport of AIX support
Boot loader sets LD_LIBRARY_PATH for linux. However I found out that for
AIX it should set LIBPATH environment variable.
http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
Look in the bootloader code for place where LD_LIBRARY_PATH is set and
try to use LIBPATH for AIX.
Pyinstaller will probably work on 5.x. But the apps created on 6.1 might
not work on 5.x. I think that apps created on 6.1 should work on 7.
Just create an AIX specific exclude list. Just keep minimum changes to
make it work on aix. Since it is a stable branch.
In svn trunk these exclude lists are already splitted for platforms.
Do not bother with test. I fixed it in svn so to fix it for 1.5 should
be easy for me.
I commited your patch into 1.5 branch.
Thanks
Tests worked for me on linux.
Just a note to C code:
for windows compatibility we try to avoid using mixed declaration and
code, like:
uint32_t pyvers_major;
uint32_t pyvers_minor;
pyvers_major = ntohl(f_cookie.pyvers) / 10;
pyvers_minor = ntohl(f_cookie.pyvers) % 10;
const char* dllPathPrefix = f_workpath ? f_workpath : f_homepath;
That was only change I made. Otherwise it seems ok. Could you please
test the code directly from 1.5 branch if it still woks?
If you want to port AIX to trunk I would appreciate that. The code
changed recently. I made some refactoring. For code specific to
Linux/Solaris/AIX there is a variable 'is_unix'.
Do you think you could write some text for the manual? I would welcome
some info about:
- what and how to install tools on AIX necessary for pyinstaller to work
- how to compile bootloader on AIX (in case there is something special
to be done by users).
Well, this line broke compilation on windows. I moved it to unix
specific part. Otherwise it is ok. I fixed it for 1.5.
> For code specific to
> > Linux/Solaris/AIX there is a variable 'is_unix'.
>
> That sounds good. I also remember having seen other variables like
> this to avoid constantly duplicated (and possible inconsistent) calls
> to 'sys.platform.startswith(<something>)'.
There is a bunch of them:
from PyInstaller import is_win, is_darwin, is_unix, is_solar, is_aix
Could you try compile bootloader with xlc? I suppose it is the default
compiler.
Is the /opt/freeware/lib standard path on aix for freeware libs?
MS Visual studio 2008 express.
It should be possible to compile bootloader with mingw but mingw
bootloader is not well tested and the msvcrt library is not statically
linked with the binary as it is with msvc.
Yes, that should be fixed for 1.5.2.
What compiler is in general more used in the aix world? Gcc or xlc?
What is supposed to be better?
what about looking for command 'python-config'?
you could get some info from it like:
python-config --prefix
You could also look at the wscript file if it needs some changes to tell
gcc link libpython static.
>
> I think I will call it the day for now, and have a look at it after
> the weekend.
Or we could just state:
"Pyinstaller works on AIX 6.1, created executables should work on
5.2/5.3. PyInstaller does not work on 5.x.
That sounds good.
Thanks again for your work.
That's the decision we made. We suppose that precompiled bootloader
would be used.
I only added an option to wscript to enable symbols for static linking.
But there seems to be more to do. We need to tell gcc to link static
version of python library. I was trying to do that but without success.
Or maybe i didn't use correctly python with static lib.
thanks, fix commited.