circle icon indicating copy to clipboard operation
circle copied to clipboard

Compiling lvgl to bootable kernel (on macOS)

Open naturalmechanics opened this issue 8 months ago • 34 comments

I need to compile Circle with LVGL in a bootable mode for rpi.

Everything is good, I can compile, the samples. They produce kernel.d and kernel7l.img (i can use the later to boot an RPi cm4)

But, I need to run LVGL, i followed the instructions in addon/lvgl/sample/readme.

Ialso looked at this: https://github.com/rsta2/circle/issues/552

However, the compilation does not produce any error - but only produces a kernel.d, and a main.d

I need to produce kernel7l.img. How can I do that? Thank you.

naturalmechanics avatar Apr 20 '25 14:04 naturalmechanics

On which OS do you try to build the LVGL sample? Have you updated the LVGL submodule using:

git submodule update --init addon/lvgl/lvgl/

rsta2 avatar Apr 20 '25 17:04 rsta2

Hi

  1. The host OS is Mac OS 11
  2. yes, I have done that git submodule update --init addon/lvgl/lvgl/ - but this did not produce any output at all (neither success, nor error)

naturalmechanics avatar Apr 20 '25 20:04 naturalmechanics

Unfortunately I do not have a Mac and that's why building on it is not fully supported. I cannot test it. We can try to get the LVGL build working anyway.

Have you tried the version with the Makefile on the develop branch as noted in issue #552? There was recently a problem with building on Windows and this version fixes it. Perhaps this also helps on MacOS? If not, I will send you a special Makefile with a workaround.

rsta2 avatar Apr 21 '25 09:04 rsta2

Yes.

I dont need the DEFINE += -DARM_ALLOW_MULTI_CORE - I am just trying to build the LVGL sample

I also tried with LVGL downloaded from their github

But i was unsuccessful. My goal is to have a bootable kernel where i can run LVGL on baremetal

naturalmechanics avatar Apr 21 '25 09:04 naturalmechanics

OK. Please replace addon/lvgl/Makefile with the file in the attached .zip archive and rebuild addon/lvgl/ and, if this works, addon/lvgl/sample/. I guess, there is a problem with the $(shell) operator in MacOS's make tool. So I copied its output directly into the Makefile.

Makefile.zip

rsta2 avatar Apr 21 '25 10:04 rsta2

I just tested it. there is still no *img file in the sample folder.

My workflow was:

  1. git clone --recursive https://github.com/rsta2/circle.git (get everything, incl lvgl)
  2. cd circle
  3. git submodule update --init addon/lvgl/lvgl/ (no effect)
  4. ./makeall
  5. cd addon/lvgl
  6. replace makefile
  7. make -> onl yproduces lvgl.d
  8. cd sample
  9. make
  10. only produce kernel.d and main.d

naturalmechanics avatar Apr 21 '25 15:04 naturalmechanics

I teseted with some debugs

OBJS = lvgl.o $(CSRCS:.c=.o)

debug_targ_0:
        @echo "Objects ready"

EXTRACLEAN += $(CSRCS:.c=.o) $(CSRCS:.c=.d)

debug_targ_1:
        @echo "did extraclean work?"
        
liblvgl.a: $(OBJS)
        @echo "  AR    $@"
        @rm -f $@
        @$(AR) cr $@ $(OBJS)
        
debug_targ_2:
        @echo "liblvgl ok"
        @echo  $(CIRCLEHOME)/Rules.mk

Only the first debug message is being printed, EXTRACLEAN doesn't fire

naturalmechanics avatar Apr 21 '25 15:04 naturalmechanics

and if I do:

liblvgl.a:
               $(OBJS) # note: new line
               # turn off the echo
# continue the rest

I get: make: lvgl.o: No such file or directory

naturalmechanics avatar Apr 21 '25 15:04 naturalmechanics

Thanks for testing! Attached there is another .zip archive, with a Makefile to be replaced in addon/lvgl/. Please clean everything with make clean before trying to build.

Makefile.zip

rsta2 avatar Apr 21 '25 17:04 rsta2

Hi thank you for the other makefile Immediate collision:

  CPP   lvgl.o
In file included from ../../addon/lvgl/lvgl/src/lv_conf_internal.h:60,
                 from ../../addon/lvgl/lvgl/src/lv_init.h:16,
                 from ../../addon/lvgl/lvgl/lvgl.h:21,
                 from ../../addon/lvgl/lvgl.h:25,
                 from lvgl.cpp:20:
../../addon/lvgl/lvgl/src/../../lv_conf.h:62:33: fatal error: inttypes.h: No such file or directory
   62 | #define LV_INTTYPES_INCLUDE     <inttypes.h>
      |                   

