cross compiling pyzmq for Android #227

Closed
cyrilh opened this Issue Jun 27, 2012 · 13 comments

Projects

None yet

2 participants

@cyrilh
Contributor
cyrilh commented Jun 27, 2012

First I followed the instructions from http://www.zeromq.org/build:android? (Revised: 2012.06.9). One patch could be necessary for libzmq: some equivalent of --disable-version used in jzmq, so as to link with -avoid-version... the alternative I found so far is a symlink from libzmq.so.3 in a folder python is searching to libzmq.so in zmq folder. Also must pull some recent version where https://zeromq.jira.com/browse/LIBZMQ-382 is solved.

Then I followed advice from http://jamaaldev.blogspot.fr/2012/01/running-volatility-memory-forensics-on.html and installed http://python-for-android.googlecode.com/files/python-lib_r16.zip

Then I did patch a bit pyzmq so it would link properly:

  • linking against target python2.6 library
  • some issue with bundle_libzmq:
    • if calling python2.6 setupegg.py build; python2.6 setupegg.py bdist_egg this will NOT bundle the library
    • if calling python2.6 setupegg.py build bdist_egg this will bundle the library, but will override the library_dirs necessary for compilation
  • I chose to fix by calling the latter and appending to library_dirs

here is the full patch:

diff  setup.py.original  setup.py
117,119c117,119
<            'libraries'      : ['zmq'],
<            'include_dirs'   : [],
<            'library_dirs'   : [],

---
>            'libraries'      : ['zmq', 'python2.6'],
>            'include_dirs'   : ['../python-lib/include/python2.6'],
>            'library_dirs'   : ['../python-lib/lib/'],
136c136
<             settings['library_dirs'] = ['zmq']

---
>             settings['library_dirs'] += ['zmq']
497c497
<         configure.check_zmq_version()

---
>         #configure.check_zmq_version()
565c565
<             configure.check_zmq_version()

