lvgl-micropython / lvgl_micropython

LVGL module for MicroPython
MIT License
87 stars 29 forks source link

The macOS build tries to link with SDL2-2.0.dynlib #184

Closed mark-hoy closed 1 week ago

mark-hoy commented 1 week ago

The builder/macOS.py file seems to have checks for libSDL2-2.0.0.dylib, but during the build the linker wants SDL2-2.0

I have to admit, I don't really understand what the checks in macOS.py are doing

$ python3 make.py macOS DISPLAY=sdl_display INDEV=sdl_pointer
...
_timer.o build-standard/machine_sdl.o build-standard/shared/runtime/gchelper_generic.o build-standard/shared/timeutils/timeutils.o build-standard/shared/readline\
/readline.o   -Lbuild-standard/SDL -lSDL2-2.0    -Wl,-map,build-standard/micropython.map -Wl,-dead_strip -lm  -lpthread -lffi
ld: library 'SDL2-2.0' not found
clang: error: linker command failed with exit code 1 (use -v to see invocation)

A simple work around is to copy libSDL2-2.0.0.dylib which I installed via "brew" into /usr/local/lib/libSDL2-2.0.dylib

kdschlosser commented 1 week ago

SDL2 should be compiled at the same time the firmware is compiled. The reason why I am not using the precompiled binaries that are in the package managers is because a lot of the time they are not up to date with the latest released version of a library. So to avoid any issues it gets compiled when the firmware does.

Now ideally I wanted to do like what is done with the unix port which is compiling SDL2 into the firmware. This results in a complete package that is a single binary and SDL is not an external dependency. I was not able to get clang to use a static library it doesn't want to link to it. It only wants to link to a dynamic library. The other issue with clang is even if I did manage to get it to link to the static library if a user had SDL2 installed in their system as a dynamic library clang would place a priority of linking to the dynamic library instead of the static one. It's rather annoying actually.

Maybe you can shed some light on how to force clang to link to a static library. If we can do this then there would be no issue.

If you look in the build folder where the micropython binary is, the SDL2 dynamic library should be in there. If it is not do me a favor and check lib/micropython/ports/unix/build-standard/SDL and see if the dynamic library is in there.

It should be copying the library to the same folder as the binary. I am going to look at the build script to see if something is amiss with the linking.

kdschlosser commented 1 week ago

the build should be fixed now. I made some changes and hopefully everything should be good to go. The CI completes the build without any errors.

mark-hoy commented 1 week ago

Congrats, you have a working macOS build now. The build directory has the executable and the dynamic library.

I don't know much about clang and it's dynamic/static loader requirements though.

$ python3 make.py macOS DISPLAY=sdl_display INDEV=sdl_pointer
...

ld-standard/shared/timeutils/timeutils.o build-standard/shared/readline/readline.o   -Lbuild-standard/SDL -lSDL2-2.0    -
Wl,-map,build-standard/micropython.map -\
Wl,-dead_strip -lm  -lpthread -lffi
strip  build-standard/micropython
size $(find build-standard -path "build-standard/build/frozen*.o") build-standard/micropython
__TEXT  __DATA  __OBJC  others  dec     hex
1245184 16384   0       4295294976      4296556544      100184000
compiled binary is /Users/mark_hoy/git/lvgl_micropython/build
You need to make the binary executable by running
"sudo chmod +x lvgl_micropy_macOS"
bash-5.2$ ls build
libSDL2-2.0.0.dylib     lvgl_micropy_macOS

I then invoked it with the following

DYLD_LIBRARY_PATH=. ./lvgl_micropy_macOS 

A test with Mitch's code has me loading up a SDL image on my mac Mini. :-)

mark-hoy commented 1 week ago

I found an article on OSX static/dynamic linking and how someone solved it.

OSX static/dynamic linking

I think it suggests using -L with a pointer to the static library directory. (I am tired though and was skimming the info).

kdschlosser commented 1 week ago

I did do that and it doesn't work. LOL the dynamic library if one is installed is chosen over the static library 100% of the time.

I am happy to see it is now compiling correctly. I had to make a change when compiling SDL2 for it to work. It was compiling the static library and not the dynamic one.

I did however tell clang to check the folder that the binary is located in for the dynamic library before checking anywhere else. So long as the SDL dynamic library file is in the same folder as the binary it does what it is supposed to do. If you delete that file or move it to a different folder then you should not be able to run micropython.

You can test that if you want.

kdschlosser commented 1 week ago

In that page you linked to it states the problem in it.

-l is used to tell the linker the name of the libraries to look into for symbols. If you decide to compile a program that uses functions from libpng, you would add -lpng to the arguments passed to clang.

-L is used to tell the linker where to look for the library files. ld maintains a list of directories to search for a library to use. The default library search path is /usr/lib then /usr/local/lib. The -L option will add a new library search path.

At this point is it important to point out that, if the linker finds both a .a (static) and .dylib (dynamic) file in the search paths, it will ALWAYS choose the dynamic library.

The last one is the problem. it searches the paths for a dynamic library and if found that is what is used. if no dynamic library is found then it searches the paths for a static library. the first library it finds is the one it uses. Adding a search path using the -L parameter appends a path to the search list. so it is always going to be the last path searched...

kdschlosser commented 1 week ago

OK I change the macos port so it will use the installed SDL2 dynamic library instead of compiling it. SDL2 in homebrew is a sufficient version to may as well use that instead of compiling it.

The CI does compile properly so it should also work locally. make sure to use brew install SDL2 to install SDL2 prior to compiling.

mark-hoy commented 1 week ago

I downloaded the latest, recompiled and launched it. It picks up my libSDL2-2.0.0.dylib

➜  lvgl_micropython git:(main) ✗ locate libSDL2-2.0.0.dylib
/usr/local/Cellar/sdl2/2.30.9/lib/libSDL2-2.0.0.dylib
/usr/local/lib/libSDL2-2.0.0.dylib
➜  lvgl_micropython git:(main) ✗ ls -lt /usr/local/lib/libSDL2-2.0.0.dylib 
lrwxr-xr-x  1 mark  admin  45 Nov  5 14:18 /usr/local/lib/libSDL2-2.0.0.dylib -> ../Cellar/sdl2/2.30.9/lib/libSDL2-2.0.0.dylib

There is a warning from the build on a homebrew directory but that could be something from my environment as I don't see that particular path in any of the lvgl build code.

CC ../../shared/readline/readline.c
CC build-standard/frozen_content.c
LINK build-standard/micropython
ld: warning: search path '/opt/homebrew/lib' not found
__TEXT  __DATA  __OBJC  others  dec hex
1245184 12288   0   4295274496  4296531968  10017e000
compiled binary is /Users/mark/git/lvgl_micropython/build
You need to make the binary executable by running
"sudo chmod +x lvgl_micropy_macOS"
kdschlosser commented 1 week ago

It looks like it does compile properly...

have you tested the binary to see i it works? have you gotten a display with some LVGL graphics and does it interact with mouse clicks properly?

mark-hoy commented 1 week ago

It all works. Gui loads, mouse clocks work. I will close this.

kdschlosser commented 1 week ago

SWEET!!!

kdschlosser commented 1 week ago

One thing.. What kind of processor does your Mac have? Is it an Intel processor?

mark-hoy commented 1 week ago

I have now built and tested on my m1 Mac mini and my m2 MacBook Air. Each are running Sequoia

kdschlosser commented 1 week ago

OK so both are Apple silicon. we don't know if it will compile properly if the Mac has Intel silicon.