Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to deal with C source libraries with static inline header functions? #77

Open
arkanoid87 opened this issue Jul 4, 2023 · 4 comments

Comments

@arkanoid87
Copy link

I was trying to wrap LVGL and implement original hello_world.c in Nim.

#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_LABEL

/**
 * Basic example to create a "Hello world" label
 */
void lv_example_get_started_1(void)
{
    /*Change the active screen's background color*/
    lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x003a57), LV_PART_MAIN);

    /*Create a white label, set its text and align it to the center*/
    lv_obj_t * label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello world");
    lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN);
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

#endif

This library is intended to be compiled with the project source, and has many static inline functions in header files, for example
lv_color_hex

inlined functions are skipped by futhark and never wrapped, and it makes generally sense when linking, but what should I do when the project importing the library is meant to call static inline header functions?

I tried, just for quick test, commenting out if node["inlined"].getBool: return
Compiling this file:

import futhark

importc:
  path "../lvgl"
  path "../lvgl/src/misc"
  path "../lvgl/src/core"
  "lvgl.h"
  "lv_color.h"
  "lv_obj_style_gen.h"

Resulted in clang complaining many redefinitions

Error: Opir exited with non-zero exit code 255.
Opir output: 
Warning: Possible failure to include lv_conf.h, please read the comment in this file if you get errors
Error: redefinition of 'lv_obj_get_style_width'
Error: redefinition of 'lv_obj_get_style_min_width'
Error: redefinition of 'lv_obj_get_style_max_width'
Error: redefinition of 'lv_obj_get_style_height'
Error: redefinition of 'lv_obj_get_style_min_height'
Error: redefinition of 'lv_obj_get_style_max_height'
Error: redefinition of 'lv_obj_get_style_x'
Error: redefinition of 'lv_obj_get_style_y'
Error: redefinition of 'lv_obj_get_style_align'
Error: redefinition of 'lv_obj_get_style_transform_width'
Error: redefinition of 'lv_obj_get_style_transform_height'
Error: redefinition of 'lv_obj_get_style_translate_x'
Error: redefinition of 'lv_obj_get_style_translate_y'
Error: redefinition of 'lv_obj_get_style_transform_zoom'
Error: redefinition of 'lv_obj_get_style_transform_angle'
Error: redefinition of 'lv_obj_get_style_transform_pivot_x'
Error: redefinition of 'lv_obj_get_style_transform_pivot_y'
Error: redefinition of 'lv_obj_get_style_pad_top'
Error: redefinition of 'lv_obj_get_style_pad_bottom'
Fatal: too many errors emitted, stopping now

Is there a designed way to apply Futhark in this context?

@PMunch
Copy link
Owner

PMunch commented Jul 5, 2023

The reason inlined weren't generated to begin with is because it makes no sense when dynamically linking. I don't quite remember if this was a matter of actually finding these in a header meant for dynamic linking, or if this was just me being cautious. But for compiling together with the sources it doesn't make sense to omit them.

I've pushed a new version 0.9.3 which adds the -d:generateInline flag. Along with this code:

import futhark

importc:
  path "../lvgl"
  "lvgl.h"

lvObjSetStyleBgColor(lvScrAct(), lvColorHex(0x003a57), LV_PART_MAIN.lvStyleSelectorT)

it now fails on the C building step (because I didn't tell it how to actually link with lvgl). If you get something set up with LVGL I would love to see the results :)

@arkanoid87
Copy link
Author

Thank you for addressing this

I can confirm that using -d:generateInline I end up with linking errors, but the errors are about linker not finding inlined functions in header, for example:

@mtest_lvgl.nim.c:(.text+0xee): undefined reference to `lv_scr_act'

defined in src/disp/lv_disp.h
https://github.com/lvgl/lvgl/blob/1c1b59988004622de564b2655af56757ece00182/src/disp/lv_disp.h#L373

Afaik compiling LVGL C files into a static or dynamic library file is not the way, as inlined functions wont be there anyway. I'd guess that the right way is to add the header pragma to inlined functions

I've tried (using outputPath) to manually add it to generate lv_scr_act function:

  proc lvscract*(): ptr lvobjt_469762759 {.cdecl, header: "../lvgl/src/core/lv_disp.h", importc: "lv_scr_act".}

but I get conflicting types

test_lvgl_d/@mtest_lvgl.nim.c:83:15: error: conflicting types for ‘lv_obj_set_style_bg_color’; have ‘void(tyObject_structlvobjt469762586__9bfZUyxszOQcFM5H1JhlJQw *, tyObject_lvcolor16t469762490__J1gTOGAA6so8WXGapvAg1w,  NU32)’ {aka ‘void(tyObject_structlvobjt469762586__9bfZUyxszOQcFM5H1JhlJQw *, tyObject_lvcolor16t469762490__J1gTOGAA6so8WXGapvAg1w,  unsigned int)’}
   83 | N_CDECL(void, lv_obj_set_style_bg_color)(tyObject_structlvobjt469762586__9bfZUyxszOQcFM5H1JhlJQw* obj, tyObject_lvcolor16t469762490__J1gTOGAA6so8WXGapvAg1w value, NU32 selector);

Am I missing something? How are inlined functions in .h files supposed to be used/imported in Nim code, without Futhark?

@PMunch
Copy link
Owner

PMunch commented Jul 5, 2023

Hmm, header should remove the declaration. Maybe having both cdecl and header confuses it. Try removing cdecl and see if that helps.

@PMunch
Copy link
Owner

PMunch commented Jul 12, 2023

Did you ever get a chance to test this?

EDIT: Just did some quick and dirty testing with a hand written Nim file and .h file. I can't get it to create any definition for my procedure when using the header pragma. Maybe this is a bug fixed in recent versions of Nim, which version are you running?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants