RE: Odd behaviour when building on Win32 using MinGW



Espen Harlinn writes:
 > The distributions often uses an old version of libtool - i.e. pre
 > 1.5

The first thing to do then is to run libtoolize --force, aclocal,
automake, autoconf?

 > Write a DllMain function and get the name of the module using the handle
 > passed as an argument to GetModuleFileName and store the result in a
 > global variable and use it to calculate the other paths.

That's what GLib does.

 > Take a look at the makefiles, and you will see the atk for instance
 > wants to know the path to the locale dir as
 > -DATKLOCALEDIR=\""$(atklocaledir)"\" and this is hardcoded in the
 > makefile.

It is hardcoded in the makefile, but not used in the source if on
Win32:

In the gnome-2-2 branch (atk-1.2.x):

2003-06-13  Tor Lillqvist  <tml iki fi>

	* atk/atkobject.c: On Windows, don't use hardcoded ATKLOCALEDIR,
	but deduce it from DLL location, like GLib, GTK etc do.

(In HEAD, that was fixed already on 2003-02-25.)

 > As long as a function is named
 > g_win32_get_package_installation_directory it will never be used by
 > most of the gtk developers since they mostly develop for unix, and
 > will most likely either scorn win32 compability or think that this
 > function should only be used in the win32 port of gtk and apps/libs
 > built on top of that.

But how *could* such a function be written machine-independently and
put in GLib? Say you have some library libfoo, that uses some Makefile
macro FOODATADIR, with value $(prefix)/lib/foo/2.3.

Currently, I would having stuff like this in libfoo/some.c: (code just typed
in now as I write, no guarantee of correctness).

#ifdef G_OS_WIN32
#undef FOODATADIR
#define FOODATADIR get_data_dir()

G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)

static char *
get_data_dir (void)
{
  static char *result = NULL;
  if (result == NULL)
    result = g_strdup_printf ("%s/lib/foo/%d.%d",
      g_win32_get_package_installation_directory (NULL, dll_name),
      FOO_API_MAJOR_VERSION, FOO_API_MINOR_VERSION);

  return result;
}
#endif

And the rest of the some.c code then would use FOODATADIR as before.

Is your suggestion to instead don't use the FOODATADIR in libfoo's
source at all, but call a g_syspath_get_data_directory() function? And
that function wouldn't take any parameters?

How on earth could that function, compiled into GLib, on Unix be able
to return a hardcoded macro from libfoo's makefile? And on Windows,
how can it know *what* DLL's name and location it should use to deduce
libfoo's installation location? Look up its return address from the
stack, find out in what DLL that code is, get a handle for that? Brrr.

A better way might be to define a macro in GLib that would expand *in
each library that uses it* to something like the code snippet
above. Hmm, something that could be used like this:

in libfoo:

G_DEFINE_INSTALLATION_PATH_GETTER (foo_data_dir, FOODATADIR)
   ...
   path = g_strdup_printf ("%s/foo", foo_data_dir());
   ...

The macro would be defined (in some GLib header) something like:

#ifdef G_OS_WIN32
#define G_DEFINE_INSTALLATION_PATH_GETTER (func, hardcoded) \
G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name) \
static char * \
func (void) \
...
#else
#define func() hardcoded
#endif

 > If glib/atk/pango/gtk and so on used this or a similar (possibly
 > extended) set of functions on all platforms instead of the hardcoded
 > stuff from the makefiles,

Well, they do use G_WIN32_DLLMAIN_FOR_DLL_NAME() and
g_win32_get_package_installation_(sub)directory(). Sure, it might be a
good idea to add some macros from GLib instead and use them, to avoid
the ifdefs, as outline above. Patches (to HEAD) welcome...

--tml





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]