-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Comments
Hi, Kevin! ( @kdschlosser )
I believe the answer to this is to remove the Note: it is correct that these are in Wanna try removing the (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 Edit: On Windows, Additional: The disassembly of |
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. 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. |
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. |
There has to be a compiler switch or a linker switch that controls this behavior. |
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 |
I like it! I'm anxious to see what @kisvegabor and @liamHowatt think once they get back after the 6th.... |
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 |
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 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. |
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. |
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 |
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. |
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:
I am thinking |
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. |
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? |
I just remembered there is no documentation for these functions because they are generated using a script. you can instruct Doxygen to ignore the #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. |
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... |
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
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
The text was updated successfully, but these errors were encountered: