Discussion:
Problems using relocatable on Win32
Reuben Thomas
2017-12-09 17:13:16 UTC
Permalink
I recently had a bug report https://github.com/AbiWord/enchant/issues/172
for a use of relocatable-lib-lgpl on Win32 which had some problems. After
investigation, there are a couple of ways in which either my understanding
of how to use relocatable is deficient, or there's a bug in relocatable.

1. For use in a library, relocatable.c should be built with IN_LIBRARY
defined. The documentation (relocatable-maint.texi) says to add
-DIN_LIBRARY to the defines for the library which is being made
relocatable. Unfortunately, I wrote that documentation, and it appears to
be a misunderstanding. The problem is that relocatable.c is compiled as
part of gnulib, not as part of the gnulib-using library, so it doesn't see
this define.

Presumably, relocatable should be built and linked into each library and
program that uses it, as the way it needs to be built depends on the
context (whether it is being used with a library or not, the setting of
INSTALLDIR etc.). But as things stand, relocatable.c is compiled once and
added to libgnu.a.

2. To get the correct path at which the library is installed, INSTALLDIR is
defined. First, we have the same problem as above: where should INSTALLDIR
be defined so that its definition is seen at compile time? But there's a
further problem: on Win32, DLLs are installed to bindir, not libdir, so
INSTALLDIR needs a different definition. Is there a suitable variable that
points to "where the shared library will be installed"? (I presume this
only makes sense for shared libraries: one can't have a relocatable static
library!)

Help? Am I just using relocatable wrong? Or is there a problem/limitation
here? (At least in my current case, I only want to use relocatable once, so
just working out how to pass the correct INSTALLDIR (bindir or libdir) and
-DIN_LIBRARY to the compilation of relocatable.c in gnulib would be
sufficient.)
--
https://rrt.sc3d.org
Bruno Haible
2017-12-09 19:59:57 UTC
Permalink
Hello Reuben,
Post by Reuben Thomas
1. For use in a library, relocatable.c should be built with IN_LIBRARY
defined. The documentation (relocatable-maint.texi) says to add
-DIN_LIBRARY to the defines for the library which is being made
relocatable. Unfortunately, I wrote that documentation, and it appears to
be a misunderstanding. The problem is that relocatable.c is compiled as
part of gnulib, not as part of the gnulib-using library, so it doesn't see
this define.
You'll need two different invocations of gnulib-tool, I'd say:
- one for the library which is being made relocatable,
here use module 'relocatable-lib-lgpl' and define -DIN_LIBRARY in
Makefile.am (*),
- one for the code that makes use of this library,
here use module 'relocatable-prog' and do not define -DIN_LIBRARY
but do define INSTALLDIR (only needed if you also define
ENABLE_COSTLY_RELOCATABLE there).

(*) In order to achieve this, use a hand-written Makefile.am that 'include's
a gnulib-tool generated Makefile.gnulib (gnulib-tool option
--makefile-name=Makefile.gnulib). For an example, see [1].
Post by Reuben Thomas
2. To get the correct path at which the library is installed, INSTALLDIR is
defined. First, we have the same problem as above: where should INSTALLDIR
be defined so that its definition is seen at compile time?
Define INSTALLDIR in the DEFS or AM_CPPFLAGS of the Makefile.am that covers
the compilation of the .c files that invoke set_program_name (after including
progname.h).

If you want ENABLE_COSTLY_RELOCATABLE, define INSTALLDIR also in the
Makefile.am of the directory of the second gnulib-tool invocation mentioned
above.
Post by Reuben Thomas
But there's a
further problem: on Win32, DLLs are installed to bindir, not libdir, so
INSTALLDIR needs a different definition.
In gettext, where all programs get installed in $(bindir), I use the definition
-DINSTALLDIR=\"$(bindir)\"

Where does $(libdir) come into play?
Post by Reuben Thomas
Is there a suitable variable that
points to "where the shared library will be installed"?
Ah, you have a relocatable library that depends on another relocatable library?

Bruno

