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

static function declarations do not get exported #7525

Open
kdschlosser opened this issue Dec 28, 2024 · 18 comments
Open

static function declarations do not get exported #7525

kdschlosser opened this issue Dec 28, 2024 · 18 comments

Comments

@kdschlosser
Copy link
Contributor

LVGL version

v9.2.2

Platform

Windows 11
cmake
ninja
MSVC

What happened?

@liamHowatt
@kisvegabor

Functions that are declared as static and are supposed to be apart of the public API do not get exported when compiling LVGL into a shared library.

Some examples are in src/core/lv_obj_style.h

My understanding of the purpose of static functions could be flawed and if it is please correct me. a function is made static if the function is only supposed to be used "locally". When I say locally I mean by the projects code. Static function declaration is more commonly used in C source files so there are no name collisions between source files and any functions that are declared in a source file as static has a zero possibility of being used in some other source file. Basically any function that is declared/defined in a C source file and is ONLY used in that very same source file should be made static. If for some reason a private header file has function declarations in it and that header file is included in public header files then the functions that are declared in the private header files should be made static. This is so they don't get exported when compiling a shared library. private header files really should not be included in any public header files. They should only be included in other private header files or in source files.

So public API functions should not be made static and all private functions should be made static. That is what my understanding is.

As a note, functions should not be defined in header files, only declared. the definitions should be in a source file. This keeps things a lot cleaner as far as documentation is concerned. it separate the documentation from the source code so things don't turn into a jumble that makes it hard to read.

In order for me to circumvent the problem I have to create wrapper functions that are not static so they get exported for use. a rather frustrating thing to have to do considering there are 292 functions in the LVGL API that are marked as static.

@vwheeler63 would probably know what is the "industry standard" when it comes to this kind of a thing. If I am wrong in my understanding of the use of static functions please let me know.

How to reproduce?

Here is a list of functions that are not marked as static and should be. This is not an all inclusive list as every option in LVGL is not turned on. I am sure there are functions in the disabled options that should also be made static as well.

Click me to see the list
LODEPNG_VERSION_STRING
code128_encode_gs1
code128_encode_raw
code128_estimate_len
gd_close_gif
gd_get_frame
gd_open_gif_data
gd_open_gif_file
gd_render_frame
gd_rewind
jd_decomp
jd_mcu_load
jd_mcu_output
jd_prepare
jd_restart
load_kern
lodepng_add_itext
lodepng_add_text
lodepng_can_have_alpha
lodepng_chunk_ancillary
lodepng_chunk_append
lodepng_chunk_check_crc
lodepng_chunk_create
lodepng_chunk_data
lodepng_chunk_data_const
lodepng_chunk_find
lodepng_chunk_find_const
lodepng_chunk_generate_crc
lodepng_chunk_length
lodepng_chunk_next
lodepng_chunk_next_const
lodepng_chunk_private
lodepng_chunk_safetocopy
lodepng_chunk_type
lodepng_chunk_type_equals
lodepng_clear_icc
lodepng_clear_itext
lodepng_clear_text
lodepng_color_mode_cleanup
lodepng_color_mode_copy
lodepng_color_mode_init
lodepng_color_mode_make
lodepng_color_stats_init
lodepng_compress_settings_init
lodepng_compute_color_stats
lodepng_convert
lodepng_crc32
lodepng_decode
lodepng_decode24
lodepng_decode24_file
lodepng_decode32
lodepng_decode32_file
lodepng_decode_file
lodepng_decode_memory
lodepng_decoder_settings_init
lodepng_decompress_settings_init
lodepng_deflate
lodepng_encode
lodepng_encode24
lodepng_encode24_file
lodepng_encode32
lodepng_encode32_file
lodepng_encode_file
lodepng_encode_memory
lodepng_encoder_settings_init
lodepng_error_text
lodepng_get_bpp
lodepng_get_channels
lodepng_get_raw_size
lodepng_has_palette_alpha
lodepng_huffman_code_lengths
lodepng_inflate
lodepng_info_cleanup
lodepng_info_copy
lodepng_info_init
lodepng_inspect
lodepng_inspect_chunk
lodepng_is_alpha_type
lodepng_is_greyscale_type
lodepng_is_palette_type
lodepng_load_file
lodepng_palette_add
lodepng_palette_clear
lodepng_save_file
lodepng_set_icc
lodepng_state_cleanup
lodepng_state_copy
lodepng_state_init
lodepng_zlib_compress
lodepng_zlib_decompress
qrcodegen_calcSegmentBufferSize
qrcodegen_encodeBinary
qrcodegen_encodeSegments
qrcodegen_encodeSegmentsAdvanced
qrcodegen_encodeText
qrcodegen_getMinFitVersion
qrcodegen_getModule
qrcodegen_getSize
qrcodegen_isAlphanumeric
qrcodegen_isNumeric
qrcodegen_makeAlphanumeric
qrcodegen_makeBytes
qrcodegen_makeEci
qrcodegen_makeNumeric
qrcodegen_version2size
test_ffs_fls

Here is a list of all of the lv_obj_* functions that get exported.

Click me to see the list ``` lv_obj_add_event_cb lv_obj_add_flag lv_obj_add_state lv_obj_add_style lv_obj_align lv_obj_align_to lv_obj_allocate_spec_attr lv_obj_area_is_visible lv_obj_assign_id lv_obj_bind_checked lv_obj_bind_flag_if_eq lv_obj_bind_flag_if_not_eq lv_obj_bind_state_if_eq lv_obj_bind_state_if_not_eq lv_obj_calculate_ext_draw_size lv_obj_calculate_style_text_align lv_obj_center lv_obj_check_type lv_obj_class_create_obj lv_obj_class_init_obj lv_obj_class_property_get_id lv_obj_clean lv_obj_create lv_obj_delete lv_obj_delete_anim_completed_cb lv_obj_delete_async lv_obj_delete_delayed lv_obj_destruct lv_obj_dump_tree lv_obj_enable_style_refresh lv_obj_event_base lv_obj_fade_in lv_obj_fade_out lv_obj_free_id lv_obj_get_child lv_obj_get_child_by_id lv_obj_get_child_by_type lv_obj_get_child_count lv_obj_get_child_count_by_type lv_obj_get_class lv_obj_get_click_area lv_obj_get_content_coords lv_obj_get_content_height lv_obj_get_content_width lv_obj_get_coords lv_obj_get_display lv_obj_get_event_count lv_obj_get_event_dsc lv_obj_get_ext_draw_size lv_obj_get_group lv_obj_get_height lv_obj_get_id lv_obj_get_index lv_obj_get_index_by_type lv_obj_get_layer_type lv_obj_get_local_style_prop lv_obj_get_parent lv_obj_get_property lv_obj_get_screen lv_obj_get_scroll_bottom lv_obj_get_scroll_dir lv_obj_get_scroll_end lv_obj_get_scroll_left lv_obj_get_scroll_right lv_obj_get_scroll_snap_x lv_obj_get_scroll_snap_y lv_obj_get_scroll_top lv_obj_get_scroll_x lv_obj_get_scroll_y lv_obj_get_scrollbar_area lv_obj_get_scrollbar_mode lv_obj_get_self_height lv_obj_get_self_width lv_obj_get_sibling lv_obj_get_sibling_by_type lv_obj_get_state lv_obj_get_style_opa_recursive lv_obj_get_style_prop lv_obj_get_style_property lv_obj_get_transformed_area lv_obj_get_user_data lv_obj_get_width lv_obj_get_x lv_obj_get_x2 lv_obj_get_x_aligned lv_obj_get_y lv_obj_get_y2 lv_obj_get_y_aligned lv_obj_has_class lv_obj_has_flag lv_obj_has_flag_any lv_obj_has_state lv_obj_has_style_prop lv_obj_hit_test lv_obj_id_compare lv_obj_init_draw_arc_dsc lv_obj_init_draw_image_dsc lv_obj_init_draw_label_dsc lv_obj_init_draw_line_dsc lv_obj_init_draw_rect_dsc lv_obj_invalidate lv_obj_invalidate_area lv_obj_is_editable lv_obj_is_group_def lv_obj_is_layout_positioned lv_obj_is_scrolling lv_obj_is_valid lv_obj_is_visible lv_obj_mark_layout_as_dirty lv_obj_move_children_by lv_obj_move_to lv_obj_move_to_index lv_obj_null_on_delete lv_obj_property_get_id lv_obj_readjust_scroll lv_obj_redraw lv_obj_refr_pos lv_obj_refr_size lv_obj_refresh_ext_draw_size lv_obj_refresh_self_size lv_obj_refresh_style lv_obj_remove_event lv_obj_remove_event_cb lv_obj_remove_event_cb_with_user_data lv_obj_remove_event_dsc lv_obj_remove_flag lv_obj_remove_from_subject lv_obj_remove_local_style_prop lv_obj_remove_state lv_obj_remove_style lv_obj_remove_style_all lv_obj_replace_style lv_obj_report_style_change lv_obj_scroll_by lv_obj_scroll_by_bounded lv_obj_scroll_by_raw lv_obj_scroll_to lv_obj_scroll_to_view lv_obj_scroll_to_view_recursive lv_obj_scroll_to_x lv_obj_scroll_to_y lv_obj_scrollbar_invalidate lv_obj_send_event lv_obj_set_align lv_obj_set_content_height lv_obj_set_content_width lv_obj_set_ext_click_area lv_obj_set_flex_align lv_obj_set_flex_flow lv_obj_set_flex_grow lv_obj_set_grid_align lv_obj_set_grid_cell lv_obj_set_grid_dsc_array lv_obj_set_height lv_obj_set_id lv_obj_set_layout lv_obj_set_local_style_prop lv_obj_set_parent lv_obj_set_pos lv_obj_set_properties lv_obj_set_property lv_obj_set_scroll_dir lv_obj_set_scroll_snap_x lv_obj_set_scroll_snap_y lv_obj_set_scrollbar_mode lv_obj_set_size lv_obj_set_state lv_obj_set_style_align lv_obj_set_style_anim lv_obj_set_style_anim_duration lv_obj_set_style_arc_color lv_obj_set_style_arc_image_src lv_obj_set_style_arc_opa lv_obj_set_style_arc_rounded lv_obj_set_style_arc_width lv_obj_set_style_base_dir lv_obj_set_style_bg_color lv_obj_set_style_bg_grad lv_obj_set_style_bg_grad_color lv_obj_set_style_bg_grad_dir lv_obj_set_style_bg_grad_opa lv_obj_set_style_bg_grad_stop lv_obj_set_style_bg_image_opa lv_obj_set_style_bg_image_recolor lv_obj_set_style_bg_image_recolor_opa lv_obj_set_style_bg_image_src lv_obj_set_style_bg_image_tiled lv_obj_set_style_bg_main_opa lv_obj_set_style_bg_main_stop lv_obj_set_style_bg_opa lv_obj_set_style_bitmap_mask_src lv_obj_set_style_blend_mode lv_obj_set_style_border_color lv_obj_set_style_border_opa lv_obj_set_style_border_post lv_obj_set_style_border_side lv_obj_set_style_border_width lv_obj_set_style_clip_corner lv_obj_set_style_color_filter_dsc lv_obj_set_style_color_filter_opa lv_obj_set_style_flex_cross_place lv_obj_set_style_flex_flow lv_obj_set_style_flex_grow lv_obj_set_style_flex_main_place lv_obj_set_style_flex_track_place lv_obj_set_style_grid_cell_column_pos lv_obj_set_style_grid_cell_column_span lv_obj_set_style_grid_cell_row_pos lv_obj_set_style_grid_cell_row_span lv_obj_set_style_grid_cell_x_align lv_obj_set_style_grid_cell_y_align lv_obj_set_style_grid_column_align lv_obj_set_style_grid_column_dsc_array lv_obj_set_style_grid_row_align lv_obj_set_style_grid_row_dsc_array lv_obj_set_style_height lv_obj_set_style_image_opa lv_obj_set_style_image_recolor lv_obj_set_style_image_recolor_opa lv_obj_set_style_layout lv_obj_set_style_length lv_obj_set_style_line_color lv_obj_set_style_line_dash_gap lv_obj_set_style_line_dash_width lv_obj_set_style_line_opa lv_obj_set_style_line_rounded lv_obj_set_style_line_width lv_obj_set_style_margin_bottom lv_obj_set_style_margin_left lv_obj_set_style_margin_right lv_obj_set_style_margin_top lv_obj_set_style_max_height lv_obj_set_style_max_width lv_obj_set_style_min_height lv_obj_set_style_min_width lv_obj_set_style_opa lv_obj_set_style_opa_layered lv_obj_set_style_outline_color lv_obj_set_style_outline_opa lv_obj_set_style_outline_pad lv_obj_set_style_outline_width lv_obj_set_style_pad_bottom lv_obj_set_style_pad_column lv_obj_set_style_pad_left lv_obj_set_style_pad_right lv_obj_set_style_pad_row lv_obj_set_style_pad_top lv_obj_set_style_radius lv_obj_set_style_rotary_sensitivity lv_obj_set_style_shadow_color lv_obj_set_style_shadow_offset_x lv_obj_set_style_shadow_offset_y lv_obj_set_style_shadow_opa lv_obj_set_style_shadow_spread lv_obj_set_style_shadow_width lv_obj_set_style_text_align lv_obj_set_style_text_color lv_obj_set_style_text_decor lv_obj_set_style_text_font lv_obj_set_style_text_letter_space lv_obj_set_style_text_line_space lv_obj_set_style_text_opa lv_obj_set_style_transform_height lv_obj_set_style_transform_pivot_x lv_obj_set_style_transform_pivot_y lv_obj_set_style_transform_rotation lv_obj_set_style_transform_scale_x lv_obj_set_style_transform_scale_y lv_obj_set_style_transform_skew_x lv_obj_set_style_transform_skew_y lv_obj_set_style_transform_width lv_obj_set_style_transition lv_obj_set_style_translate_x lv_obj_set_style_translate_y lv_obj_set_style_width lv_obj_set_style_x lv_obj_set_style_y lv_obj_set_user_data lv_obj_set_width lv_obj_set_x lv_obj_set_y lv_obj_stringify_id lv_obj_style_apply_color_filter lv_obj_style_create_transition lv_obj_style_deinit lv_obj_style_init lv_obj_style_state_compare lv_obj_swap lv_obj_transform_point lv_obj_transform_point_array lv_obj_tree_walk lv_obj_update_flag lv_obj_update_layer_type lv_obj_update_layout lv_obj_update_snap ```