However, I have it here:

/System/Volumes/Data/Users/username_here/circle-dev/circle-3/circle/addon/lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/inttypes.h

If i directly edit the lv_config.h with the full file path, then I get additional errors

/System/Volumes/Data/Users/username_here/circle-dev/circle-3/circle/addon/lvgl/lvgl/src/libs/thorvg/rapidjson/msinttypes/stdint.h:98:12: fatal error: wchar.h: No such file or directory
   98 | #  include <wchar.h>

Correcting that, continues with other errors (another file not found ..)

naturalmechanics avatar Apr 21 '25 17:04 naturalmechanics

The Makefile workaround seems to work. Now we have a toolchain problem. The file inttypes.h must be provided by the toolchain. The file, which you have found in LVGL is for an external library, which is not used in Circle.

Which toolchain are you using? The recommended toolchain for Circle can be downloaded here. Please skip the version on top, go down to version 13.2.Rel1 and download the bare-metal target version (arm-none-eabi), which fits for your Mac (x86_64 or Apple silicon). Please try to build Circle and the LVGL library with this toolchain.

rsta2 avatar Apr 22 '25 09:04 rsta2

still same problem. i have reinstalled the thing : https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-darwin-arm64-arm-none-eabi.pkg

naturalmechanics avatar Apr 22 '25 16:04 naturalmechanics

I have changed your makefile like this:

CIRCLEHOME = ../..

LVGL_PATH = ./lvgl

INCLUDE += -I/Library/Developer/CommandLineTools/usr/lib/clang/16/include
# that is the correct location, I have checked with find command

OBJS =	lvgl.o \
	lvgl/src/draw/lv_draw_mask.o \

Now I have:

/Library/Developer/CommandLineTools/usr/lib/clang/16/include/__stddef_ptrdiff_t.h:15:50: error: missing binary operator before token "("
   15 |     (__has_feature(modules) && !__building_module(_Builtin_stddef))
      |                                                  ^
In file included from /Library/Developer/CommandLineTools/usr/lib/clang/16/include/stddef.h:87:
/Library/Developer/CommandLineTools/usr/lib/clang/16/include/__stddef_size_t.h:15:50: error: missing binary operator before token "("
   15 |     (__has_feature(modules) && !__building_module(_Builtin_stddef))
      |                                                  ^
In file included from /Library/Developer/CommandLineTools/usr/lib/clang/16/include/stddef.h:102:
/Library/Developer/CommandLineTools/usr/lib/clang/16/include/__stddef_null.h:10:41: error: missing binary operator before token "("
   10 | #if !defined(NULL) || !__building_module(_Builtin_stddef)
      |                                         ^
In file included from /Library/Developer/CommandLineTools/usr/lib/clang/16/include/stddef.h:107:
/Library/Developer/CommandLineTools/usr/lib/clang/16/include/__stddef_nullptr_t.h:15:50: error: missing binary operator before token "("
   15 |     (__has_feature(modules) && !__building_module(_Builtin_stddef))
      |                                                  ^
In file included from /Library/Developer/CommandLineTools/usr/lib/clang/16/include/stddef.h:122:
/Library/Developer/CommandLineTools/usr/lib/clang/16/include/__stddef_offsetof.h:15:50: error: missing binary operator before token "("
   15 |     (__has_feature(modules) && !__building_module(_Builtin_stddef))
      |                                                  ^
In file included from ../../addon/lvgl/lvgl/src/misc/lv_types.h:22:
/Library/Developer/CommandLineTools/usr/lib/clang/16/include/inttypes.h:21:15: fatal error: inttypes.h: No such file or directory
   21 | #include_next <inttypes.h>
      |               ^~~~~~~~~~~~
compilation terminated.

naturalmechanics avatar Apr 22 '25 16:04 naturalmechanics

and if i do this:

CXX = arm-none-eabi-g++ # Add this for C++ compiler
CFLAGS = -Wall -O2 "-D__building_module(_Builtin_stddef)=0"


#INCLUDE += -I/Library/Developer/CommandLineTools/usr/lib/clang/16/include
INCLUDE += -I/Library/Developer/CommandLineTools/usr/lib/clang/16/include -I../../include -I$(LVGL_PATH)

I get:

inttypes.h: No such file or directory
   21 | #include_next <inttypes.h>
      |               ^~~~~~~~~~~~

Now, I can locate inttypes.h, but the error is in the include_next

naturalmechanics avatar Apr 22 '25 16:04 naturalmechanics

Finally I have changed the includefile path

This is my makefile now:

CXX = arm-none-eabi-g++ # Add this for C++ compiler
INCLUDE += -I/Applications/ArmGNUToolchain/13.2.Rel1/arm-none-eabi/arm-none-eabi/include/ -I../../include -I$(LVGL_PATH)
# the correct toolchain

Now i have:

../../include/circle/types.h:62:15: error: expected constructor, destructor, or type conversion before '(' token
   62 | ASSERT_STATIC (sizeof (boolean) == 1);
      |               ^
In file included from ../../include/circle/memory.h:29,
                 from ../../include/circle/new.h:23,
                 from lvgl.cpp:27:
../../include/circle/heapallocator.h:32:15: error: expected constructor, destructor, or type conversion before '(' token
   32 | ASSERT_STATIC (DATA_CACHE_LINE_LENGTH_MAX >= 16);

naturalmechanics avatar Apr 22 '25 16:04 naturalmechanics

finally , commenting out the assertions in both the headers, i can successfully compile to liblvgl.a

BUT. running make command in the sample folder with this makefile


# define only one
SPI_DISPLAY = DISPLAY_TYPE_ST7789
#SPI_DISPLAY = DISPLAY_TYPE_ILI9341
#I2C_DISPLAY = DISPLAY_TYPE_SSD1306

CIRCLEHOME = ../../..

OBJS	= main.o kernel.o

LIBS	= $(CIRCLEHOME)/addon/lvgl/liblvgl.a \
	  $(CIRCLEHOME)/lib/usb/libusb.a \
	  $(CIRCLEHOME)/lib/input/libinput.a \
	  $(CIRCLEHOME)/lib/fs/libfs.a \
	  $(CIRCLEHOME)/lib/libcircle.a

## all the *.a files exist, i checked...

ifneq ($(strip $(SPI_DISPLAY)),)
LIBS	+= $(CIRCLEHOME)/addon/display/libdisplay.a

CFLAGS	+= -DSPI_DISPLAY=$(SPI_DISPLAY)
else ifneq ($(strip $(I2C_DISPLAY)),)
LIBS	+= $(CIRCLEHOME)/addon/display/libdisplay.a

# this libdisplay.a file however is **NOT** created.
# i can go in and manually create it by running make in addon/display

CFLAGS	+= -DI2C_DISPLAY=$(I2C_DISPLAY)
endif

include $(CIRCLEHOME)/Rules.mk

-include $(DEPS)

Still does not produce any bootable image.

Edit: even if i go in the display folder, and run make there, and create the libdisplay.a file, and then try to compile lvgl samples, it still does not generate a bootable kernel

However, display samples in addon/display can be compiled to a kernel7l.img

naturalmechanics avatar Apr 22 '25 16:04 naturalmechanics

My final goal is to run an hdmi output with circle and lvgl

naturalmechanics avatar Apr 22 '25 18:04 naturalmechanics

Are you sure, that you are using the installed GNU C toolchain, which you have downloaded from the linked website? I think, you are using clang, which is different and the clang support in Circle is only experimental. I don't think, you can build LVGL with it in Circle (as you see). The PREFIX= variable in Config.mk must contain the full path to the toolchain's bin/ directory (exception: the toolchain bin/ directory is in the PATH) and the toolchain prefix, e.g.:

PREFIX=/home/me/tools/gcc/13.2.rel1/bin/arm-none-eabi-

Also clang must not be enabled in Config.mk to build the LVGL library.

It's the expected behavior, that the addon/display/ library has to be built manually as everything under addon/.

rsta2 avatar Apr 22 '25 21:04 rsta2

Hi,

Thought i could pitch in since i'm also building on macos (14 Sonoma) using the official 64bit toolchain and my own Circle projects all build perfectly fine so i have a working setup.

I think i followed all steps in the README.ms, but i seem to be getting another error, but i am also on the development branch currently, and not the latest. I don't want to update at this time because i'm testing some stuff. Don't know if it could help, but here is the error i get when trying to make the sample:

from main.cpp:20:
../../../addon/lvgl/lvgl.h:47:35: error: 'lv_display_t' has not been declared
47 |         static void DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer);

If i get the chance later on when updating to the latest circle version, i'll try again!

nickverlinden avatar Apr 24 '25 11:04 nickverlinden

@nickverlinden Please find the following line in addon/lvgl/lv_conf.h and change the value from 0 to 1:

#define LV_USE_PRIVATE_API 0

Then build again. Thanks.

rsta2 avatar Apr 24 '25 11:04 rsta2

I realized i did something wrong, and a sa result did not build /addon/lvgl first, trying that (without legacy api option) results in a lot of errors:

nick@macbook-air lvgl % make      
  CPP   lvgl.o
