wholden/zwo-efw

Linux EFW support

APinto-DTx opened this issue · 15 comments

First of all, great work!

I am currently trying to apply your package on a raspberry (armv8), however I am having some problems when loading the ".so" libraries provided with cffi.

The error that I'm getting is something similar to:

"OSError: cannot load library ... undefined symbol: udev_enumerate_new. Additionally, ctypes.util.find_library() did not manage to locate a library called ..."

Aha, the promised day has come! When I put that in the readme, I wasn't sure anyone would ever take me up on it. I have a Linux system I can do some testing on. Give me a few days and I can get back to you.

Briefly looking at it, it might be easier in Linux to switch to HID based communications instead of relying on a DLL or anything. I'll let you know.

@APinto-DTx Quick followup, you grabbed the libEFWFilter.so from the "armv8" folder of the EFW_linux_mac_SDK_V1.7, right?

I will be testing with the x64 version, so hopefully once it's working with x64 it will be portable to armv8.

Side comment about Linux support, you will need to install the efw.rules file because of how Linux handles usb permissions.

The command is: $ sudo install efw.rules /lib/udev/rules.d

The efw.rules file is included in the Linux & Mac SDK from Zwo:
https://astronomy-imaging-camera.com/software-drivers

@APinto-DTx Quick followup, you grabbed the libEFWFilter.so from the "armv8" folder of the EFW_linux_mac_SDK_V1.7, right?

I will be testing with the x64 version, so hopefully once it's working with x64 it will be portable to armv8.

Thanks tons for the help!
Yes, I'm using the armv8 library and placed it at the lib folder after installing zwo-efw via pip install. Previously, I've installed the efw-rules as you pointed out.

Gotcha, yea I'm fighting a bit with cffi, it doesn't appear to enjoy loading from absolute paths on Linux. Lovely.

Could you include the entire error message you got when you tried it? I haven't seen the undefined symbol: udev_enumerate_new. and I want to make sure what I'm troubleshooting is similar to what you're seeing.

Ah after a little more digging, I get the same error. Based on this post, it seems like the libEFWFilter.so requires being linked to udev. I'm not sure that ffi.dlopen supports this functionality. Hmm need to keep digging.

the error is:
OSError: cannot load library 'pathstuff..../zwo_efw/lib/libEFWFilter.so.1.7': pathstuff..../zwo_efw/lib/libEFWFilter.so.1.7: undefined symbol: udev_enumerate_new

@APinto-DTx

Some significant progress, check out the "linux" branch and the build_instructions in the lib folder. I couldn't get it to work as straightforwardly as it worked with the Windows dll. For linux, we need to switch to the api-mode of cffi, which requires pre-building a python module that is linked to the ".so" shared library files.

I got the EFWGetNum function, now I just need to add the others and reorganize the other modules to import from the output file generated by cffi.

@APinto-DTx

The latest update to the linux branch is now working on Ubuntu. Because of the linking requirements, this approach requires using cffi to build a python extension. I am not sure how straightforward this will be for working on raspberry pi and armv8, but give it a try and post the results. Fingers crossed!

Hey @wholden thanks for your dedication. It really helped!

I was able to run python efw_build.py with no problems. To help future users, when copying the files to the zwo_efw/lib it might help to not forget to create a soft link to the library.

ln -s libEFWFilter.so.1.7 libEFWFilter

However, after installing I'm getting an error.

ModuleNotFoundError: No module named 'zwo_efw.lib'

I tried to install the package with pip install . and manage to copy the files to the lib folder.

I'm getting now a new error

lib/python3.7/site-packages/zwo_efw/api.py", line 1, in <module>
    from .lib._efw_api import ffi
ImportError: libEFWFilter.so: cannot open shared object file: No such file or directory

Hi @APinto-DTx , seems like we're getting close!

I am not sure about the need to run the linking command you posted. I am not super experienced with linking-related issues, but is that command really needed? In my testing I think I just had the libEFWFilter.so.1.7 file.

If you are doing the linking, I wonder if it needs to be linked to libEFWFilter.so instead of just libEFWFilter. Maybe that is the reason it gave the error.

@APinto-DTx Although it's very weird to me that you got that error when trying to load the library in python, and not during the actual linking step when running python efw_build.py. If there was an issue finding the library, it should have happened at that stage I would think.

When running the python efw_build.py command, with libEFWFilter.so.1.7 the gcc fails to execute. The link was just an alternative, but another one (easier) is to rename to libEFWFilter.so. After that the python command (efw_build.py) works like a charm.

Hi @wholden! Managed to get it working.

Here are the steps that I did. Think not all of them are necessary, specially on the part of installation, but here it goes.

from setuptools import setup, find_packages

setup(
        name='zwo_efw',
        version='1.0',
        author='William Holden',
        description=('Python bindings for controlling the ZWO electronic filter wheel (EFW).'),
        packages=find_packages(),
        include_package_data=True,
        zip_safe=True,
        )

Additionally, I've created a MANIFEST.in file to include the result of python efw_build.py

recursive-include zwo_efw *

To install the commands were the following:

python setup.py sdist
pip install ./dist/zwo_efw-1.0.tar.gz

Now comes the OS part.

  • At the file ``'/etc/ld.so.conf``` add the path to the location of the lib folder of zwo_efw
  • Run ldconfig

That's it!

@APinto-DTx Awesome!! You've surpassed my knowledge of proper naming and folder-organizing of linked-libraries, thanks for posting what worked for you!

If you're interested, wrap your changes in a pull request to the Linux branch and I can merge them in for other users. For now, I'll refer to this post in the readme of the Linux branch so other users can follow in your footsteps.