lvgl / lv_binding_micropython

LVGL binding for MicroPython
MIT License
250 stars 161 forks source link

Some compilers do not accept `.mp_obj_type` in 1.20 #282

Closed embeddedt closed 1 year ago

embeddedt commented 1 year ago

I'm finding that Emscripten's clang version is refusing to accept the way some structs are being initialized now. This doesn't happen before the 1.20 merge so I assume it's related to upstream changing how object types are defined. Any ideas?

build/lvgl/lv_mpy.c:1138:20: error: initializer element is not a compile-time constant
    .mp_obj_type = mp_lv_LV_RES_type_base,
                   ^~~~~~~~~~~~~~~~~~~~~~
build/lvgl/lv_mpy.c:1184:20: error: initializer element is not a compile-time constant
    .mp_obj_type = mp_lv_ENUM_LV_LOG_LEVEL_type_base,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
build/lvgl/lv_mpy.c:1246:20: error: initializer element is not a compile-time constant
    .mp_obj_type = mp_lv_LV_ALIGN_type_base,
                   ^~~~~~~~~~~~~~~~~~~~~~~~
build/lvgl/lv_mpy.c:1294:20: error: initializer element is not a compile-time constant
    .mp_obj_type = mp_lv_LV_DIR_type_base,
Code near line 1246 ```c STATIC MP_DEFINE_CONST_OBJ_TYPE( mp_lv_LV_ALIGN_type_base, MP_QSTR_LV_ALIGN, MP_TYPE_FLAG_NONE, print, LV_ALIGN_print, attr, call_parent_methods, locals_dict, &LV_ALIGN_locals_dict ); STATIC const mp_lv_obj_type_t mp_lv_LV_ALIGN_type = { #ifdef LV_OBJ_T .lv_obj_class = NULL, #endif .mp_obj_type = mp_lv_LV_ALIGN_type_base, }; ```
amirgon commented 1 year ago

Strange. All Micropython types are now defined in the new way, so all ports including wasm are already using them.

Indeed, mp_lv_LV_ALIGN_type_base should be a compile-time constant because mp_lv_LV_ALIGN_type is defined static (When initializing an object of static or thread-local storage duration, every expression in the initializer must be a constant expression or string literal) - but it is! since it's defined itself as STATIC MP_DEFINE_CONST_OBJ_TYPE

I can find examples in upstream Micropython of doing the same thing. For example:

STATIC MP_DEFINE_CONST_OBJ_TYPE(
    mp_type_thread_lock,
    MP_QSTR_lock,
    MP_TYPE_FLAG_NONE,
    locals_dict, &thread_lock_locals_dict
    );

...

STATIC const mp_rom_map_elem_t mp_module_thread_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__thread) },
    { MP_ROM_QSTR(MP_QSTR_LockType), MP_ROM_PTR(&mp_type_thread_lock) },

Here too, mp_type_thread_lock is defined as static with MP_DEFINE_CONST_OBJ_TYPE and used to initialize the static const structure mp_module_thread_globals_table.

Could you try to enable MICROPY_PY_THREAD in ports/webassembly/mpconfigport.h and see if you are getting the same error on upstream micropython?

What is the clang version that you are using? Is it possible to switch clang version on Emscripten?

embeddedt commented 1 year ago

Could you try to enable MICROPY_PY_THREAD in ports/webassembly/mpconfigport.h and see if you are getting the same error on upstream micropython?

I don't get the error when I do that.

What is the clang version that you are using? Is it possible to switch clang version on Emscripten?

The previous version of Emscripten I was using included Clang 13. I'll update to the latest version (which uses Clang 17) and see what happens.

embeddedt commented 1 year ago

Exact same error, unfortunately. -Werror is disabled and there is no -pedantic present, so I'm not sure what is causing this. This is the full compiler invocation:

emcc -Wno-unused-function -DFFCONF_H=\"lib/oofatfs/ffconf.h\" -std=gnu99 -Wall -Wno-error -Wdouble-promotion -Wfloat-conversion -DNDEBUG -Os -I../../lib/lv_bindings -I. -I../.. -Ibuild -I/work/emsdk/upstream/emscripten/cache/sysroot/include/freetype2 -fdata-sections -ffunction-sections -DMICROPY_SDL=1 -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -DMICROPY_MODULE_FROZEN_STR -DMICROPY_MODULE_FROZEN_MPY -D MICROPY_FROZEN_MANIFEST=manifest.py -c -MD -o build/build/lvgl/lv_mpy.o build/lvgl/lv_mpy.c