In file included from lvgl.cpp:20:
../../addon/lvgl/lvgl.h:47:35: error: 'lv_display_t' has not been declared
   47 |         static void DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer);
      |                                   ^~~~~~~~~~~~
lvgl.cpp: In member function 'boolean CLVGL::Initialize()':
lvgl.cpp:102:34: error: invalid conversion from 'void (*)(lv_log_level_t, const char*)' {aka 'void (*)(signed char, const char*)'} to 'lv_log_print_g_cb_t' {aka 'void (*)(const char*)'} [-fpermissive]
  102 |         lv_log_register_print_cb (LogPrint);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
      |                                  |
      |                                  void (*)(lv_log_level_t, const char*) {aka void (*)(signed char, const char*)}
In file included from ../../addon/lvgl/lvgl/lvgl.h:25,
                 from ../../addon/lvgl/lvgl.h:25:
../../addon/lvgl/lvgl/src/misc/lv_log.h:64:51: note:   initializing argument 1 of 'void lv_log_register_print_cb(lv_log_print_g_cb_t)'
   64 | void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb);
      |                               ~~~~~~~~~~~~~~~~~~~~^~~~~~~~
lvgl.cpp:114:16: error: 'lv_display_t' does not name a type; did you mean 'lv_disp_t'?
  114 |         static lv_display_t *display = lv_display_create (nWidth, nHeight);
      |                ^~~~~~~~~~~~
      |                lv_disp_t
lvgl.cpp:118:46: error: 'display' was not declared in this scope; did you mean 'CDisplay'?
  118 |                 lv_display_set_color_format (display, LV_COLOR_FORMAT_I1);
      |                                              ^~~~~~~
      |                                              CDisplay
lvgl.cpp:118:55: error: 'LV_COLOR_FORMAT_I1' was not declared in this scope; did you mean 'LV_COLOR_SET_A1'?
  118 |                 lv_display_set_color_format (display, LV_COLOR_FORMAT_I1);
      |                                                       ^~~~~~~~~~~~~~~~~~
      |                                                       LV_COLOR_SET_A1
lvgl.cpp:118:17: error: 'lv_display_set_color_format' was not declared in this scope
  118 |                 lv_display_set_color_format (display, LV_COLOR_FORMAT_I1);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:125:34: error: 'display' was not declared in this scope; did you mean 'CDisplay'?
  125 |         lv_display_set_flush_cb (display, DisplayFlush);
      |                                  ^~~~~~~
      |                                  CDisplay
lvgl.cpp:125:9: error: 'lv_display_set_flush_cb' was not declared in this scope
  125 |         lv_display_set_flush_cb (display, DisplayFlush);
      |         ^~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:127:33: error: 'LV_DISP_RENDER_MODE_PARTIAL' was not declared in this scope
  127 |                                 LV_DISP_RENDER_MODE_PARTIAL);
      |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:126:9: error: 'lv_display_set_buffers' was not declared in this scope; did you mean 'lv_canvas_set_buffer'?
  126 |         lv_display_set_buffers (display, m_pBuffer1, m_pBuffer2, nBufSizePixels * sizeof (u16),
      |         ^~~~~~~~~~~~~~~~~~~~~~
      |         lv_canvas_set_buffer
lvgl.cpp:166:36: error: 'lv_indev_create' was not declared in this scope; did you mean 'lv_line_create'?
  166 |         static lv_indev_t *indev = lv_indev_create ();
      |                                    ^~~~~~~~~~~~~~~
      |                                    lv_line_create
lvgl.cpp:167:9: error: 'lv_indev_set_type' was not declared in this scope; did you mean 'lv_indev_get_type'?
  167 |         lv_indev_set_type (indev, LV_INDEV_TYPE_POINTER);
      |         ^~~~~~~~~~~~~~~~~
      |         lv_indev_get_type
lvgl.cpp:168:9: error: 'lv_indev_set_read_cb' was not declared in this scope; did you mean 'lv_anim_set_ready_cb'?
  168 |         lv_indev_set_read_cb (indev, PointerRead);
      |         ^~~~~~~~~~~~~~~~~~~~
      |         lv_anim_set_ready_cb
lvgl.cpp: At global scope:
lvgl.cpp:234:6: error: variable or field 'DisplayFlush' declared void
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |      ^~~~~
lvgl.cpp:234:27: error: 'lv_display_t' was not declared in this scope; did you mean 'lv_disp_t'?
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                           ^~~~~~~~~~~~
      |                           lv_disp_t
lvgl.cpp:234:41: error: 'pDisplay' was not declared in this scope; did you mean 'CDisplay'?
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                         ^~~~~~~~
      |                                         CDisplay
lvgl.cpp:234:51: error: expected primary-expression before 'const'
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                                   ^~~~~
lvgl.cpp:234:78: error: expected primary-expression before '*' token
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                                                              ^
lvgl.cpp:234:79: error: 'pBuffer' was not declared in this scope
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                                                               ^~~~~~~
lvgl.cpp: In static member function 'static void CLVGL::DisplayFlushComplete(void*)':
lvgl.cpp:261:9: error: 'lv_display_t' was not declared in this scope; did you mean 'lv_disp_t'?
  261 |         lv_display_t *pDisplay = (lv_display_t *) pParam;
      |         ^~~~~~~~~~~~
      |         lv_disp_t
lvgl.cpp:261:23: error: 'pDisplay' was not declared in this scope; did you mean 'CDisplay'?
  261 |         lv_display_t *pDisplay = (lv_display_t *) pParam;
      |                       ^~~~~~~~
      |                       CDisplay
lvgl.cpp:261:49: error: expected primary-expression before ')' token
  261 |         lv_display_t *pDisplay = (lv_display_t *) pParam;
      |                                                 ^
lvgl.cpp:264:9: error: 'lv_display_flush_ready' was not declared in this scope; did you mean 'lv_disp_flush_ready'?
  264 |         lv_display_flush_ready (pDisplay);
      |         ^~~~~~~~~~~~~~~~~~~~~~
      |         lv_disp_flush_ready
lvgl.cpp: In member function 'void CLVGL::SetupCursor(lv_indev_t*)':
lvgl.cpp:417:37: error: 'lv_image_dsc_t' does not name a type; did you mean 'lv_img_dsc_t'?
  417 |                 m_pCursorDesc = new lv_image_dsc_t;
      |                                     ^~~~~~~~~~~~~~
      |                                     lv_img_dsc_t
lvgl.cpp:421:39: error: 'struct lv_img_header_t' has no member named 'magic'
  421 |                 m_pCursorDesc->header.magic = LV_IMAGE_HEADER_MAGIC;
      |                                       ^~~~~
lvgl.cpp:421:47: error: 'LV_IMAGE_HEADER_MAGIC' was not declared in this scope
  421 |                 m_pCursorDesc->header.magic = LV_IMAGE_HEADER_MAGIC;
      |                                               ^~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:424:44: error: 'LV_COLOR_FORMAT_ARGB8888' was not declared in this scope
  424 |                 m_pCursorDesc->header.cf = LV_COLOR_FORMAT_ARGB8888;
      |                                            ^~~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:425:39: error: 'struct lv_img_header_t' has no member named 'stride'
  425 |                 m_pCursorDesc->header.stride = CURSOR_WIDTH * 4;
      |                                       ^~~~~~
lvgl.cpp:429:59: error: 'lv_screen_active' was not declared in this scope; did you mean 'lv_scr_act'?
  429 |                 lv_obj_t *pCursorImage = lv_image_create (lv_screen_active ());
      |                                                           ^~~~~~~~~~~~~~~~
      |                                                           lv_scr_act
lvgl.cpp:429:42: error: 'lv_image_create' was not declared in this scope; did you mean 'lv_img_create'?
  429 |                 lv_obj_t *pCursorImage = lv_image_create (lv_screen_active ());
      |                                          ^~~~~~~~~~~~~~~
      |                                          lv_img_create
lvgl.cpp:431:17: error: 'lv_image_set_src' was not declared in this scope; did you mean 'lv_img_set_src'?
  431 |                 lv_image_set_src (pCursorImage, m_pCursorDesc);
      |                 ^~~~~~~~~~~~~~~~
      |                 lv_img_set_src
make: *** [../../Rules.mk:210: lvgl.o] Error 1

And with legacy api option:

nick@macbook-air lvgl % make
  CPP   lvgl.o
In file included from lvgl.cpp:20:
../../addon/lvgl/lvgl.h:47:35: error: 'lv_display_t' has not been declared
   47 |         static void DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer);
      |                                   ^~~~~~~~~~~~
lvgl.cpp: In member function 'boolean CLVGL::Initialize()':
lvgl.cpp:102:34: error: invalid conversion from 'void (*)(lv_log_level_t, const char*)' {aka 'void (*)(signed char, const char*)'} to 'lv_log_print_g_cb_t' {aka 'void (*)(const char*)'} [-fpermissive]
  102 |         lv_log_register_print_cb (LogPrint);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
      |                                  |
      |                                  void (*)(lv_log_level_t, const char*) {aka void (*)(signed char, const char*)}
In file included from ../../addon/lvgl/lvgl/lvgl.h:25,
                 from ../../addon/lvgl/lvgl.h:25:
