[GRASS5] Library Issues

I've been analysing the interdependencies between the various GRASS
libraries, and wished to discuss some of the results.

1. The following symbols are referenced in libimage_sup.a, but don't
appear to be defined anywhere:

  symbol |object
  -------------------+-------------
  mark_control |photo_init.o
  Menu_msg |ltm_anal.o
  Menu_msg |photo_anal.o
  Menu_msg |poly_anal.o
  read_elev |ltm_anal.o
  read_elev |ltm_trans.o
  read_elev |photo_anal.o
  read_elev |photo_trans.o
  select_current_env |convert_ll.o
  select_target_env |convert_ll.o

Can anyone shed any light on this? Are they meant to be defined by the
application? If so, the interface should probably be changed to use an
explicit callback.

There are also a number of undefined symbols in libgeo.a:

  D_ask_driver_raw
  D_clear_driver
  D_cursor_buttons
  D_foot_switch
  D_get_scale
  D_read_raw
  D_setup_driver
  D_setup_origin
  D_start_button

It appears that these are meant to be provided by a "driver" (although
the only implementation which I can find is src.contrib/OTHER/numonics).
Is this the case?

2. A significant number of global symbols are defined in multiple
libraries; in particular, the following are defined in both libortho.a
and libimage_sup.a:

  I_ask_camera_any
  I_ask_camera_new
  I_ask_camera_old
  I_compute_ortho_equations
  I_find_camera
  I_find_initial
  I_get_con_points
  I_get_group_camera
  I_get_group_elev
  I_get_ref_points
  I_inverse_ortho_ref
  I_list_cameras
  I_new_con_point
  I_new_ref_point
  I_ortho_ref
  I_put_con_points
  I_put_group_camera
  I_put_group_elev
  I_put_ref_points
  I_read_con_points
  I_read_ref_points
  I_write_con_points
  I_write_ref_points

The following symbols are also multiply defined:

  symbol |object |library
  ------------+-------------+--------------
  Bugs2 |error.o |libimage_sup.a
  Bugs2 |error.o |libortho.a
  I_georef |georef.o |libI.a
  I_georef |georef.o |libortho.a
  inverse |m_inverse.o |libortho.a
  inverse |inverse.o |libtrans.a
  isnull |isnull.o |libortho.a
  isnull |inverse.o |libtrans.a
  m_add |matrix_ops.o |libimage_sup.a
  m_add |m_add.o |libortho.a
  matrix_error|ref_ortho.o |libimage_sup.a
  matrix_error|orthoref.o |libortho.a
  m_copy |matrix_ops.o |libimage_sup.a
  m_copy |m_copy.o |libortho.a
  m_mult |matrix_ops.o |libimage_sup.a
  m_mult |m_mult.o |libortho.a
  m_mult |m_mult.o |libtrans.a
  transpose |jacobi.o |libgmath.a
  transpose |m_transpose.o|libortho.a

Can someone who is familiar with the imagery code look into the
apparent duplication, and whether it can be eliminated?

The matrix stuff will ultimately be handled by the gmath library.

3. There are three pairs of libraries which are mutually dependent:

  im_lib |ex_lib
  ------------+------------
  libgis.a |libcoorcnv.a
  libstubs.a |libdbmi.a
  libvect.a |libdig2.a

a)
  libgis.a references:
  CC_datum_name
  CC_datum_shift
  CC_get_datum_by_name

  libcoorcnv.a references:
  G_realloc
  G_fatal_error
  G_warning
  G_ellipsoid_name
  G_get_ellipsoid_by_name
  G_get_spheroid_by_name
  G_getl
  G_gisbase
  G_store
  G_strcasecmp
  G_strcat
  G_strcpy
  G_strip

The obvious solution is to move coorcnv/datum.c into libgis.

b)
  libstubs.a references:
  db_procedure_not_implemented

  libdbmi.a references:
  db_driver_add_column
  db_driver_bind_update
  db_driver_close_cursor
  db_driver_close_database
  db_driver_create_database
  db_driver_create_index
  db_driver_create_table
  db_driver_delete
  db_driver_delete_database
  db_driver_describe_table
  db_driver_drop_column
  db_driver_drop_index
  db_driver_drop_table
  db_driver_execute_immediate
  db_driver_fetch
  db_driver_find_database
  db_driver_finish
  db_driver_init
  db_driver_insert
  db_driver_list_databases
  db_driver_list_indexes
  db_driver_list_tables
  db_driver_open_database
  db_driver_open_insert_cursor
  db_driver_open_select_cursor
  db_driver_open_update_cursor
  db_driver_update

I haven't looked very far into this, but libdbmi probably needs to be
split into two separate libraries; a high-level library above the
drivers, which provides the API to clients, and a low-level library
which provides utilities for the drivers.

c)
  libvect.a references:
  dig_alloc_points
  dig_bound_box2
  dig__fill_head_portable
  dig__fread_port_C
  dig__fread_port_D
  dig__fread_port_I
  dig__fread_port_L
  dig__fwrite_port_C
  dig__fwrite_port_D
  dig__fwrite_port_I
  dig__fwrite_port_L
  dig__Init_portable_code
  dig_load_plus
  dig_new_to_old_type
  dig_old_to_new_type
  dig_point_in_poly
  dig__set_cur_in_head
  dig__set_cur_out_head
  dig_struct_copy
  dig_x_Rd_P_area
  dig_x_Rd_P_att
  dig_x_Rd_P_isle
  dig_x_Rd_P_line
  dig_x_Rd_Plus_head
  dig_x_Rd_P_node
  dig_x_Wr_P_area
  dig_x_Wr_P_att
  dig_x_Wr_P_isle
  dig_x_Wr_P_line
  dig_x_Wr_Plus_head
  dig_x_Wr_P_node

  libdig2.a references:
  dig_Rd_P_area
  dig_Rd_P_att
  dig_Rd_P_isle
  dig_Rd_P_line
  dig_Rd_Plus_head
  dig_Rd_P_node
  dig_Wr_P_area
  dig_Wr_P_att
  dig_Wr_P_isle
  dig_Wr_P_line
  dig_Wr_Plus_head
  dig_Wr_P_node
  V2_read_line

What is the distiction between libvect.a and libdig2.a? Should they be
combined? Or is all of this going to be replaced in 5.1?

--
Glynn Clements <glynn.clements@virgin.net>

Glynn,
thanks for the nice analyis.
Unfortunatly I know even less about these libraries then you do.
Unless you can find somebody to explain it to you,
I suggest that you just go ahead and try your best attempt to fix stuff.

If you think that any change might possibly cause a major hickup,
we should leave it for 5.1.x.

  Bernhard

On Fri, Apr 12, 2002 at 11:45:46AM +0100, Glynn Clements wrote:

I've been analysing the interdependencies between the various GRASS
libraries, and wished to discuss some of the results.

On Friday 12 April 2002 12:45 pm, Glynn Clements wrote:

I've been analysing the interdependencies between the various GRASS
libraries, and wished to discuss some of the results.

3. There are three pairs of libraries which are mutually dependent:

  im_lib |ex_lib
  ------------+------------
  libgis.a |libcoorcnv.a
  libstubs.a |libdbmi.a
  libvect.a |libdig2.a

b)
  libstubs.a references:
  db_procedure_not_implemented

  libdbmi.a references:
  db_driver_add_column

...

  db_driver_update

I haven't looked very far into this, but libdbmi probably needs to be
split into two separate libraries; a high-level library above the
drivers, which provides the API to clients, and a low-level library
which provides utilities for the drivers.

We can just move db_procedure_not_implemented() to libstubs.a, it
is used only by other functions in that lib and should not be used
anywhere else.

c)
  libvect.a references:
  dig_alloc_points

...

  libdig2.a references:
  dig_Rd_P_area

This is solved in 5.1, I would not recommend any changes in 5.0.

What is the distiction between libvect.a and libdig2.a? Should they be
combined? Or is all of this going to be replaced in 5.1?

In 5.0 it is more confused, in 5.1 I try to keep in vectlib all higher level
functions used by modules and in diglib all lower level functions like
R/W portable format or low level functions for topology structure
modifications.

Radim

Radim Blazek wrote:

> I've been analysing the interdependencies between the various GRASS
> libraries, and wished to discuss some of the results.