you will notice that the following functions are missing.

Click me to see the list
lv_obj_style_get_selector_state
lv_obj_style_get_selector_part
lv_obj_set_style_pad_all
lv_obj_set_style_pad_hor
lv_obj_set_style_pad_ver
lv_obj_set_style_margin_all
lv_obj_set_style_margin_hor
lv_obj_set_style_margin_ver
lv_obj_set_style_pad_gap
lv_obj_set_style_size
lv_obj_set_style_transform_scale
lv_obj_get_style_space_left
lv_obj_get_style_space_right
lv_obj_get_style_space_top
lv_obj_get_style_space_bottom
lv_obj_calculate_style_text_align
lv_obj_get_style_transform_scale_x_safe
lv_obj_get_style_transform_scale_y_safe
lv_obj_get_style_width
lv_obj_get_style_min_width
lv_obj_get_style_max_width
lv_obj_get_style_height
lv_obj_get_style_min_height
lv_obj_get_style_max_height
lv_obj_get_style_length
lv_obj_get_style_x
lv_obj_get_style_y
lv_obj_get_style_align
lv_obj_get_style_transform_width
lv_obj_get_style_transform_height
lv_obj_get_style_translate_x
lv_obj_get_style_translate_y
lv_obj_get_style_transform_scale_x
lv_obj_get_style_transform_scale_y
lv_obj_get_style_transform_rotation
lv_obj_get_style_transform_pivot_x
lv_obj_get_style_transform_pivot_y
lv_obj_get_style_transform_skew_x
lv_obj_get_style_transform_skew_y
lv_obj_get_style_pad_top
lv_obj_get_style_pad_bottom
lv_obj_get_style_pad_left
lv_obj_get_style_pad_right
lv_obj_get_style_pad_row
lv_obj_get_style_pad_column


etc....
@kdschlosser
Copy link
Contributor Author

@vwheeler63
Copy link
Contributor

vwheeler63 commented Dec 28, 2024

Hi, Kevin! ( @kdschlosser )

static in front of inline makes the compiler TRY to NOT generate a separate function if the circumstances are right for it (there are several, which are beyond the scope of this writing). But compiling for a static library, not actually in an application is certainly one of those cases, in which case, indeed, it would not generate a function and also not generate a name for it in the static library.

I believe the answer to this is to remove the static from the declaration. (It would be nice if this could only be done in the case of generating a static library, in which case you would want all inline functions to generate real functions in the library. This is an area [inline functions while generating static libraries] that I have not dealt much with up to this point. @kisvegabor @liamHowatt Am I missing anything? )

Note: it is correct that these are in .h files because of the nature of inline functions -- they are meant to avoid generating a separate function (if possible) and instead incorporating the function's contents directly into the calling function when possible (as if the lines of the function definition were contained in a macro, and the macro were used in the caller). Though if they are in the API, they are definitely needed in the generated static library!

Wanna try removing the static for the static library generation to see if that remedies the missing exports? You should be able to do it for just 1 function and see if its name subsequently shows up in the exports.

(Currently trying it myself....)

Edit:

It seems to me like the static-library-generating project should make sure no names get removed.... and I'm sure there is a "standard procedure" for this case, that I am, as yet, unaware of.

Results: when static is removed from the inline function, the name does show up in the static library in the "text" section (generated machine instructions) as well as in a "stack unwind section" (which usually has something to do with C++ exception handling). I am using nm LvglWindowsStatic.lib to see this.

Edit:

On Windows, LvglWindowsSimulator.exe is slightly smaller without static before the inline keyword.

Additional:

The disassembly of LvglWindowsSimulator.exe shows actual CALLS being made to lv_obj_style_pad_all() function instead of in-lining if static is taken away. With the static keyword present, the contents of the function are being incorporated into their callers.

@kdschlosser
Copy link
Contributor Author

just because a function in inlined doesn't mean it always gets inlined. simply changing the compiler optimization alters this behavior.

But at any rate the solution would be to create macros that would handle it, Is there a need for the function to be static? I don't think there is a need to have the function declared as static when using inline.

https://stackoverflow.com/questions/7762731/whats-the-difference-between-static-and-static-inline-function

It's the static that is causing the issue not the inline and it can/should be removed as there is no issue with the same function existing in other translation units because it doesn't.

@kdschlosser
Copy link
Contributor Author

The LVGL simulator is not linked against a shared library. It is linking against a static one.

@vwheeler63
Copy link
Contributor

vwheeler63 commented Dec 28, 2024

The LVGL simulator is not linked against a shared library. It is linking against a static one.

I know -- I was using it to compare when there were actual calls present.

@kdschlosser
Copy link
Contributor Author

There has to be a compiler switch or a linker switch that controls this behavior.

@kdschlosser
Copy link
Contributor Author

what I also don't know is if the static functions get exported properly when compiling under Linux. If they do get exported then we can use a simple

#if defined(MSVC) && defined(DLL)
#define STATIC_INLINE
#else
#define STATIC_INLINE     static inline
#endif

and it would get used like so...

STATIC_INLINE void lv_obj_set_style_margin_all(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
{
    lv_obj_set_style_margin_left(obj, value, selector);
    lv_obj_set_style_margin_right(obj, value, selector);
    lv_obj_set_style_margin_top(obj, value, selector);
    lv_obj_set_style_margin_bottom(obj, value, selector);
}

when compiling as a shared library using MSVC then -DDLL would need to be added to the compiler arguments which is pretty easily done..

@vwheeler63
Copy link
Contributor

If they do get exported then we can use a simple

I like it! I'm anxious to see what @kisvegabor and @liamHowatt think once they get back after the 6th....

@kdschlosser
Copy link
Contributor Author

it doesn't work with MSVC...

The reason why it doesn't work is because it's a definition and not a declaration. so when the header file gets imported into a C source file and then again into another C source file there are now 2 function definitions that are the same.

I had to move the definitions into a C source file and then make a declaration in the header file. Removing the static inline of course. That is the only way I was able to get it to compile and have the functions properly exported.

@kdschlosser
Copy link
Contributor Author

It's going to become a coding mess in order to make it work right because there will need to be a double set of code for the same functions, ones that are static inline and defined in the header file but guarded with a macro so it known to use those when compiling without making a shared library. The second will be defined in a c source file without the static inline and once again guarded with a macro for a shared library compilation.

The big ? is how does this all play out compiling on posix using clang or gcc or is this just an issue that is specific to MSVC. I am thinking it is going to be an MSVC specific bump in the road.

I even tried to force it by turning off inline functions completely using the /Ob0 switch and I also tried adding the functions to an export definition file. Neither worked.

@vwheeler63
Copy link
Contributor

vwheeler63 commented Dec 29, 2024

it doesn't work with MSVC...

Actually, that's now now inline functions work. The compiler and linker work it out so at most there is only one function with that name. BUT! I have not thoroughly tested it with the static-library output, so you may be right.

@vwheeler63
Copy link
Contributor

vwheeler63 commented Dec 29, 2024

It's going to become a coding mess

Duplicate code definitely does not sound like a good idea. I am thinking Liam and Gábor might have some insights.

Did you test it with just removing the static? Does it work to link with it then as a static library? The test I did yesterday (looking up the name lv_obj_set_style_pad_all with the nm command in the generated static library) indicated it generated a globally-available function for it.

@kdschlosser
Copy link
Contributor Author

no it doesn't work the functions do not get exported, and why would they? The function is supposed to be inlined which an oversimplification of it is it acts kind of like a macro does where it gets inserted into the place it is being called.

With what I am doing I cannot link as a static library. It needs to be a shared library because it is being compiled all by itself with no other C code accessing it.

There is a binding that I wrote for LVGL that allows LVGL to be used in CPython on a desktop. To do that I am using the ctypes module in CPython as the binding layer to access the shared library. That makes it cross platform so it will work on anything that is able to run CPython so long as I can compile LVGL as a shared library. There is no way to access a static library from inside of CPython unless I write the binding code in C. Doing that would be a large task. It could be done using swig or cython but it would be a very large undertaking.

@vwheeler63
Copy link
Contributor

...it would be a very large undertaking.

Probably even better to be generated code.

That said, if the static library is to be usable at all, the entire API must be available. I guess it's over to @kisvegabor to determine how to remedy. I can think of 2 workable solutions off the top of my head:

  1. turn them into normal functions, or
  2. turn them into macros.

I am thinking #2 won't work for a Python binding, am I right?

@kdschlosser
Copy link
Contributor Author

I am thinking #2 won't work for a Python binding, am I right?

no it will not. macros replace code.

I did however come up with an idea. Leave the inline static functions how they are just rename then to something else. Maybe prefixing them with an underscore. do a check to see if the compilation is for a shared library running MSVC using a macro that can be passed to the compiler at the command line. If the macro exists then wrapper functions that are not static inline get made that will make the needed calls to the static inline functions. and if that macro doesn't exist then macros gets created instead that point to the underscore prefixed functions.

That will be the cleanest way of doing it allowing everything to work like it should.

I am going to code that up. Going to need your assistance with it to handle the documentation end of things. It's going to be tricky to get it to work correctly so the documentation displays how it does right now. Maybe not use macros that point to the static inline functions maybe create static inline function wrappers only when the documentation is being compiled.

Gonna have to dink about with it so see what the best way is to handle that.

@kdschlosser
Copy link
Contributor Author

kdschlosser commented Dec 30, 2024

Macros are not available to any binding other than the C++ binding. That is because the C++ binding LVGL is able to be compiled with the binding and not as a shared library... The MicroPython binding is not able to use macros because the binding code gets generated from the preprocessor output which means all of the macros have been expanded so they are not visible to the code generator.

The question is can this be done...

static inline int32_t _obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part)
{
    lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_HEIGHT);
    return (int32_t)v.num;
}

#ifdef MSVC_SHARED_LIB
int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part) return _obj_get_style_min_height(obj, part);
#else
static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part) return _obj_get_style_min_height(obj, part);
#endif

can you inline an inlined function like that?

@kdschlosser
Copy link
Contributor Author

I just remembered there is no documentation for these functions because they are generated using a script. you can instruct Doxygen to ignore the _obj_get_style_min_height function without any issue and you can change the code to read

#if defined(MSVC_SHARED_LIB) && !defined(DOXYGEN)
int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part) return _obj_get_style_min_height(obj, part);
#else
static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part) return _obj_get_style_min_height(obj, part);
#endif

so when doing a documentation build on Windows the documentation will capture the static inline portion of the function when generating the API documentation.

@kdschlosser
Copy link
Contributor Author

I just don't know how the compiler will handle the nested inline function calls. Will it optimize it correctly without making the compiled binary larger... That is something I do not know...

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