../../addon/lvgl/lvgl/src/misc/lv_log.h:64:51: note:   initializing argument 1 of 'void lv_log_register_print_cb(lv_log_print_g_cb_t)'
   64 | void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb);
      |                               ~~~~~~~~~~~~~~~~~~~~^~~~~~~~
lvgl.cpp:114:16: error: 'lv_display_t' does not name a type; did you mean 'lv_disp_t'?
  114 |         static lv_display_t *display = lv_display_create (nWidth, nHeight);
      |                ^~~~~~~~~~~~
      |                lv_disp_t
lvgl.cpp:118:46: error: 'display' was not declared in this scope; did you mean 'CDisplay'?
  118 |                 lv_display_set_color_format (display, LV_COLOR_FORMAT_I1);
      |                                              ^~~~~~~
      |                                              CDisplay
lvgl.cpp:118:55: error: 'LV_COLOR_FORMAT_I1' was not declared in this scope; did you mean 'LV_COLOR_SET_A1'?
  118 |                 lv_display_set_color_format (display, LV_COLOR_FORMAT_I1);
      |                                                       ^~~~~~~~~~~~~~~~~~
      |                                                       LV_COLOR_SET_A1
lvgl.cpp:118:17: error: 'lv_display_set_color_format' was not declared in this scope
  118 |                 lv_display_set_color_format (display, LV_COLOR_FORMAT_I1);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:125:34: error: 'display' was not declared in this scope; did you mean 'CDisplay'?
  125 |         lv_display_set_flush_cb (display, DisplayFlush);
      |                                  ^~~~~~~
      |                                  CDisplay
lvgl.cpp:125:9: error: 'lv_display_set_flush_cb' was not declared in this scope
  125 |         lv_display_set_flush_cb (display, DisplayFlush);
      |         ^~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:127:33: error: 'LV_DISP_RENDER_MODE_PARTIAL' was not declared in this scope
  127 |                                 LV_DISP_RENDER_MODE_PARTIAL);
      |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:126:9: error: 'lv_display_set_buffers' was not declared in this scope; did you mean 'lv_canvas_set_buffer'?
  126 |         lv_display_set_buffers (display, m_pBuffer1, m_pBuffer2, nBufSizePixels * sizeof (u16),
      |         ^~~~~~~~~~~~~~~~~~~~~~
      |         lv_canvas_set_buffer
lvgl.cpp:166:36: error: 'lv_indev_create' was not declared in this scope; did you mean 'lv_line_create'?
  166 |         static lv_indev_t *indev = lv_indev_create ();
      |                                    ^~~~~~~~~~~~~~~
      |                                    lv_line_create
lvgl.cpp:167:9: error: 'lv_indev_set_type' was not declared in this scope; did you mean 'lv_indev_get_type'?
  167 |         lv_indev_set_type (indev, LV_INDEV_TYPE_POINTER);
      |         ^~~~~~~~~~~~~~~~~
      |         lv_indev_get_type
lvgl.cpp:168:9: error: 'lv_indev_set_read_cb' was not declared in this scope; did you mean 'lv_anim_set_ready_cb'?
  168 |         lv_indev_set_read_cb (indev, PointerRead);
      |         ^~~~~~~~~~~~~~~~~~~~
      |         lv_anim_set_ready_cb
lvgl.cpp: At global scope:
lvgl.cpp:234:6: error: variable or field 'DisplayFlush' declared void
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |      ^~~~~
lvgl.cpp:234:27: error: 'lv_display_t' was not declared in this scope; did you mean 'lv_disp_t'?
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                           ^~~~~~~~~~~~
      |                           lv_disp_t
lvgl.cpp:234:41: error: 'pDisplay' was not declared in this scope; did you mean 'CDisplay'?
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                         ^~~~~~~~
      |                                         CDisplay
lvgl.cpp:234:51: error: expected primary-expression before 'const'
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                                   ^~~~~
lvgl.cpp:234:78: error: expected primary-expression before '*' token
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                                                              ^
lvgl.cpp:234:79: error: 'pBuffer' was not declared in this scope
  234 | void CLVGL::DisplayFlush (lv_display_t *pDisplay, const lv_area_t *pArea, u8 *pBuffer)
      |                                                                               ^~~~~~~
lvgl.cpp: In static member function 'static void CLVGL::DisplayFlushComplete(void*)':
lvgl.cpp:261:9: error: 'lv_display_t' was not declared in this scope; did you mean 'lv_disp_t'?
  261 |         lv_display_t *pDisplay = (lv_display_t *) pParam;
      |         ^~~~~~~~~~~~
      |         lv_disp_t
lvgl.cpp:261:23: error: 'pDisplay' was not declared in this scope; did you mean 'CDisplay'?
  261 |         lv_display_t *pDisplay = (lv_display_t *) pParam;
      |                       ^~~~~~~~
      |                       CDisplay
lvgl.cpp:261:49: error: expected primary-expression before ')' token
  261 |         lv_display_t *pDisplay = (lv_display_t *) pParam;
      |                                                 ^
lvgl.cpp:264:9: error: 'lv_display_flush_ready' was not declared in this scope; did you mean 'lv_disp_flush_ready'?
  264 |         lv_display_flush_ready (pDisplay);
      |         ^~~~~~~~~~~~~~~~~~~~~~
      |         lv_disp_flush_ready
lvgl.cpp: In member function 'void CLVGL::SetupCursor(lv_indev_t*)':
lvgl.cpp:417:37: error: 'lv_image_dsc_t' does not name a type; did you mean 'lv_img_dsc_t'?
  417 |                 m_pCursorDesc = new lv_image_dsc_t;
      |                                     ^~~~~~~~~~~~~~
      |                                     lv_img_dsc_t
lvgl.cpp:421:39: error: 'struct lv_img_header_t' has no member named 'magic'
  421 |                 m_pCursorDesc->header.magic = LV_IMAGE_HEADER_MAGIC;
      |                                       ^~~~~
lvgl.cpp:421:47: error: 'LV_IMAGE_HEADER_MAGIC' was not declared in this scope
  421 |                 m_pCursorDesc->header.magic = LV_IMAGE_HEADER_MAGIC;
      |                                               ^~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:424:44: error: 'LV_COLOR_FORMAT_ARGB8888' was not declared in this scope
  424 |                 m_pCursorDesc->header.cf = LV_COLOR_FORMAT_ARGB8888;
      |                                            ^~~~~~~~~~~~~~~~~~~~~~~~
lvgl.cpp:425:39: error: 'struct lv_img_header_t' has no member named 'stride'
  425 |                 m_pCursorDesc->header.stride = CURSOR_WIDTH * 4;
      |                                       ^~~~~~
lvgl.cpp:429:59: error: 'lv_screen_active' was not declared in this scope; did you mean 'lv_scr_act'?
  429 |                 lv_obj_t *pCursorImage = lv_image_create (lv_screen_active ());
      |                                                           ^~~~~~~~~~~~~~~~
      |                                                           lv_scr_act
lvgl.cpp:429:42: error: 'lv_image_create' was not declared in this scope; did you mean 'lv_img_create'?
  429 |                 lv_obj_t *pCursorImage = lv_image_create (lv_screen_active ());
      |                                          ^~~~~~~~~~~~~~~
      |                                          lv_img_create
lvgl.cpp:431:17: error: 'lv_image_set_src' was not declared in this scope; did you mean 'lv_img_set_src'?
  431 |                 lv_image_set_src (pCursorImage, m_pCursorDesc);
      |                 ^~~~~~~~~~~~~~~~
      |                 lv_img_set_src
make: *** [../../Rules.mk:210: lvgl.o] Error 1

nickverlinden avatar Apr 24 '25 11:04 nickverlinden

Hi

I have performed some tests.

  1. I have set the full path: PREFIX=/opt/homebrew/bin/arm-none-eabi- (this is correct path, checked with which arm-non-eabi-gcc
  2. did make clean (resp ./makeall clean) everywhere and then make (resp .makeall)
  3. The I used the following makefile for addon/lvgl/sample

#SPI_DISPLAY = DISPLAY_TYPE_ST7789
SPI_DISPLAY = DISPLAY_TYPE_ILI9341
#I2C_DISPLAY = DISPLAY_TYPE_SSD1306
# tested with all of them

CIRCLEHOME = ../../..

OBJS    = main.o kernel.o

LIBS    = $(CIRCLEHOME)/addon/lvgl/liblvgl.a \
          $(CIRCLEHOME)/lib/usb/libusb.a \
          $(CIRCLEHOME)/lib/input/libinput.a \
          $(CIRCLEHOME)/lib/fs/libfs.a \
          $(CIRCLEHOME)/lib/libcircle.a

ifneq ($(strip $(SPI_DISPLAY)),)
LIBS    += $(CIRCLEHOME)/addon/display/libdisplay.a

CFLAGS  += -DSPI_DISPLAY=$(SPI_DISPLAY)
else ifneq ($(strip $(I2C_DISPLAY)),)
LIBS    += $(CIRCLEHOME)/addon/display/libdisplay.a

CFLAGS  += -DI2C_DISPLAY=$(I2C_DISPLAY)
endif

targ0:
        @echo "everything fine"
        @echo $(CIRCLEHOME)

include $(CIRCLEHOME)/Rules.mk

targ05:
        @echo "got rules"
-include $(DEPS)

targ1:
        @echo "final inclusion complete..."

Targ0 prints. Circlehome/Rules.mk exists.

But targ 05 or targ 1 does not print so I assume the error is in the include? I checked the rules.mk file, and there placed the full path /opt/homebrew/bin/arm-none-eabi- as well. No change. It only produces kernel.d and main.d in the sample folder, but no bootable image.

Please help.

naturalmechanics avatar Apr 24 '25 16:04 naturalmechanics

@naturalmechanics I don't think, you can debug a Makefile that way, or I do not understand your intention. As I understand it, a Makefile is completely parsed, before the target is executed, which is given on the command line. If no target is given, the first target found in the Makefile is executed.

@naturalmechanics, @nickverlinden I'm getting in doubt, if I can help you here. Because I do not have a Mac, I can only make guesses, what happens on macOS, but it's difficult.

If there is somebody out there, who as a Mac and has some knowledge about LVGL and Circle, perhaps you may have a look at this. It would be great, if LVGL could be built for Circle use on macOS. Currently this is not supported.

Another option would be to use a Raspberry Pi 4 or 5 under Raspberry Pi OS, install the AArch64-hosted toolchain for the wanted target (32 or 64-bit) from the well-known website (see above) and build LVGL with this system. That's working well, I tested it again.

rsta2 avatar Apr 24 '25 18:04 rsta2

No worries for me, i'm not using it. Was just here to help you confirm the build with a working toolchain. If i find some time i might poke around!

nickverlinden avatar Apr 24 '25 19:04 nickverlinden

Ok, so at the end, the solution is to build on a Linux host and prepare the final kernel?

naturalmechanics avatar Apr 24 '25 22:04 naturalmechanics

@naturalmechanics Yes, at least at the moment.

rsta2 avatar Apr 25 '25 09:04 rsta2

@rsta2

Hi man

I managed to build it on a linux Host.

In case it helps anyone:

uname: Linux glassplanet 6.12.9-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 10 Jan 2025 00:39:41 +0000 x86_64 GNU/Linux

OS Cachy Linux, cpu instruction v3

  • IMPORTANT the default Makefile does not work. I do need to replace the default Makefile in addon/lvgl with the second Makefile you sent me here
  • On Cachy, if someone is trying to build it, he will need to install : -- extra/arm-none-eabi-gcc -- arm-none-eabi-newlib (otherwise inttypes.h will me missing) -- arm-none-eabi-binutils (auto installs with arm-none-eabi-gcc, provides arm-none-eabi-as, arm-none-eabi-ar,arm-none-eabi-ld etc)

This will create a bootable kernel image.

Besides for changing the Makefile (which is the only non-standard part in the workflow) this took me 20 mins of work

Now, I would be very grateful, if you could tell me, how to

  1. bring output via an HDMI out, to a standard HDMI screen. Is there are example including Circle+lvgl?
  2. How do I compile it? the sample in addon/lvgl/sample, the makefile contains:
#SPI_DISPLAY = DISPLAY_TYPE_ST7789
#SPI_DISPLAY = DISPLAY_TYPE_ILI9341
#I2C_DISPLAY = DISPLAY_TYPE_SSD1306

But I want HDMI out. What do I need to change?

naturalmechanics avatar Apr 27 '25 13:04 naturalmechanics

What did not work with the default Makefile (any messages)? Please note that with the default Makefile it takes some time, until the build starts, because it has to collect the files, to be built, first.

I assume with the recommended toolchain (see the Circle README.md) it would work out of the box with the default Makefile.

HDMI output is the default for addon/lvgl/sample. You do not need to change anything. It will build the standard LVGL widget demo program.

rsta2 avatar Apr 27 '25 14:04 rsta2

Hi thank you for the response

What did not work with the default Makefile (any messages)?

It will not make the liblvgl.a, even after the run completes (as evident by the return of shell prompt) and then waiting for additional 10 min But your replacement file build it within 4-5 mins

HDMI output is the default for addon/lvgl/sample

that means i can directly use the kernel7l.img file, and boot RPI cm4 (Rasppi is set to 4 inRules.mk) while an hdmi screen is connected?

naturalmechanics avatar Apr 27 '25 14:04 naturalmechanics

The CM4 is special. You have to call configure with:

./configure -r 4 -d USE_XHCI_INTERNAL -d USE_EMBEDDED_MMC_CM

and rebuild all. USE_EMBEDDED_MMC_CM enables the access to the eMMC memory of the CM4 together with the library in addon/SDCard/.

rsta2 avatar Apr 27 '25 14:04 rsta2