amirgon commented 1 year ago

Could you try branch fix/282? I changed mp_obj_type to pointer, I think it should be anyway.

embeddedt commented 1 year ago

Seems to have moved the problem to a different location. Progress?

build/lvgl/lv_mpy.c:15952:13: error: initializer element is not a compile-time constant
 15952 |     parent, mp_lv_obj_type.mp_obj_type,
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~
../../py/obj.h:783:250: note: expanded from macro 'MP_DEFINE_CONST_OBJ_TYPE'
  783 | #define MP_DEFINE_CONST_OBJ_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_type_t, __VA_ARGS__))
      |                                                                                                                                                                                                                                                          ^~~~~~~~~~~
../../py/obj.h:749:415: note: expanded from macro 'MP_DEFINE_CONST_OBJ_TYPE_NARGS_7'
  749 | #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slots = { v1, v2, v3, v4, v5, v6, v7, } }
      |                                                                                                                                                                                                                                                                                                                                                                                                                               ^~
../../py/obj.h:770:44: note: expanded from macro 'MP_DEFINE_CONST_OBJ_TYPE_EXPAND'
  770 | #define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x
      |                                            ^
STATIC MP_DEFINE_CONST_OBJ_TYPE(
    mp_lv_canvas_type_base,
    MP_QSTR_canvas,
    MP_TYPE_FLAG_NONE,
    print, canvas_print,
    make_new, canvas_make_new,
    binary_op, mp_lv_obj_binary_op,
    attr, call_parent_methods,
    buffer, mp_lv_obj_get_buffer,
    parent, mp_lv_obj_type.mp_obj_type, // <---- this is the line that errors
    locals_dict, &canvas_locals_dict
);
amirgon commented 1 year ago

Seems to have moved the problem to a different location. Progress?

Maybe...
I've updated the branch, could you try again?

embeddedt commented 1 year ago

Unfortunately looks about the same to me.

build/lvgl/lv_mpy.c:15429:34: error: initializer element is not a compile-time constant
 15429 |     { MP_ROM_QSTR(MP_QSTR_CTRL), MP_ROM_PTR(mp_lv_LV_BTNMATRIX_CTRL_type.mp_obj_type) },
       |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../py/obj.h:348:23: note: expanded from macro 'MP_ROM_PTR'
  348 | #define MP_ROM_PTR(p) (p)
      |                       ^~~
build/lvgl/lv_mpy.c:15462:13: error: initializer element is not a compile-time constant
 15462 |     parent, mp_lv_obj_type.mp_obj_type,
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~
../../py/obj.h:783:250: note: expanded from macro 'MP_DEFINE_CONST_OBJ_TYPE'
  783 | #define MP_DEFINE_CONST_OBJ_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_type_t, __VA_ARGS__))
      |                                                                                                                                                                                                                                                          ^~~~~~~~~~~
../../py/obj.h:749:415: note: expanded from macro 'MP_DEFINE_CONST_OBJ_TYPE_NARGS_7'
  749 | #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7(_struct_type, _typename, _name, _flags, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slots = { v1, v2, v3, v4, v5, v6, v7, } }
      |                                                                                                                                                                                                                                                                                                                                                                                                                               ^~
../../py/obj.h:770:44: note: expanded from macro 'MP_DEFINE_CONST_OBJ_TYPE_EXPAND'
  770 | #define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x
      |                                            ^
build/lvgl/lv_mpy.c:15771:13: error: initializer element is not a compile-time constant
 15771 |     parent, mp_lv_obj_type.mp_obj_type,
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~
amirgon commented 1 year ago

Unfortunately looks about the same to me.

Forgot to push, sorry.... Try now?

embeddedt commented 1 year ago

Much better, now only the MP_ROM_PTR one remains.

build/lvgl/lv_mpy.c:12731:34: error: initializer element is not a compile-time constant
 12731 |     { MP_ROM_QSTR(MP_QSTR_FLAG), MP_ROM_PTR(mp_lv_LV_OBJ_FLAG_type.mp_obj_type) },
       |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../py/obj.h:348:23: note: expanded from macro 'MP_ROM_PTR'
  348 | #define MP_ROM_PTR(p) (p)
      |                       ^~~
amirgon commented 1 year ago

Much better, now only the MP_ROM_PTR one remains.

Fixed now?

embeddedt commented 1 year ago

Seems to have carried on compiling now! Thank you!

amirgon commented 1 year ago

When it's all good - we can merge https://github.com/lvgl/lv_binding_micropython/pull/284