---
>             #configure.check_zmq_version()
  • Using proper tools (as installed by http://www.zeromq.org/build:android?):
    CC="arm-linux-androideabi-gcc"
    LDSHARED="arm-linux-androideabi-gcc -shared"
  • Configure (or edit manually setup.cfg) to path to zmq.
  • Then as stated above, build with
    python2.6 setupegg.py build bdist_egg
  • Issues still open:
    • did not make a clean patch for libzmq -avoid-version issue, only patched src/Makefile manually, I guess it would be worth adding --disable-version to configure.in and Makefile.in
    • did not figure out yet how libzmq is to be distributed. Today, after installing the egg, I have it bundled in lib/python2.6/lib-dynload/zmq folder, but I need to manually symlink to it from the lib/python2.6/lib-dynload/ above. Maybe something like the --enable-self-contained options from jzmq?
    • did not figure out how to put python2.6 library path in setup.cfg rather than setup.py, it seems it would require some patching of buildutils.py

The complete procedure including http://www.zeromq.org/build:android? and patch from zeromq/libzmq@eb6c668

# INSTALLING TOOLCHAIN
cd /tmp
wget http://dl.google.com/android/ndk/android-ndk-r8-linux-x86.tar.bz2
tar xvfj android-ndk-r8-linux-x86.tar.bz2
sudo ./android-ndk-r8/build/tools/make-standalone-toolchain.sh --install-dir=/opt/android-toolchain
export PATH=/opt/android-toolchain/bin:$PATH

# PREPARING OUTPUT DIRECTORY
export OUTPUT_DIR=/tmp/zeromq-android

# BUILDING LIBZMQ FROM GIT WITH MANUAL PATCH
cd /tmp/
git clone https://github.com/zeromq/zeromq3-x.git
cd zeromq3-x/
echo "
@@ -126,7 +126,7 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
     int sd = open_socket (AF_INET, SOCK_DGRAM, 0);
     errno_assert (sd != -1);

-    struct ifreq ifr; 
+    struct ifreq ifr;

     //  Copy interface name for ioctl get.
     strncpy (ifr.ifr_name, nic_, sizeof (ifr.ifr_name));
@@ -371,10 +371,10 @@ int zmq::tcp_address_t::resolve_hostname (const char *hostname_, bool ipv4only_)
     zmq_assert(sa && sa_len > 0);

     memset (&address, 0, sizeof (address));
-    if (sa->sa_family == AF_INET && sa_len >= sizeof (address.ipv4)) {
+    if (sa->sa_family == AF_INET && sa_len >= (socklen_t) sizeof (address.ipv4)) {
         memcpy(&address.ipv4, sa, sizeof (address.ipv4));
     }
-    else if (sa->sa_family == AF_INET6 && sa_len >= sizeof (address.ipv6)) {
+    else if (sa->sa_family == AF_INET6 && sa_len >= (socklen_t) sizeof (address.ipv6)) {
         memcpy(&address.ipv6, sa, sizeof (address.ipv6));
     }
 }
@@ -577,7 +577,7 @@ int zmq::tcp_address_mask_t::to_string (std::string &addr_)

 const bool zmq::tcp_address_mask_t::match_address (const struct sockaddr *ss, const socklen_t ss_len) const
 {
-    zmq_assert (address_mask != -1 && ss != NULL && ss_len >= sizeof(struct sockaddr));
+    zmq_assert (address_mask != -1 && ss != NULL && ss_len >= (socklen_t) sizeof (struct sockaddr));

     if (ss->sa_family != address.generic.sa_family)
         return false;
" | patch -b src/tcp_address.cpp
./autogen.sh
./configure --host=arm-linux-androideabi --prefix=$OUTPUT_DIR CPPFLAGS="-fPIC -fvisibility=default" LIBS="-lgcc"
make
make install

cd /tmp
wget http://python-for-android.googlecode.com/files/python-lib_r16.zip
unzip python-lib_r16.zip -dpython-lib
wget https://github.com/zeromq/pyzmq/downloads/pyzmq-2.2.0.tar.gz
tar -xvf pyzmq-2.2.0.tar.gz
cd pyzmq-2.2.0
cat setup.cfg.template | sed 's|/usr/local|/tmp/zeromq-android|' > setup.cfg
echo -e "\n[bdist_egg]\nplat-name=linux-armv\n" >> setup.cfg    
echo "
117,119c117,119
<            'libraries'      : ['zmq'],
<            'include_dirs'   : [],
<            'library_dirs'   : [],

---
>            'libraries'      : ['zmq', 'python2.6'],
>            'include_dirs'   : ['../python-lib/include/python2.6'],
>            'library_dirs'   : ['../python-lib/lib/'],
136c136
<             settings['library_dirs'] = ['zmq']

---
>             settings['library_dirs'] += ['zmq']
497c497
<         configure.check_zmq_version()

---
>         #configure.check_zmq_version()
565c565
<             configure.check_zmq_version()

---
>             #configure.check_zmq_version()
" | patch -b setup.py

export CC="arm-linux-androideabi-gcc"
export LDSHARED="arm-linux-androideabi-gcc -shared"
python2.6 setupegg.py build bdist_egg
@minrk
Member
minrk commented Jun 27, 2012

Thanks for the useful info!

Trying to construct an actual issue out of this, it looks like we should:

  • make sure setup.cfg can specify libs/includes
  • allow skipping the check-version step
  • some issue with bundle_libzmq:
    • if calling python2.6 setupegg.py build; python2.6 setupegg.py bdist_egg this will NOT bundle the library
    • if calling python2.6 setupegg.py build bdist_egg this will bundle the library, but will override the library_dirs

Yes, I've encountered this. I believe it is a result of clean firing in the wrong place / under the wrong conditions. I've been using the build bdist_egg workaround for quite a while. The easiest fix is probably to remove the implied clean, and just trust users to have done clean prior to bdist.

@cyrilh
Contributor
cyrilh commented Jun 27, 2012

Agree with your 2 actions.
In addition:

  • Action 3: I think 136c136 patch is a bugfix to apply for all.
  • Action 4: document this on http://www.zeromq.org/build:android and/or http://www.zeromq.org/bindings:python
  • Action 5: define how libzmq should be installed on Android: why is it bundled in zmq folder? why do I need a symlink from the folder above? Should bundle_libzmq take libzmq.so.3 (follow symlinks in /path/to/zmq)?

The reason for build bdist_egg is the bundle_libzmq that will detect that both are present and do the associated if for build command, while if you do build alone it wont do bundle_libzmq.

Ideally https://github.com/zeromq/zeromq3-x.git should include the patch from zeromq/libzmq@eb6c668, but I dont know the dynamic of that project. As it was a known issue and already in trunk libzmq I did not comment on it.

@minrk
Member
minrk commented Jun 27, 2012

Action 3: I think 136c136 patch is a bugfix to apply for all.

Sure - it is absolutely correct at present, because libzmq is the only library linked. Adding optional linking changes that.

Action 4: document this on http://www.zeromq.org/build:android and/or http://www.zeromq.org/bindings:python

Those are wikis - by all means, please contribute to them.

Action 5: define how libzmq should be installed on Android: why is it bundled in zmq folder?

I don't really know the answer to this one. I don't have any experience cross-compiling.
Currently bdists are only used for building eggs/installers with bundled libzmq, because a bdist without bundled libzmq makes no sense.

why do I need a symlink from the folder above?

I have no idea - probably something wrong with the android Python.

Should bundle_libzmq take libzmq.so.3 (follow symlinks in /path/to/zmq)?

It already does this - when you specify --zmq=foo, it finds the library, and copies it into the zmq dir.

If this requires too much monkeying around with the already much-too-complex setup.py, then I will suggest that cross-compiling be done with an entirely different setup.py (as with your patch), because cross-compiling is simply not important enough to justify adding too much complexity to the build process.

@minrk
Member
minrk commented Jun 27, 2012

Also, as for libzmq - just send a pull request if there are patches you think should be applied to a particular repo.

@cyrilh
Contributor
cyrilh commented Jun 27, 2012

Those are wikis - by all means, please contribute to them.

I will (and have started in a humble way). Will do more when git code is stable (not documenting patching more than a link to an issue).

Should bundle_libzmq take libzmq.so.3 (follow symlinks in /path/to/zmq)?
It already does this - when you specify --zmq=foo, it finds the library, and copies it into the zmq dir.

If this requires too much monkeying around with the already much-too-complex setup.py, then I will suggest that cross->compiling be done with an entirely different setup.py (as with your patch), because cross-compiling is simply not >important enough to justify adding too much complexity to the build process.

This might be a problem on any system and not only cross compiling:

  • when libzmq is built as libzmq.so.3.0.0 with soname=libzmq.so.3 and then symlinked to libzmq.so.3 and libzmq.so, I suspect any include when linked to libzmq.so will then look for libzmq.so.3
  • why (which PATH variable) tells to look for libzmq.so in zmq folder and not on a standard library folder? Is the "bundle_libzmq" tested on e.g. any linux system?

But I agree with your argument of not making setup.py more complex... I acutally think libzmq could be seen as a dependency to be installed separately without bundling => maybe make an option for not bundling libzmq at all?

@minrk
Member
minrk commented Jun 27, 2012

when libzmq is built as libzmq.so.3.0.0 with soname=libzmq.so.3 and then symlinked to libzmq.so.3 and libzmq.so, I suspect any include when linked to libzmq.so will then look for libzmq.so.3

This is already handled, because it uses os.path.realpath, which follows symlinks, to pull in libzmq.so.X (or libzmq.X.dylib).

why (which PATH variable) tells to look for libzmq.so in zmq folder and not on a standard library folder?

It is in the rpath (runtime_library_dirs) compiler option to look relative to the zmq dir.

Is the "bundle_libzmq" tested on e.g. any linux system?

Yes, I use it regularly. Mostly on Ubuntu, but occasionally other systems.

I actually think libzmq could be seen as a dependency to be installed separately without bundling => maybe make an option for not bundling libzmq at all?

If libzmq were a dependency, that would make bdists pretty pointless. This is a cross-compilation issue, because it is totally silly to make a bdist that excludes libzmq on any normal environment. sdists totally cover that case in all sensible circumstances other than cross-compilation.

@cyrilh
Contributor
cyrilh commented Jun 27, 2012

This is already handled, because it uses os.path.realpath, which follows symlinks, to pull in libzmq.so.X (or libzmq.X.dylib)

As I see it it setup.py pulls libzmq.so.X but keep it named libzmq.so... while something from pyzmq or libzmq.so itself is trying to load dynamically libzmq.so.3. This may be due to the bundled libzmq.so file embedding soname="libzmq.so.3".

About the search path, I will have to check the rpath and maybe that thing called "$ORIGIN"? In case you see something obvious in the following:

The python environement:

export EXTERNAL_STORAGE=/mnt/sdcard
export LANG=en
export PYTHONPATH=/mnt/sdcard/com.googlecode.pythonforandroid/extras/python:/data/data/com.googlecode.pythonforandroid/files/python/lib/pyt    hon2.6/lib-dynload:/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6
export TEMP=/mnt/storage/com.googlecode.pythonforandroid/extras/python/tmp
export PYTHON_EGG_CACHE=$TEMP
export PYTHONHOME=/data/data/com.googlecode.pythonforandroid/files/python
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/data/com.googlecode.pythonforandroid/files/python/lib:/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload:/mnt/sdcard/com.googlecode.pythonforandroid/extras/python
/data/data/com.googlecode.pythonforandroid/files/python/bin/python

The python command from the installed egg:

>>> import zmq
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__.py", line 26, in <module>
    from zmq.utils import initthreads # initialize threads
ImportError: Cannot load library: link_image[1963]: 22913 could not load needed library 'libzmq.so.3' for 'initthreads.so' (load_library[1105]: Library 'libzmq.so.3' not found)

Strace:

Process 22913 attached - interrupt to quit
read(0, 0x6d6d0, 1024)                  = ? ERESTARTSYS (To be restarted)
read(0, 0x6d6d0, 1024)                  = ? ERESTARTSYS (To be restarted)
read(0, 0x6d6d0, 1024)                  = ? ERESTARTSYS (To be restarted)
read(0, "import zmq\n", 1024)           = 11
futex(0x643bc, 0x81 /* FUTEX_??? */, 1) = 0
stat64("zmq", 0xbe959488)               = -1 ENOENT (No such file or directory)
open("zmq.so", O_RDONLY|O_LARGEFILE)    = -1 ENOENT (No such file or directory)
open("zmqmodule.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("zmq.py", O_RDONLY|O_LARGEFILE)    = -1 ENOENT (No such file or directory)
open("zmq.pyc", O_RDONLY|O_LARGEFILE)   = -1 ENOENT (No such file or directory)
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/distribute-0.6.27-py2.6.egg/zmq", 0xbe959488) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/distribute-0.6.27-py2.6.egg/zmq.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/distribute-0.6.27-py2.6.egg/zmqmodule.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/distribute-0.6.27-py2.6.egg/zmq.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/distribute-0.6.27-py2.6.egg/zmq.pyc", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
stat64("/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/zmq", 0xbe959488) = -1 ENOENT (No such file or directory)
open("/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/zmq.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/zmqmodule.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/zmq.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/zmq.pyc", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__.py", {st_mode=S_IFREG|0755, st_size=1348, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__", 0xbe958428) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__module.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__.py", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0755, st_size=1348, ...}) = 0
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__.pyc", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=1261, ...}) = 0
mprotect(0x40011000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x40011000, 4096, PROT_READ)   = 0
read(4, "\321\362\r\n\310y\230Oc\0\0\0\0\0\0\0\0\10\0\0\0@\0\0\0s\362\0\0\0d\0\0Z\0\0d\1\0d\2\0k\1\0Z\1\0e\1\0i\2\0i\3\0d\3\0\203\1\0ov\0\1d\1\0d\2\0k\4\0Z\4\0d\1\0d\2\0k\5\0Z\5\0e\4\0i\6\0i\7\0e\10\0\203\1\0Z\t\0e\4\0i\6\0i\n\0e\t\0d\4\0\203\2\0Z\v\0e\4\0i\6\0i\f\0e\v\0\203\1\0o\24\0\1e\5\0i\r\0i\16\0e\v\0\203\1\0\1n\1\0\1[\t\0[\v\0[\5\0[\4\0n\1\0\1d\1\0d\5\0k\17\0l\20\0Z\20\0"..., 4096) = 1261
fstat64(4, {st_mode=S_IFREG|0755, st_size=1261, ...}) = 0
read(4, "", 4096)                       = 0
close(4)                                = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/sys", 0xbe9550b8) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/sys.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/sysmodule.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/sys.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/sys.pyc", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/zmq", 0xbe9550b8) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/zmq.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/zmqmodule.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/zmq.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/zmq.pyc", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/__init__.py", {st_mode=S_IFREG|0755, st_size=0, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/__init__", 0xbe954058) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/__init__.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/__init__module.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/__init__.py", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/__init__.pyc", O_RDONLY|O_LARGEFILE) = 9
fstat64(9, {st_mode=S_IFREG|0755, st_size=137, ...}) = 0
mprotect(0x40011000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x40011000, 4096, PROT_READ)   = 0
read(9, "\321\362\r\n\310y\230Oc\0\0\0\0\0\0\0\0\1\0\0\0@\0\0\0s\4\0\0\0d\0\0S(\1\0\0\0N(\0\0\0\0(\0\0\0\0(\0\0\0\0(\0\0\0\0s2\0\0\0build/bdist.linux-x86_64/egg/zmq/utils/__init__.pyt\10\0\0\0<module>\1\0\0\0s\0\0\0\0", 4096) = 137
fstat64(9, {st_mode=S_IFREG|0755, st_size=137, ...}) = 0
read(9, "", 4096)                       = 0
close(9)                                = 0
close(4)                                = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/initthreads", 0xbe9550a8) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/initthreads.so", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=28597, ...}) = 0
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/initthreads.so", {st_mode=S_IFREG|0755, st_size=28597, ...}) = 0
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/utils/initthreads.so", O_RDONLY|O_LARGEFILE) = 9
lseek(9, 0, SEEK_SET)                   = 0
read(9, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\254\v\0\0004\0\0\0\310]\0\0\2\0\0\0054\0 \0\4\0(\0\36\0\33\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34\33\0\0\34\33\0\0\5\0\0\0\0\20\0\0\1\0\0\0\34\33\0\0\34+\0\0\34+\0\0l\2\0\0\310\2\0\0\6\0\0\0\0\20\0\0\2\0\0\0004\33\0\0004+\0\0004+\0\0\350\0\0\0\350\0\0\0\6\0\0\0\4\0\0\0Q\345td\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\0\0\0\4\0\0\0%\0\0\0009\0\0"..., 4096) = 4096
lseek(9, -8, SEEK_END)                  = 28589
read(9, "ple_New\0", 8)                 = 8
mmap2(0x80400000, 12288, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x80400000
mmap2(0x80400000, 6940, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 9, 0) = 0x80400000
mprotect(0x80400000, 8192, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mmap2(0x80402000, 3464, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 9, 0x1) = 0x80402000
close(9)                                = 0
stat64("/vendor/lib/libzmq.so.3", 0xbe956b58) = -1 ENOENT (No such file or directory)
stat64("/system/lib/libzmq.so.3", 0xbe956b58) = -1 ENOENT (No such file or directory)
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/libzmq.so.3", 0xbe956b58) = -1 ENOENT (No such file or directory)
stat64("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/libzmq.so.3", 0xbe956b58) = -1 ENOENT (No such file or directory)
stat64("/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/libzmq.so.3", 0xbe956b58) = -1 ENOENT (No such file or directory)
stat64("/vendor/lib/libzmq.so.3", 0xbe956b58) = -1 ENOENT (No such file or directory)
stat64("/system/lib/libzmq.so.3", 0xbe956b58) = -1 ENOENT (No such file or directory)
munmap(0x80400000, 12288)               = 0
close(4)                                = 0
close(3)                                = 0
futex(0xb424, 0x81 /* FUTEX_??? */, 1)  = 0
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "Traceback (most recent call last):\n", 35) = 35
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "  File \"<stdin>\", line 1, in <module>\n", 38) = 38
open("<stdin>", O_RDONLY|O_LARGEFILE)   = -1 ENOENT (No such file or directory)
open("<stdin>", O_RDONLY|O_LARGEFILE)   = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/distribute-0.6.27-py2.6.egg/<stdin>", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/<stdin>", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/<stdin>", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/<stdin>", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python26.zip/<stdin>", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/<stdin>", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info/<stdin>", O_RDONLY|O_LARGEFILE) = -1 ENOTDIR (Not a directory)
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "  File \"/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__.py\", line 26, in <module>\n", 129) = 129
open("/data/data/com.googlecode.pythonforandroid/files/python/lib/python2.6/lib-dynload/zmq/__init__.py", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0755, st_size=1348, ...}) = 0
mprotect(0x40011000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x40011000, 4096, PROT_READ)   = 0
read(3, "\"\"\"Python bindings for 0MQ.\"\"\"\n\n#-----------------------------------------------------------------------------\n#  Copyright (C) 2010-2012 Brian Granger, Min Ragan-Kelley\n#\n#  This file is part of pyzm"..., 4096) = 1348
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "    ", 4)                     = 4
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "from zmq.utils import initthreads # initialize threads\n", 55) = 55
close(3)                                = 0
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "ImportError", 11)             = 11
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, ": ", 2)                       = 2
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "Cannot load library: link_image[1963]: 22913 could not load needed library \'libzmq.so.3\' for \'initthreads.so\' (load_library[1105]: Library \'libzmq.so.3\' not found)", 163) = 163
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
write(2, "\n", 1)                       = 1
futex(0x28cb4, 0x81 /* FUTEX_??? */, 1) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(2, ">>> ", 4)                     = 4
read(0, 0x6d6d0, 1024)                  = ? ERESTARTSYS (To be restarted)
@minrk
Member
minrk commented Jun 27, 2012

