stinos / micropython-wrap

API for interop between C/C++ and MicroPython
MIT License
124 stars 23 forks source link

Trouble getting it to work #2

Closed harryofskyrim closed 5 years ago

harryofskyrim commented 5 years ago

Following the instructions to integrate and build with Micropython custom fork, I used the sample code from micropython-wrap's readme to try and add the module and sample Makefile lines from the fork's readme to assemble the shared library. I also changed the name of the registration function to initxxx() and init_xxx() in my attempts to get it to work. .so file is in the ~/.micropython/lib directory, micropython unix port is built, but the module is not accessible. There's definitely something I'm missing. Probably an exhaustive Hello World tutorial would help.

stinos commented 5 years ago

You're right that it should be init_<module_name> not just initxxx, I'll clarify that in the README.

I suggest to have a look at how the test module is built: the Makefile shows how to build static and shared libraries, and module.cpp shows the init function used.

edit also see comment here for a step by step example

harryofskyrim commented 5 years ago

Well, I mean, I used init_, I just referred to the way it's written in that readme. The step-by-step example shows something I am doing already, and that's a relief at least

I heavily rely on the Makefile and the sample module.cpp already, but I there is this one problem (I get it even when building the original module.cpp with the original Makefile out of the box).

To build the shared library the original Makefile generates the micropython headers first with some flags set to 0: UPYFLAGS = MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 MICROPY_PY_AXTLS=0 MICROPY_FATFS=0 MICROPY_PY_THREAD=0

In my case, building the micropython itself then fails because related modules are not found: In file included from ../../py/objmodule.h:29, from ../../py/objmodule.c:30: ../../py/objmodule.c:166:19: error: ‘MP_QSTR__thread’ undeclared here (not in a function); did you mean ‘MP_QSTR_read’? { MP_ROM_QSTR(MP_QSTR__thread), MP_ROM_PTR(&mp_module_thread) },, etc.

If I omit the header building or change the flags to 1, micropython is built successfully, but the module is not registered within micropython.

stinos commented 5 years ago

I assume if you first build MicroPython with some flags 0, then change them and build MicroPython again, it doesn't detect all of these changes and/or doesn't generate qstr again, hence the errors. Doing a rebuild would fix that. But if I recall correctly the reason those flags are 0 is that I couldn't figure out how to build MicroPython with them and with -rdynamic, which I think is required to make the importing work. It's been a long time I tested this so some flags might now actually work though.

(I get it even when building the original module.cpp with the original Makefile out of the box).

Can you enable debug logging in loaddynlib.c (change line 6 to #if 1) and see what the output is? If that outputs anything, it means your .so file was found on disk but could not be opened or the init function wasn't found. If there's no output from that file, the .so file wasn't found.

Otherwise if you write down the exact steps you are following, the code you are using etc, I can try to reproduce and debug this myself (in the latest windows-pyd branch of my MicroPython fork combined with latest micropython-wrap, make testsharedlib works and runs all tests)

harryofskyrim commented 5 years ago

Given that for the latest versions it worked fine for you, I just deleted the micropython-wrap and the windows-pyd fork locally and cloned them again, and everything worked fine for me too. Don't know what went wrong yesterday, most probably I messed something up. Thanks for the help anyway

Unrelated: the Makefile clean target in micropython-wrap attempts to delete the non-existent $(MICROPYTHON_DIR)/ports/unix/micropython directory or file, shouldn't it be $(MICROPYTHON_DIR)/ports/unix/build directory?

stinos commented 5 years ago

Ok good to hear. I have rewritten the README for my MicroPython fork and added basic examples, and while doing that found a possible cause why it didn't work for you: importing a .so from the current directory doesn't work becuase the dynamic loader doesn't look in the current directory, which can be solved by invoking micropython like LD_LIBRARY_PATH=$(pwd) micropython; or by putting the .so elsewhere in the MicroPython search path because then full paths are used.

stinos commented 5 years ago

Unrelated: the Makefile clean target in micropython-wrap attempts to delete the non-existent $(MICROPYTHON_DIR)/ports/unix/micropython directory or file, shouldn't it be $(MICROPYTHON_DIR)/ports/unix/build directory?

It was really intended to delete the micropython executable created. This has been changed now to just call make clean on the unix port though so there are no artefacts.