> 3. There are three pairs of libraries which are mutually dependent:
>
> im_lib |ex_lib
> ------------+------------
> libgis.a |libcoorcnv.a
> libstubs.a |libdbmi.a
> libvect.a |libdig2.a

> b)
> libstubs.a references:
> db_procedure_not_implemented
>
> libdbmi.a references:
> db_driver_add_column
...
> db_driver_update
>
> I haven't looked very far into this, but libdbmi probably needs to be
> split into two separate libraries; a high-level library above the
> drivers, which provides the API to clients, and a low-level library
> which provides utilities for the drivers.

We can just move db_procedure_not_implemented() to libstubs.a, it
is used only by other functions in that lib and should not be used
anywhere else.

The above dependency is the reason why I noticed the issue, but then
noticed that dbmi/lib/README says:

  This library contains routines called both by client and drivers.

The issue isn't worth fixing just for libstubs.a. It's only worth
dealing with if the library was going to be fully split into client
and driver libraries, so that you have something like:

                        --> driver --
                       / \
  client --> libdbmi -<---> driver ---+-> libdbmi_drv
                       \ /
                        --> driver --

> c)
> libvect.a references:
> dig_alloc_points
...
> libdig2.a references:
> dig_Rd_P_area

This is solved in 5.1, I would not recommend any changes in 5.0.

OK.

> What is the distiction between libvect.a and libdig2.a? Should they be
> combined? Or is all of this going to be replaced in 5.1?

In 5.0 it is more confused, in 5.1 I try to keep in vectlib all higher level
functions used by modules and in diglib all lower level functions like
R/W portable format or low level functions for topology structure
modifications.

So, in 5.1, vectlib depends upon diglib but diglib no longer depends
upon vectlib?

--
Glynn Clements <glynn.clements@virgin.net>

On Monday 15 April 2002 10:31 am, Glynn Clements wrote:

The above dependency is the reason why I noticed the issue, but then
noticed that dbmi/lib/README says:

  This library contains routines called both by client and drivers.

The issue isn't worth fixing just for libstubs.a. It's only worth
dealing with if the library was going to be fully split into client
and driver libraries, so that you have something like:

                        --> driver --
                       / \
  client --> libdbmi -<---> driver ---+-> libdbmi_drv
                       \ /
                        --> driver --

Sorry, here I don't understand much. Just note that some routines are called
both by client and drivers, then it would be necessary to have 3 libes:
common(shared), for drivers and for clients. I would left it all in one. What
is the problem with one big library?

So, in 5.1, vectlib depends upon diglib but diglib no longer depends
upon vectlib?

Yes.

Radim

Radim Blazek wrote:

> The above dependency is the reason why I noticed the issue, but then
> noticed that dbmi/lib/README says:
>
> This library contains routines called both by client and drivers.
>
> The issue isn't worth fixing just for libstubs.a. It's only worth
> dealing with if the library was going to be fully split into client
> and driver libraries, so that you have something like:
>
> --> driver --
> / \
> client --> libdbmi -<---> driver ---+-> libdbmi_drv
> \ /
> --> driver --

Sorry, here I don't understand much. Just note that some routines are called
both by client and drivers, then it would be necessary to have 3 libes:
common(shared), for drivers and for clients. I would left it all in one. What
is the problem with one big library?

There isn't a problem at present. It may or may not present a problem
for shared libraries. In the worst case, it would just mean that
libdbmi couldn't be built as a shared library.

My original analysis was concerned with library dependencies, which
are an issue for shared libraries. It started from being unable to
build a shared libgis, due to the circular dependency between libgis
and libcoorcnv (coupled with the fact that, as it stood, libgis had
curses as a dependency because of G_edit_{cats,cellhd,history}).

Looking into it further, I found three sets of (apparent) mutual
dependencies, as noted in my original email. As it turns out, the
libdbmi -> libstubs dependency is largely bogus; libstubs just happens
to export many of the functions which libdbmi imports. The more
significant circular dependency is between libdbmi and the individual
drivers. However, the driver functions aren't in a library, so they
didn't show up in the analysis.

In short, I don't think that the dbmi case is particularly important.
libgis has already been fixed, and vectlib/diglib may as well wait for
5.1

--
Glynn Clements <glynn.clements@virgin.net>