[1] http://git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=gettext-tools/libgettextpo/Makefile.am
Reuben Thomas
2017-12-09 20:44:24 UTC
Permalink
On 9 December 2017 at 19:59, Bruno Haible <***@clisp.org> wrote:

​[snip]

Thanks very much for the method. Presumably this is effectively missing
documentation? (You haven't suggested that I'm doing something unexpected.)​
Post by Bruno Haible
Post by Reuben Thomas
But there's a
further problem: on Win32, DLLs are installed to bindir, not libdir, so
INSTALLDIR needs a different definition.
In gettext, where all programs get installed in $(bindir), I use the definition
-DINSTALLDIR=\"$(bindir)\"
Where does $(libdir) come into play?
​Because I am using relocatable-lib, so it is the library that is trying to
find resources relative to itself.​
Post by Bruno Haible
Ah, you have a relocatable library that depends on another relocatable library?
​I have a relocatable library that depends on files in pkgdatadir.​
--
https://rrt.sc3d.org
Reuben Thomas
2017-12-09 22:25:21 UTC
Permalink
Post by Reuben Thomas
​I have a relocatable library that depends on files in pkgdatadir.​
​So, the shared library calls relocate. relocate tries to compute
curr_prefix_better, using get_shared_library_fullname. This will have a
prefix of libdir (or bindir on Win32). This is why I am setting INSTALLDIR
to libdir (but need bindir on Win32).
--
https://rrt.sc3d.org
Bruno Haible
2017-12-10 01:48:32 UTC
Permalink
Hi Reuben,
​I have a relocatable library that depends on files in pkgdatadir.​
​So, the shared library calls relocate. relocate tries to compute
curr_prefix_better, using get_shared_library_fullname. This will have a
prefix of libdir (or bindir on Win32). This is why I am setting INSTALLDIR
to libdir (but need bindir on Win32).
Oh, I see. Yes, after reading the code I confirm your finding:

INSTALLDIR should be defined

1) for the code in the relocatable library (only needed if
ENABLE_COSTLY_RELOCATABLE is not defined to 0). Its value should
be a C string that contains (for a shared library) the installation directory
of the shared library; often this will be $(libdir) on Unix excluding Cygwin,
or $(bindir) on Windows or Cygwin.

2) for the code that makes use of the relocatable library, that is, that invokes
set_program_name. Its value should be a C string that contains the installation
directory of the program; often this will be $(bindir).

Bruno
Reuben Thomas
2017-12-10 08:31:26 UTC
Permalink
Post by Bruno Haible
Hi Reuben,
Post by Reuben Thomas
Post by Reuben Thomas
​I have a relocatable library that depends on files in pkgdatadir.​
​So, the shared library calls relocate. relocate tries to compute
curr_prefix_better, using get_shared_library_fullname. This will have a
prefix of libdir (or bindir on Win32). This is why I am setting
INSTALLDIR
Post by Reuben Thomas
to libdir (but need bindir on Win32).
INSTALLDIR should be defined
1) for the code in the relocatable library (only needed if
ENABLE_COSTLY_RELOCATABLE is not defined to 0). Its value should
be a C string that contains (for a shared library) the installation directory
of the shared library; often this will be $(libdir) on Unix excluding Cygwin,
or $(bindir) on Windows or Cygwin.
2) for the code that makes use of the relocatable library, that is, that invokes
set_program_name. Its value should be a C string that contains the installation
directory of the program; often this will be $(bindir).
Thanks very much for the confirmation. For case 1, am I correct in thinking
there is no variable that contains this directory, i.e. "the directory
where shared libraries are installed"? As far as I can tell, this
directory is computed by libtool, and I can't see a better way than
effectively recomputing it, that is, use bindir when the platform is
cygwin, mingw or cegcc, and libdir otherwise.
--
https://rrt.sc3d.org
Bruno Haible
2017-12-10 12:33:49 UTC
Permalink
Post by Reuben Thomas
For case 1, am I correct in thinking
there is no variable that contains this directory, i.e. "the directory
where shared libraries are installed"? As far as I can tell, this
directory is computed by libtool, and I can't see a better way than
effectively recomputing it, that is, use bindir when the platform is
cygwin, mingw or cegcc, and libdir otherwise.
Correct. You need to define it by yourself. An Automake conditional
based on "$host_os" will do the trick.

AM_CONDITIONAL([SHLIBS_IN_BINDIR], [case "$host_os" in mingw* | cygwin*) true;; *) false;; esac])

if SHLIBS_IN_BINDIR
AM_CPPFLAGS += -DINSTALLDIR=\"$(bindir)\"
else
AM_CPPFLAGS += -DINSTALLDIR=\"$(libdir)\"
endif

Bruno
Reuben Thomas
2017-12-11 10:32:24 UTC
Permalink
Post by Bruno Haible
Post by Reuben Thomas
For case 1, am I correct in thinking
there is no variable that contains this directory, i.e. "the directory
where shared libraries are installed"? As far as I can tell, this
directory is computed by libtool, and I can't see a better way than
effectively recomputing it, that is, use bindir when the platform is
cygwin, mingw or cegcc, and libdir otherwise.
Correct. You need to define it by yourself. An Automake conditional
based on "$host_os" will do the trick.
AM_CONDITIONAL([SHLIBS_IN_BINDIR], [case "$host_os" in mingw* | cygwin*)
true;; *) false;; esac])
if SHLIBS_IN_BINDIR
AM_CPPFLAGS += -DINSTALLDIR=\"$(bindir)\"
else
AM_CPPFLAGS += -DINSTALLDIR=\"$(libdir)\"
endif
​Thanks for this, which I have incorporated into a patch for the
relocatable documentation, attached, along with a minor patch to use better
tags in a couple of cases in gnulib.texi.
--
https://rrt.sc3d.org
Reuben Thomas
2017-12-11 11:25:04 UTC
Permalink
Post by Reuben Thomas
​Thanks for this, which I have incorporated into a patch for the
relocatable documentation, attached, along with a minor patch to use better
tags in a couple of cases in gnulib.texi.
​I noticed that of course the AM_CONDITIONAL goes in configure.ac, so
updated patch attached.
--
https://rrt.sc3d.org
Bruno Haible
2017-12-11 13:19:22 UTC
Permalink
Hi Reuben,
​Thanks for this, which I have incorporated into a patch for the
relocatable documentation, attached, along with a minor patch to use better
tags in a couple of cases in gnulib.texi.
​I noticed that of course the AM_CONDITIONAL goes in configure.ac, so
updated patch attached.
Thanks. Applied, with a typo fix:
@code{COSTLY_RELOCATABLE} -> @code{ENABLE_COSTLY_RELOCATABLE}

Bruno

Bruno Haible
2017-12-10 01:16:02 UTC
Permalink
Hi Reuben,
Post by Reuben Thomas
Thanks very much for the method. Presumably this is effectively missing
documentation?
The recommendation to use 2 gnulib-tool invocations is documented in
section "Using Gnulib for both a library and a binary" [1].

The trick to use --makefile-name in order to add some tweaks is
currently undocumented. It would deserve to be documented, somewhere
in chapter "Invoking gnulib-tool".

Bruno

[1] https://www.gnu.org/software/gnulib/manual/html_node/Multiple-instances.html
Bruno Haible
2017-12-10 15:33:01 UTC
Permalink
Hi Reuben,
Post by Bruno Haible
The trick to use --makefile-name in order to add some tweaks is
currently undocumented. It would deserve to be documented
I've now added this documentation.

Also a doc tweak: The opposite term for "library" is "program", not "binary".
Libraries exist as source as a binaries (.a and .so files), like programs.

Bruno
Reuben Thomas
2017-12-11 10:21:59 UTC
Permalink
Post by Bruno Haible
Hi Reuben,
Post by Bruno Haible
The trick to use --makefile-name in order to add some tweaks is
currently undocumented. It would deserve to be documented
I've now added this documentation.
​Thanks very much. I had prepared a patch for this (not submitted), but
yours is much better.​
--
https://rrt.sc3d.org
Continue reading on narkive:
Loading...