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)

-- CategoryPackagingGuide

stefanlsd/dpkg-gensymbols (last edited 2008-11-02 15:12:51 by stefanlsd)