dpkg-gensymbols
Ubuntu Symbols - dpkg-gensymbols
Introduction
This page seeks to summarise what I learnt from recently trying to understand library symbols. (Some of this may definitely be incorrect and wrong assumptions have made, please feel free to correct me.)
I attempted to try and understand library symbols while looking at the update for pidgin from 2.5.0 to 2.5.1. So the examples that follow below are related to that.
When creating a library, we need to have a set of names (symbols) to call each of the exported functions, and we need to let programs that use the library use the same symbols to identify what they want the library to do.
dpkg-gensymbols hunts down libraries, and creates a debian/symbols file : this file is then used to better identify the versioned dependencies of a program using the library (from ${shlibs:depends}
All libraries that export symbols (and a .so file) ought use it, but this is not the case as of yet. For those that don't use dpkg-gensymbols, please see /PackagingGuide/Recipes/CheckingLibrarySymbols.
shared objects are useful for two different purposes 1) as a plugin mechanism in conjunction with dlopen 2) for dynamic libraries, to share code between different projects
Setup
Put the following into ~/.bashrc and ~/.pbuilderrc
export DPKG_GENSYMBOLS_CHECK_LEVEL=4
This causes pbuilder to fail building if the symbols are incorrect.
Background
Taken from the following http://lists.debian.org/debian-devel/2007/06/msg00197.html
The repository contains two scripts: a new "dpkg-gensymbols" that is used to generate "DEBIAN/symbols" file during the build process and a replacement for "dpkg-shlibdeps" that uses symbol files to generate dependencies and normal shlibs if there's no corresponding symbols file. How does it work to generate a dependency ----------------------------------------- dpkg-shlibdeps works as usual except that instead of looking at *.shlibs file, it first tries to find *.symbols file. Then for each ELF binary it will generate the list of dynamic symbols that it uses. For each symbol, it will go through the list of libraries (in the same order as they are referenced in the binary) and try to find the symbol in the corresponding symbol file. If yes, it checks the minimal version of the library which provides it and compares/updates the minimal version needed by the whole package. If the symbol is not found in a *.symbols file, then we check against the libraries which are listed by the binary but for which we haven't found an *.symbols file. If the symbol is present in one of those libraries, then we record the dependency indicated by the corresponding shlibs file. If the symbol is found nowhere it displays a warning (maybe it should fail?). At the end, it computes the resulting dependency. dpkg-shlibdeps will use symbols file available in /etc/dpkg/symbols/. So if you want to try it out without recompiling many packages, you can simply generate the symbols file that you want and put them in this directory. What does it mean for library maintainers ----------------------------------------- Library maintainers are supposed to maintain the *.symbols file. For this, they have to create files "debian/<package>.symbols.<arch>" (dpkg-gensymbols will try too fallback to "debian/symbols.<arch>", "debian/<package>.symbols" and "debian/symbols"). They are required to provide the minimal version (as used in the dependency generated) associated to each symbol. Then during the build process, dpkg-gensymbols will use those symbols file and merge information concerning newer symbols provided by the library. The result is provided inside the package itself as a DEBIAN/symbols file. The canonical way to call dpkg-gensymbols during a build is: dpkg-gensymbols -p<package> -P<packagebuildtree> (the version is extracted from the changelog, and all the libraries found in the <packagebuildtree> are scanned) If you want to explicitly list the libraries that will be scanned, then you can pass several -e<library-file> (you can use glob expression like -edebian/libc6/lib/*.so*). Library maintainers who want to avoid any mistakes can use the "-c" option (for compare) which will make the compilation fail if the generated symbols file differ from the maintainer supplied file. In that case, the build log contains a diff between the two symbols files and he can analyze the differences (and update his file if necessary). Creating a first version of the symbols file is not difficult either. For the sake of example, here's how I did with the libc6 package. I included the etch package first so that I have history of symbols starting from etch. $ aptitude download libc6/stable libc6/unstable $ dpkg -x libc6_2.3.6.ds1-13_i386.deb /tmp/etch-libc6 $ dpkg -x libc6_2.5-9_i386.deb /tmp/sid-libc6 $ dpkg-gensymbols -v2.3.6.ds1 -plibc6 -e/tmp/etch-libc6/lib*.so* -Olibc6.symbols $ dpkg-gensymbols -v2.5-9 -plibc6 -e/tmp/sid-libc6/lib*.so* -Olibc6.symbols Note that -P/tmp/etch-libc6 should have been enough but since the etch package of the libc6 contains multiple versions of the same shared libraries I had to specify precisely which files I wanted to scan with -e. Note also that you should do that for all architectures in case symbol information differ from on arch to the other. Since this is painful, I'll try to generate files ready to be downloaded (see below). If you know that there's no difference between architectures, you don't need to bother but using -c during build will help you ensuring that you were right and that there's indeed no difference.
Example
Pidgin used cdbs so the dh scripts are called by cdbs and are not in the debian/rules file. dh_makeshlibs calls dpkg-gensymbols to create the symbols (man dpkg-gensymbols) and then dh_shlibdeps checks the created .so files and what they are linked against.
After using debuild -S -sa and creating my new pidgin .dsc file and .diff, i run pbuilder build against the .dsc.
This is a piece of the output from the log
dh_makeshlibs -plibpurple0 -V "libpurple0 (>= 1:2.5.0)" -X/usr/lib/purple-2 dpkg-gensymbols: warning: some libraries disappeared in the symbols file: libgnt.so.0 dpkg-gensymbols: warning: some new symbols appeared in the symbols file: see diff output below dpkg-gensymbols: warning: debian/libpurple0/DEBIAN/symbols doesn't match completely debian/libpurple0.symbols --- dpkg-gensymbolsLy6Y4M 2008-09-03 10:16:03.000000000 +0000 +++ dpkg-gensymbolsoJiCaK 2008-09-03 10:16:03.000000000 +0000 @@ -1,301 +1,3 @@ -libgnt.so.0 libpurple0 #MINVER# - g_hash_table_duplicate@Base 1:2.4.0 - gnt_ascii_only@Base 1:2.4.0 - gnt_bindable_action_free@Base 1:2.4.0 - gnt_bindable_action_param_free@Base 1:2.4.0 - gnt_bindable_bindings_view@Base 1:2.4.0 - gnt_bindable_build_help_window@Base 1:2.4.0 - gnt_bindable_check_key@Base 1:2.5.0 - gnt_bindable_class_register_action@Base 1:2.4.0 - gnt_bindable_get_gtype@Base 1:2.4.0 - gnt_bindable_perform_action_key@Base 1:2.4.0 - gnt_bindable_perform_action_named@Base 1:2.4.0 - gnt_bindable_register_binding@Base 1:2.4.0 - gnt_bindable_remap_keys@Base 1:2.4.0 - gnt_boolean_handled_accumulator@Base 1:2.4.0 - gnt_box_add_widget@Base 1:2.4.0 - gnt_box_get_gtype@Base 1:2.4.0 - gnt_box_give_focus_to_child@Base 1:2.4.0 - gnt_box_move_focus@Base 1:2.4.0 - gnt_box_new@Base 1:2.4.0 - gnt_box_readjust@Base 1:2.4.0 - gnt_box_remove@Base 1:2.4.0 - gnt_box_remove_all@Base 1:2.4.0 - gnt_box_set_alignment@Base 1:2.4.0 - gnt_box_set_fill@Base 1:2.4.0 - gnt_box_set_pad@Base 1:2.4.0 - gnt_box_set_title@Base 1:2.4.0 - gnt_box_set_toplevel@Base 1:2.4.0 - gnt_box_sync_children@Base 1:2.4.0 - gnt_button_get_gtype@Base 1:2.4.0 - gnt_button_new@Base 1:2.4.0 - gnt_check_box_get_checked@Base 1:2.4.0 - gnt_check_box_get_gtype@Base 1:2.4.0 - gnt_check_box_new@Base 1:2.4.0 - gnt_check_box_set_checked@Base 1:2.4.0 - gnt_clipboard_get_gtype@Base 1:2.4.0 - gnt_clipboard_get_string@Base 1:2.4.0 - gnt_clipboard_set_string@Base 1:2.4.0 - gnt_closure_marshal_BOOLEAN__INT_INT@Base 1:2.4.0 - gnt_closure_marshal_BOOLEAN__INT_INT_INT@Base 1:2.4.0 - gnt_closure_marshal_BOOLEAN__INT_INT_INT_POINTER@Base 1:2.4.0 - gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER@Base 1:2.4.0 - gnt_closure_marshal_BOOLEAN__STRING@Base 1:2.4.0 - gnt_closure_marshal_BOOLEAN__VOID@Base 1:2.4.0 - gnt_closure_marshal_VOID__INT_INT@Base 1:2.4.0 - gnt_closure_marshal_VOID__INT_INT_INT_INT@Base 1:2.4.0 - gnt_closure_marshal_VOID__POINTER_BOOLEAN@Base 1:2.4.0 - gnt_closure_marshal_VOID__POINTER_POINTER@Base 1:2.4.0 - gnt_closure_marshal_VOID__STRING_STRING@Base 1:2.4.0 - gnt_color_add_pair@Base 1:2.4.0 - gnt_color_pair@Base 1:2.4.0 - gnt_color_pairs_parse@Base 1:2.4.0 - gnt_colors_get_color@Base 1:2.4.0 - gnt_colors_parse@Base 1:2.4.0 - gnt_combo_box_add_data@Base 1:2.4.0 - gnt_combo_box_get_gtype@Base 1:2.4.0 - gnt_combo_box_get_selected_data@Base 1:2.4.0 - gnt_combo_box_new@Base 1:2.4.0 - gnt_combo_box_remove@Base 1:2.4.0 - gnt_combo_box_remove_all@Base 1:2.4.0 - gnt_combo_box_set_selected@Base 1:2.4.0 - gnt_entry_add_suggest@Base 1:2.4.0 - gnt_entry_add_to_history@Base 1:2.4.0 - gnt_entry_clear@Base 1:2.4.0 - gnt_entry_get_gtype@Base 1:2.4.0 - gnt_entry_get_text@Base 1:2.4.0 - gnt_entry_new@Base 1:2.4.0 - gnt_entry_remove_suggest@Base 1:2.4.0 - gnt_entry_set_always_suggest@Base 1:2.4.0 - gnt_entry_set_flag@Base 1:2.4.0 - gnt_entry_set_history_length@Base 1:2.4.0 - gnt_entry_set_masked@Base 1:2.4.0 - gnt_entry_set_max@Base 1:2.4.0 - gnt_entry_set_text@Base 1:2.4.0 - gnt_entry_set_word_suggest@Base 1:2.4.0 - gnt_file_new@Base 1:2.4.0 - gnt_file_new_dir@Base 1:2.4.0 - gnt_file_sel_get_dirs_only@Base 1:2.4.0 - gnt_file_sel_get_gtype@Base 1:2.4.0 - gnt_file_sel_get_must_exist@Base 1:2.4.0 - gnt_file_sel_get_selected_file@Base 1:2.4.0 - gnt_file_sel_get_selected_multi_files@Base 1:2.4.0 - gnt_file_sel_new@Base 1:2.4.0 - gnt_file_sel_set_current_location@Base 1:2.4.0 - gnt_file_sel_set_dirs_only@Base 1:2.4.0 - gnt_file_sel_set_multi_select@Base 1:2.4.0 - gnt_file_sel_set_must_exist@Base 1:2.4.0 - gnt_file_sel_set_read_fn@Base 1:2.4.0 - gnt_file_sel_set_suggested_filename@Base 1:2.4.0 - gnt_get_clipboard@Base 1:2.4.0 - gnt_get_clipboard_string@Base 1:2.4.0 - gnt_giveup_console@Base 1:2.4.0 - gnt_init@Base 1:2.4.0 - gnt_init_colors@Base 1:2.4.0 - gnt_init_keys@Base 1:2.4.0 - gnt_init_styles@Base 1:2.4.0 - gnt_is_refugee@Base 1:2.4.0 - gnt_key_cdown@Base 1:2.4.0 - gnt_key_cleft@Base 1:2.4.0 - gnt_key_cright@Base 1:2.4.0 - gnt_key_cup@Base 1:2.4.0 - gnt_key_lookup@Base 1:2.4.0 - gnt_key_translate@Base 1:2.4.0 - gnt_keys_add_combination@Base 1:2.4.0 - gnt_keys_del_combination@Base 1:2.4.0 - gnt_keys_find_combination@Base 1:2.4.0 - gnt_keys_print_combinations@Base 1:2.4.0 - gnt_keys_refine@Base 1:2.4.0 - gnt_label_get_gtype@Base 1:2.4.0 - gnt_label_new@Base 1:2.4.0 - gnt_label_new_with_format@Base 1:2.4.0 - gnt_label_set_text@Base 1:2.4.0 - gnt_line_get_gtype@Base 1:2.4.0 - gnt_line_new@Base 1:2.4.0 - gnt_main@Base 1:2.4.0 - gnt_menu_add_item@Base 1:2.4.0 - gnt_menu_get_gtype@Base 1:2.4.0 - gnt_menu_get_item@Base 1:2.4.0 - gnt_menu_new@Base 1:2.4.0 - gnt_menuitem_activate@Base 1:2.4.0 - gnt_menuitem_check_get_checked@Base 1:2.4.0 - gnt_menuitem_check_get_gtype@Base 1:2.4.0 - gnt_menuitem_check_new@Base 1:2.4.0 - gnt_menuitem_check_set_checked@Base 1:2.4.0 - gnt_menuitem_get_gtype@Base 1:2.4.0 - gnt_menuitem_get_id@Base 1:2.4.0 - gnt_menuitem_get_submenu@Base 1:2.4.0 - gnt_menuitem_get_trigger@Base 1:2.4.0 - gnt_menuitem_new@Base 1:2.4.0 - gnt_menuitem_set_callback@Base 1:2.4.0 - gnt_menuitem_set_id@Base 1:2.4.0 - gnt_menuitem_set_submenu@Base 1:2.4.0 - gnt_menuitem_set_trigger@Base 1:2.4.0 - gnt_quit@Base 1:2.4.0 - gnt_register_action@Base 1:2.4.0 - gnt_screen_menu_show@Base 1:2.4.0 - gnt_screen_move_widget@Base 1:2.4.0 - gnt_screen_occupy@Base 1:2.4.0 - gnt_screen_release@Base 1:2.4.0 - gnt_screen_rename_widget@Base 1:2.4.0 - gnt_screen_resize_widget@Base 1:2.4.0 - gnt_screen_update@Base 1:2.4.0 - gnt_set_clipboard_string@Base 1:2.4.0 - gnt_slider_advance_step@Base 1:2.4.0 - gnt_slider_get_gtype@Base 1:2.4.0 - gnt_slider_get_value@Base 1:2.4.0 - gnt_slider_new@Base 1:2.4.0 - gnt_slider_reflect_label@Base 1:2.4.0 - gnt_slider_set_large_step@Base 1:2.4.0 - gnt_slider_set_range@Base 1:2.4.0 - gnt_slider_set_small_step@Base 1:2.4.0 - gnt_slider_set_step@Base 1:2.4.0 - gnt_slider_set_value@Base 1:2.4.0 - gnt_style_get@Base 1:2.4.0 - gnt_style_get_bool@Base 1:2.4.0 - gnt_style_get_color@Base 1:2.4.0 - gnt_style_get_from_name@Base 1:2.4.0 - gnt_style_get_string_list@Base 1:2.4.0 - gnt_style_parse_bool@Base 1:2.4.0 - gnt_style_read_actions@Base 1:2.4.0 - gnt_style_read_configure_file@Base 1:2.4.0 - gnt_style_read_menu_accels@Base 1:2.4.0 - gnt_style_read_workspaces@Base 1:2.4.0 - gnt_styles_get_keyremaps@Base 1:2.4.0 - gnt_text_format_flag_to_chtype@Base 1:2.4.0 - gnt_text_view_append_text_with_flags@Base 1:2.4.0 - gnt_text_view_append_text_with_tag@Base 1:2.4.0 - gnt_text_view_attach_editor_widget@Base 1:2.4.0 - gnt_text_view_attach_pager_widget@Base 1:2.4.0 - gnt_text_view_attach_scroll_widget@Base 1:2.4.0 - gnt_text_view_clear@Base 1:2.4.0 - gnt_text_view_get_gtype@Base 1:2.4.0 - gnt_text_view_get_lines_above@Base 1:2.4.0 - gnt_text_view_get_lines_below@Base 1:2.4.0 - gnt_text_view_new@Base 1:2.4.0 - gnt_text_view_next_line@Base 1:2.4.0 - gnt_text_view_scroll@Base 1:2.4.0 - gnt_text_view_set_flag@Base 1:2.4.0 - gnt_text_view_tag_change@Base 1:2.4.0 - gnt_tree_add_choice@Base 1:2.4.0 - gnt_tree_add_row_after@Base 1:2.4.0 - gnt_tree_add_row_last@Base 1:2.4.0 - gnt_tree_adjust_columns@Base 1:2.4.0 - gnt_tree_change_text@Base 1:2.4.0 - gnt_tree_create_row@Base 1:2.4.0 - gnt_tree_create_row_from_list@Base 1:2.4.0 - gnt_tree_get_choice@Base 1:2.4.0 - gnt_tree_get_gtype@Base 1:2.4.0 - gnt_tree_get_parent_key@Base 1:2.4.0 - gnt_tree_get_row_text_list@Base 1:2.4.0 - gnt_tree_get_rows@Base 1:2.4.0 - gnt_tree_get_selection_data@Base 1:2.4.0 - gnt_tree_get_selection_text@Base 1:2.4.0 - gnt_tree_get_selection_text_list@Base 1:2.4.0 - gnt_tree_get_selection_visible_line@Base 1:2.4.0 - gnt_tree_get_visible_rows@Base 1:2.4.0 - gnt_tree_is_searching@Base 1:2.4.0 - gnt_tree_new@Base 1:2.4.0 - gnt_tree_new_with_columns@Base 1:2.4.0 - gnt_tree_remove@Base 1:2.4.0 - gnt_tree_remove_all@Base 1:2.4.0 - gnt_tree_scroll@Base 1:2.4.0 - gnt_tree_set_choice@Base 1:2.4.0 - gnt_tree_set_col_width@Base 1:2.4.0 - gnt_tree_set_column_is_binary@Base 1:2.4.0 - gnt_tree_set_column_is_right_aligned@Base 1:2.4.0 - gnt_tree_set_column_resizable@Base 1:2.4.0 - gnt_tree_set_column_title@Base 1:2.4.0 - gnt_tree_set_column_titles@Base 1:2.4.0 - gnt_tree_set_column_visible@Base 1:2.4.0 - gnt_tree_set_column_width_ratio@Base 1:2.4.0 - gnt_tree_set_compare_func@Base 1:2.4.0 - gnt_tree_set_expanded@Base 1:2.4.0 - gnt_tree_set_hash_fns@Base 1:2.4.0 - gnt_tree_set_row_color@Base 1:2.4.0 - gnt_tree_set_row_flags@Base 1:2.4.0 - gnt_tree_set_search_column@Base 1:2.4.0 - gnt_tree_set_search_function@Base 1:2.4.0 - gnt_tree_set_selected@Base 1:2.4.0 - gnt_tree_set_show_separator@Base 1:2.4.0 - gnt_tree_set_show_title@Base 1:2.4.0 - gnt_tree_set_visible_rows@Base 1:2.4.0 - gnt_tree_sort_row@Base 1:2.4.0 - gnt_uninit_colors@Base 1:2.4.0 - gnt_uninit_styles@Base 1:2.4.0 - gnt_util_get_text_bound@Base 1:2.4.0 - gnt_util_onscreen_fit_string@Base 1:2.4.0 - gnt_util_onscreen_width@Base 1:2.4.0 - gnt_util_onscreen_width_to_pointer@Base 1:2.4.0 - gnt_util_parse_widgets@Base 1:2.4.0 - gnt_util_parse_xhtml_to_textview@Base 1:2.4.0 - gnt_util_set_trigger_widget@Base 1:2.4.0 - gnt_widget_activate@Base 1:2.4.0 - gnt_widget_bindings_view@Base 1:2.4.0 - gnt_widget_clicked@Base 1:2.4.0 - gnt_widget_confirm_size@Base 1:2.4.0 - gnt_widget_destroy@Base 1:2.4.0 - gnt_widget_draw@Base 1:2.4.0 - gnt_widget_expose@Base 1:2.4.0 - gnt_widget_get_gtype@Base 1:2.4.0 - gnt_widget_get_name@Base 1:2.4.0 - gnt_widget_get_position@Base 1:2.4.0 - gnt_widget_get_size@Base 1:2.4.0 - gnt_widget_has_focus@Base 1:2.4.0 - gnt_widget_has_shadow@Base 1:2.4.0 - gnt_widget_hide@Base 1:2.4.0 - gnt_widget_key_pressed@Base 1:2.4.0 - gnt_widget_queue_update@Base 1:2.4.0 - gnt_widget_set_focus@Base 1:2.4.0 - gnt_widget_set_name@Base 1:2.4.0 - gnt_widget_set_position@Base 1:2.4.0 - gnt_widget_set_size@Base 1:2.4.0 - gnt_widget_set_take_focus@Base 1:2.4.0 - gnt_widget_set_urgent@Base 1:2.4.0 - gnt_widget_set_visible@Base 1:2.4.0 - gnt_widget_show@Base 1:2.4.0 - gnt_widget_size_request@Base 1:2.4.0 - gnt_window_box_new@Base 1:2.4.0 - gnt_window_get_accel_item@Base 1:2.4.0 - gnt_window_get_gtype@Base 1:2.4.0 - gnt_window_get_maximize@Base 1:2.4.0 - gnt_window_new@Base 1:2.4.0 - gnt_window_present@Base 1:2.4.0 - gnt_window_set_maximize@Base 1:2.4.0 - gnt_window_set_menu@Base 1:2.4.0 - gnt_window_workspace_hiding@Base 1:2.4.0 - gnt_window_workspace_showing@Base 1:2.4.0 - gnt_wm_add_workspace@Base 1:2.4.0 - gnt_wm_copy_win@Base 1:2.4.0 - gnt_wm_get_gtype@Base 1:2.4.0 - gnt_wm_get_idle_time@Base 1:2.4.0 - gnt_wm_move_window@Base 1:2.4.0 - gnt_wm_new_window@Base 1:2.4.0 - gnt_wm_process_click@Base 1:2.4.0 - gnt_wm_process_input@Base 1:2.4.0 - gnt_wm_raise_window@Base 1:2.4.0 - gnt_wm_resize_window@Base 1:2.4.0 - gnt_wm_set_event_stack@Base 1:2.4.0 - gnt_wm_set_workspaces@Base 1:2.4.0 - gnt_wm_switch_workspace@Base 1:2.4.0 - gnt_wm_switch_workspace_next@Base 1:2.4.0 - gnt_wm_switch_workspace_prev@Base 1:2.4.0 - gnt_wm_update_window@Base 1:2.4.0 - gnt_wm_widget_find_workspace@Base 1:2.4.0 - gnt_wm_widget_move_workspace@Base 1:2.4.0 - gnt_wm_window_close@Base 1:2.4.0 - gnt_wm_window_decorate@Base 1:2.4.0 - gnt_ws_add_widget@Base 1:2.4.0 - gnt_ws_draw_taskbar@Base 1:2.4.0 - gnt_ws_get_gtype@Base 1:2.4.0 - gnt_ws_get_name@Base 1:2.4.0 - gnt_ws_hide@Base 1:2.4.0 - gnt_ws_new@Base 1:2.4.0 - gnt_ws_remove_widget@Base 1:2.4.0 - gnt_ws_set_name@Base 1:2.4.0 - gnt_ws_show@Base 1:2.4.0 - gnt_ws_widget_hide@Base 1:2.4.0 - gnt_ws_widget_show@Base 1:2.4.0 libpurple-client.so.0 libpurple0 #MINVER# PURPLE_BLIST_NODE_HAS_FLAG@Base 1:2.2.0 PURPLE_BLIST_NODE_IS_BUDDY@Base 1:2.2.0 @@ -2543,3 +2245,56 @@ purple_xfers_init@Base 1:2.2.0 purple_xfers_set_ui_ops@Base 1:2.2.0 purple_xfers_uninit@Base 1:2.2.0 + serv_add_deny@Base 1:2.5.1-0ubuntu1 + serv_add_permit@Base 1:2.5.1-0ubuntu1 + serv_alias_buddy@Base 1:2.5.1-0ubuntu1 + serv_chat_invite@Base 1:2.5.1-0ubuntu1 + serv_chat_leave@Base 1:2.5.1-0ubuntu1 + serv_chat_send@Base 1:2.5.1-0ubuntu1 + serv_chat_whisper@Base 1:2.5.1-0ubuntu1 + serv_get_info@Base 1:2.5.1-0ubuntu1 + serv_got_alias@Base 1:2.5.1-0ubuntu1 + serv_got_attention@Base 1:2.5.1-0ubuntu1 + serv_got_chat_in@Base 1:2.5.1-0ubuntu1 + serv_got_chat_invite@Base 1:2.5.1-0ubuntu1 + serv_got_chat_left@Base 1:2.5.1-0ubuntu1 + serv_got_im@Base 1:2.5.1-0ubuntu1 + serv_got_joined_chat@Base 1:2.5.1-0ubuntu1 + serv_got_typing@Base 1:2.5.1-0ubuntu1 + serv_got_typing_stopped@Base 1:2.5.1-0ubuntu1 + serv_join_chat@Base 1:2.5.1-0ubuntu1 + serv_move_buddy@Base 1:2.5.1-0ubuntu1 + serv_reject_chat@Base 1:2.5.1-0ubuntu1 + serv_rem_deny@Base 1:2.5.1-0ubuntu1 + serv_rem_permit@Base 1:2.5.1-0ubuntu1 + serv_send_attention@Base 1:2.5.1-0ubuntu1 + serv_send_file@Base 1:2.5.1-0ubuntu1 + serv_send_im@Base 1:2.5.1-0ubuntu1 + serv_send_typing@Base 1:2.5.1-0ubuntu1 + serv_set_info@Base 1:2.5.1-0ubuntu1 + serv_set_permit_deny@Base 1:2.5.1-0ubuntu1 + xmlnode_copy@Base 1:2.5.1-0ubuntu1 + xmlnode_free@Base 1:2.5.1-0ubuntu1 + xmlnode_from_str@Base 1:2.5.1-0ubuntu1 + xmlnode_get_attrib@Base 1:2.5.1-0ubuntu1 + xmlnode_get_attrib_with_namespace@Base 1:2.5.1-0ubuntu1 + xmlnode_get_child@Base 1:2.5.1-0ubuntu1 + xmlnode_get_child_with_namespace@Base 1:2.5.1-0ubuntu1 + xmlnode_get_data@Base 1:2.5.1-0ubuntu1 + xmlnode_get_data_unescaped@Base 1:2.5.1-0ubuntu1 + xmlnode_get_namespace@Base 1:2.5.1-0ubuntu1 + xmlnode_get_next_twin@Base 1:2.5.1-0ubuntu1 + xmlnode_get_prefix@Base 1:2.5.1-0ubuntu1 + xmlnode_insert_child@Base 1:2.5.1-0ubuntu1 + xmlnode_insert_data@Base 1:2.5.1-0ubuntu1 + xmlnode_new@Base 1:2.5.1-0ubuntu1 + xmlnode_new_child@Base 1:2.5.1-0ubuntu1 + xmlnode_remove_attrib@Base 1:2.5.1-0ubuntu1 + xmlnode_remove_attrib_with_namespace@Base 1:2.5.1-0ubuntu1 + xmlnode_set_attrib@Base 1:2.5.1-0ubuntu1 + xmlnode_set_attrib_with_namespace@Base 1:2.5.1-0ubuntu1 + xmlnode_set_attrib_with_prefix@Base 1:2.5.1-0ubuntu1 + xmlnode_set_namespace@Base 1:2.5.1-0ubuntu1 + xmlnode_set_prefix@Base 1:2.5.1-0ubuntu1 + xmlnode_to_formatted_str@Base 1:2.5.1-0ubuntu1 + xmlnode_to_str@Base 1:2.5.1-0ubuntu1 dh_makeshlibs: command returned error code 512 make: *** [binary-fixup/libpurple0] Error 1 dpkg-buildpackage: failure: fakeroot debian/rules binary gave error exit status 2 pbuilder: Failed autobuilding of package -> Aborting with an error
The above is a diff between the symbols found with dpkg-gensymbols and the debian/libpurple0.symbols file.
We can notice that none of the libgnt libs are being found and dpkg-gensymbols is suggesting we remove them. ('-' in front of them). Additionally, it has found some symbols that are now in libpurple0 that are not included in our libpurple0.symbols file and we should add them. ('+' in front of them).
The version number of the symbol files shows the minimum version of the library that this symbol should be available. It has to start somewhere. So if this package never had a .symbols file - dpkg-gensymbols would find a whole bunch and suggest we add them. They then become 2.5.1. The idea would be that we know, these symbols are in 2.5.1. If we use pidgin 2.5.5 when it is released and it has a new libpurple0 package and new symbols (functions) are added, we would then put the version we discovered them in into the .symbols file.
Debian has a handy feature that has seeded all the symbol versions (This should be mostly applicable to Ubuntu also - so if are are starting your .symbols file and dont have any historic symbol information - that may be a good starting point)
http://qa.debian.org/cgi-bin/mole/seedsymbols
The '-' for all the libgnt symbols reports the libgnt is not in the libpurple package. I suggest this is an error as I could find no where where libgnt was ever included with libpurple, but rather it is included in finch.
Please note - Normally dpkg-gensymbols report a '-' for symbols is incorrect and upstream has made a messup in there ABI. They should release a new SONAME to fix this if they are removing symbols. Symbols should normally only be added to '+' if the SONAME is remaining the same. (In our example the libgnt symbols were incorrectly added to libpurple0.symbols hence it was being removed).
I created a debian/finch.symbols and added them to that. I also removed all of the libgnt from debian/libpurple0.symbols. (libgnt is built when finch is built).
The other thing i did was remove the -0ubuntu1 from the version of the symbol, as it is not really important to us that is specifically 0ubuntu1 - rather we are interested in the upstream base version where the symbol was introduced.
Fixing the {libpurple0,finch}.symbols file and building now shows no errors with dh_makeshlibs, but dh_shlibdeps now reports many errors of the following:
dpkg-shlibdeps: warning: symbol gnt_text_view_scroll used by debian/finch/usr/lib/finch/gntlastlog.so found in none of the libraries.
What this is saying is that the symbol 'gnt_text_view_scroll' used by the ELF binary associated with finch '/usr/lib/finch/gntlastlog.so' was found in none of the libraries that that .so program is linked against.
Normally, we would have a library that gntlastlog.so is linked against that contains that symbol we require. We see this linking by doing
objdump -p /usr/lib/finch/gntlastlog.so
We then see the following
/usr/lib/finch/gntlastlog.so: file format elf32-i386 Program Header: LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12 filesz 0x00001060 memsz 0x00001060 flags r-x LOAD off 0x00001ec0 vaddr 0x00002ec0 paddr 0x00002ec0 align 2**12 filesz 0x00000228 memsz 0x00000234 flags rw- DYNAMIC off 0x00001ed4 vaddr 0x00002ed4 paddr 0x00002ed4 align 2**2 filesz 0x00000110 memsz 0x00000110 flags rw- STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2 filesz 0x00000000 memsz 0x00000000 flags rw- RELRO off 0x00001ec0 vaddr 0x00002ec0 paddr 0x00002ec0 align 2**0 filesz 0x00000140 memsz 0x00000140 flags r-- Dynamic Section: NEEDED libgobject-2.0.so.0 NEEDED libgmodule-2.0.so.0 NEEDED libgthread-2.0.so.0 NEEDED librt.so.1 NEEDED libglib-2.0.so.0 NEEDED libnsl.so.1 NEEDED libresolv.so.2 NEEDED libpthread.so.0 NEEDED libc.so.6 SONAME gntlastlog.so INIT 0x000007c0 FINI 0x00000f68 HASH 0x000000d4 GNU_HASH 0x00000198 STRTAB 0x000003b4 SYMTAB 0x000001d4 STRSZ 0x0000027d SYMENT 0x00000010 PLTGOT 0x00002ff4 PLTRELSZ 0x000000a8 PLTREL 0x00000011 JMPREL 0x00000718 REL 0x000006a0 RELSZ 0x00000078 RELENT 0x00000008 VERNEED 0x00000670 VERNEEDNUM 0x00000001 VERSYM 0x00000632 RELCOUNT 0x0000000b Version References: required from libc.so.6: 0x09691f73 0x00 03 GLIBC_2.1.3 0x0d696910 0x00 02 GLIBC_2.0
We are concentrating on the NEEDED and SONAME sections.
We can see in the NEEDED section that the place where the symbol name it requires is not linked against this .so file. We would expect that it should be linked against libgnt.so.0 if it was a library - but in reality this is a plugin that is loaded by libgnt.
The fact this this file contains an SONAME indicates to dh_shlibdeps that it is a library and should be linked - but this is actually a false positive and the plugin will actually be called by the application source with a dlopen.
In theory a plugin has no SONAME but most of them have due to libtool limitations. You can identify a plugin by the way it's linked in the final application.
objdump -p /usr/bin/finch Dynamic Section: NEEDED libgstreamer-0.10.so.0 NEEDED libgnt.so.0 NEEDED libncursesw.so.5 NEEDED libpurple.so.0 NEEDED libgobject-2.0.so.0 NEEDED libgthread-2.0.so.0 NEEDED libglib-2.0.so.0 NEEDED libpthread.so.0 NEEDED libc.so.6
We can see libgnt.so.0 is a library as it is linked by the final application. We do not see a call for gntlastlog.so even although it has a SONAME - we can assume it is a plugin.
man dpkg-shlibdeps man dpkg-gensymbols
gives more information and also an explanation of warnings / possible errors.
http://wiki.debian.org/UsingSymbolsFiles
is a general webpage regarding the use of .symbol files.
Thanks to persia (Emmet Hikory) and buxy (Raphael Hertzog) for their assistance in helping me trying to understand this.
Some of the information was taken from https://wiki.ubuntu.com/MOTU/School/LibraryPackaging by sistpoty (Stefan Potyra) & slangasek ( Steve Langasek)
stefanlsd/dpkg-gensymbols (last edited 2008-11-02 15:12:51 by 196)