jbaiter / gphoto2-cffi

Python bindings for libgphoto2 with an idiomatic API
GNU Lesser General Public License v3.0
38 stars 17 forks source link

cross-compile #8

Closed thijstriemstra closed 8 years ago

thijstriemstra commented 8 years ago

I'm trying to compile gphoto2-cffi into a PyQt5 application using pyqtdeploy, to be deployed on a raspberrypi (ARM platform). pyqtdeploy uses something called sip to compile c/c++ code. The steps are basically including all the *.py files from a package and point it to any additional .c files, for example:

screenshot from 2016-07-07 20-32-46

There you can see my approach for the other libraries (psutil and RPi.GPIO). Normally these C-extensions work when they're defined like:

posix_extension = Extension(
        'psutil._psutil_posix',
sources=['psutil/_psutil_posix.c'])

I tried the same for this library, as you can see in the picture, but my build is failing with a long list of errors like this:

_backend.o: In function `_cffi_d_gp_widget_set_value':
_backend.c:(.text+0x87c): undefined reference to `gp_widget_set_value'
_backend.o: In function `_cffi_f_gp_widget_set_value':
....
_backend.c:(.text+0x12664): undefined reference to `gp_abilities_list_detect'
_backend.o: In function `_cffi_d_gp_abilities_list_count':
_backend.c:(.text+0x1286c): undefined reference to `gp_abilities_list_count'
_backend.o: In function `_cffi_f_gp_abilities_list_count':
_backend.c:(.text+0x12910): undefined reference to `gp_abilities_list_count'
_backend.o: In function `_cffi_f_gp_context_new':
_backend.c:(.text+0x129d0): undefined reference to `gp_context_new'
collect2: error: ld returned 1 exit status
Makefile:435: recipe for target 'test' failed
make: *** [test] Error 1

Apparently there's also a cffi emit_c_code method, which I also tried like the patch below, but this results in similar errors:

foo.o: In function `_cffi_d_gp_widget_set_value':
foo.c:(.text+0x87c): undefined reference to `gp_widget_set_value'
foo.o: In function `_cffi_f_gp_widget_set_value':
foo.c:(.text+0x9f4): undefined reference to `gp_widget_set_value'
foo.o: In function `_cffi_d_gp_widget_set_readonly':
foo.c:(.text+0xafc): undefined reference to `gp_widget_set_readonly'
...

Any ideas how I could produce a proper _backend.c file that doesn't throw these errors?

diff --git a/gphoto2cffi/backend_build.py b/gphoto2cffi/backend_build.py
index e78998e..0fbf062 100644
--- a/gphoto2cffi/backend_build.py
+++ b/gphoto2cffi/backend_build.py
@@ -15,6 +15,7 @@ SOURCE = """
 ffi = FFI()
 ffi.set_source("_backend", SOURCE, libraries=['gphoto2'])
 ffi.cdef(CDEF)
+ffi.emit_c_code(os.path.join(os.path.dirname(__file__), "foo.c"))

 if __name__ == "__main__":
     ffi.compile()
jbaiter commented 8 years ago

This looks like a link-time issue, i.e. it cannot find the libgphoto2 functions that the backend references. Do you have any way of passing linker flags to pyqtdeploy/sip? You'll probably have to pass something like -lgphoto2.

thijstriemstra commented 8 years ago

I added that and the error changed, progress! :)

/home/raspi-build/src/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/bin/ld: foo.o: undefined reference to symbol 'gp_port_info_new@@LIBGPHOTO2_INTERNAL'
/home/raspi-build/sysroot/usr/lib/libgphoto2_port.so.12: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Makefile:435: recipe for target 'test' failed
make: *** [test] Error 1
Ready.

The sysroot contains a rsynced version of the /usr/ folder on the raspberry, including the gphoto library.

thijstriemstra commented 8 years ago

Turns out I had to add -lgphoto2 -lgphoto2_port and it compiled, sweet! Thanks for the help. Here's a screenshot with final config, maybe useful to someone else.

screenshot from 2016-07-08 01-47-01