I believe that means it is not linking against the bundled libzmq, but still linking against the original. This does not happen on a regular Linux system, so it is specific to your cross-compiling setup. Either this is a peculiarity of the android platform, or you have not actually patched the compiler settings correctly in your setup.py

python setupegg.py build bdist_egg certainly builds working libzmq linked against the bundled libzmq on regular Linux, as I use eggs to install pyzmq+libzmq on Linux systems without libzmq on a regular basis.

@cyrilh
Contributor
cyrilh commented Jun 28, 2012

The problem was indeed created by my cross compilation patch.

The problem came from the version of setup.py I was using (https://github.com/zeromq/pyzmq/downloads/pyzmq-2.2.0.tar.gz), that adds bundled zmq to library_dirs in the end (before my patch it replaced the old path, but with my patch it adds the second path to the first ).

EDIT: I just checked trunk... it is much reworked setup.py and buildutils and I guess I have to switch to that before patching any more. Did you work on reading more libraries from setup.cfg ? If not I can start on it.
I saw this part of setup.py had been reworked on trunk, so I'll try it.

@minrk
Member
minrk commented Jun 28, 2012

No, I haven't done any work on this

@cyrilh
Contributor
cyrilh commented Jul 2, 2012

Still working on that. I managed to build my egg patching the trunk "https://github.com/zeromq/pyzmq" setup system.

Generic questions:

  • If I am correct trunk setup is reworked from https://github.com/zeromq/pyzmq/tree/v2.2.0 and I should work with trunk
  • Do you feel I should keep my job as a recipe based on tag v2.2.0 and stop trying to merge in trunk?
  • I also don't know if it is clean to post patches here... I guess I should upload them somewhere instead?

Description of the changes I made:

  • get_cfg_args in buildutils/config.py now parsing more setup.cfg, without increasing much code complexity
  • get_cfg_args returns all settings and not only ZMQ
  • in setup.py, CONFIGURATION = discover_settings(), then I assign ZMQ, ZMQVER, TARGET, CROSSCOMPILE
  • I rewrote init_settings

About the way to "bundle":

  • I am a bit confused about "bundle_libzmq_dylib" and ZMQ == "bundled"... do we need to divide those two? what is the meaning? I feel this would need some cleaning.
  • I must still make a symlink from "python/lib/python2.6/lib-dynload/libzmq.so.3" to "python/lib/python2.6/lib-dynload/zmq/libzmq.so". I am crosscompiling in the case "bundle_libzmq_dylib = True" (due to the command line choice "python2.6 setupegg.py clean build bdist_egg"), but not with ZMQ="bundled"... should I do otherzise? Any hint?
  • I did merge bundled_settings() and settings_from_prefix() back into init_settings(), was it a good reason for the split?
@minrk
Member
minrk commented Jul 2, 2012

If I am correct trunk setup is reworked from https://github.com/zeromq/pyzmq/tree/v2.2.0 and I should work with trunk

Yes

Do you feel I should keep my job as a recipe based on tag v2.2.0 and stop trying to merge in trunk?

No, I would base it on trunk (master)

I also don't know if it is clean to post patches here... I guess I should upload them somewhere instead?

Pull Requests are ideal.

I am a bit confused about "bundle_libzmq_dylib" and ZMQ == "bundled"... do we need to divide those two? what is the meaning? I feel this would need some cleaning.

Apologies for the ambiguity. bundle_libzmq_dylib means bring libzmq.$SO into zmq, so that it's part of the install. --zmq=bundled means build libzmq itself as a Python extension (fallback, so that pyzmq is pip-installable).

I must still make a symlink from "python/lib/python2.6/lib-dynload/libzmq.so.3" to "python/lib/python2.6/lib-dynload/zmq/libzmq.so". I am crosscompiling in the case "bundle_libzmq_dylib = True" (due to the command line choice "python2.6 setupegg.py clean build bdist_egg"), but not with ZMQ="bundled"... should I do otherzise? Any hint?

I'm not sure. This is not an issue that seems to come up on normal systems.

I did merge bundled_settings() and settings_from_prefix() back into init_settings(), was it a good reason for the split?

Yes, please do not do this.

@cyrilh
Contributor
cyrilh commented Jul 3, 2012

I have solved the dependency to libzmq.so.3, see zeromq/zeromq3-x#16

I have moved back to original bundled_settings() and settings_from_prefix() solution.

I have never made git pull request and do not have any folder on git... I will try to keep it that way for now and let you take it from the patch here, OK? Well that was lazy, I gave it a try and it was so easy! Thank you for giving me the opportunity to try!

Now the last step is to have those backported to released version? Who asks/decides that? What about zeromq/libzmq@eb6c668?

Apologies for the ambiguity. bundle_libzmq_dylib means bring libzmq.$SO into zmq, so that it's part of the install. --zmq=bundled means build libzmq itself as a Python extension (fallback, so that pyzmq is pip-installable).

Well, I did not remember to comment that in setup.py before my pull request so that one I let up to you.

@minrk minrk referenced this issue Feb 3, 2013
Merged

progress towards more sensible build config #312

19 of 19 tasks complete
@minrk minrk closed this in 2c84e63 Feb 3, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment