Discussion:
Installing gnulib headers with project
Charlie Sale
2018-01-04 03:06:25 UTC
Permalink
Hello gnulib!

Currently, I am working on a project that is a development library that
uses gnulib's lists as a core part of the project.

I include one of the gnulib headers in one of my own header files that I
install. The issue with this is that the gnulib header is not installed
along with my project. Is there a way that I can install a gnulib header
file with the rest of my project's installation? Thanks for you help!

Charlie
--
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQENBFpKrgwBCADaPosQdy9rTpDmGp7y+m7QCW3w3AGtPgoBRJVwuXyOnRp/Q8Xg
jMaQF17GmRgy54+eZJJV5vQNrXAvTo7hX5lAjNTu0EawPE53zQZ7CFGT8YEjlJ8j
PYh5Tp02ckQxZQOZqyIQS2w2CqCZYhSeq2l50pNA2Rutxd2an1DBzdH/1zBnY5qo
r+8N5MgNBcvjgaWiT8kAefHHlD+ssWygg1yVUzxHbOoLWRi24o0mKn6a24fP5EHr
uZXfsoC1Vrhb8RjyftXw0DPFavx6Zi7VIHv68MB/aBVEtMHisCyHlfnqFTMcgKWh
hV5ZC5OR7ELNhNZ82+BoTVH5oA5bD5Hi9tklABEBAAG0J0NoYXJsaWUgU2FsZSA8
c29mdHdhcmVzYWxlMDFAZ21haWwuY29tPokBOAQTAQIAIgUCWkquDAIbAwYLCQgH
AwIGFQgCCQoLBBYCAwECHgECF4AACgkQjFElWoJ7azJvjgf/TtI2/F7xPRUzPaTi
opGbkPXgZMDrRCXK58NQMmUHXmLAwMx2MbfKOhu0hXvZw5ITlkN++bZyXZTiHLwf
fGU5BvtXFKoO8YcZtfbzsUSs3O31hNAuaEm3jwUR1LnoBYJk0Rv1/fnJKdwsUKO9
EvVRSv7CbQh3TLN1aH4RhUAf6NSvDiqv0AwKxceIZsRBf8AbsodlNpxZPay82M2X
YRMyv4sqbeLycXXqOxZMS8BGvzG1O0MobnJ7r/AsqAUUBQrHMEVhpaQgdJ4DMLDl
8KgaynN9vw6/hzl6HkeGHjk2BeUhQZ5Uae++Ot20q1+1b9SHv8YNmnC3PixXGz1G
nFyZ0bkBDQRaSq4MAQgAxWdDdccMwoKmaT6icAJGeFg3sNlgqJ8pF9sK6/QtObUl
fq/MQl2PLP5GjoH1rx8ptms7w3QeTEMJJZweSKD6Fot3R1mQ5mxkxIpR/t/5hS+n
WfqFM+Ri8Va51vBZetTge21ynKac1O1ZGIA2ySKPGexW/ouAWnpZIasmQ0LWnryh
aFNEB9ND0Eork6xjptXRGcBb98trCeiQAc4bffgHpC945f483dScdIcu192QAcY+
J9PAw8eY824s4stx8+Mvu3aaFb7SZEgAPN3WXgjMBY0jysxstAqfxxv78tHCt7uU
AOMRE2pS5nzbEcKakB2VuB4eRFVNb9Qk5Ogw+0wOGQARAQABiQEfBBgBAgAJBQJa
Sq4MAhsMAAoJEIxRJVqCe2sy/r4IAJl96tBtsk2y90J7oT1Z4KIW9zL/2lj//4FY
OU5MbGBMocmzSaosNIZDOQphzvJZGHtxpfp4WkZEU+5wi4n6OqAXoE9Uc8qKImfY
L7FXhRnnXpVuFZOpau/fSijKa5xpoGStBUE3rBm7l+U/FQqsXmmErij1EMcEu8fl
Qu2iFb1elkbticZMcczdAHPpNOwSffnhwx/sOsSqGmw0L+FgMkrnuOIpzMHhjKEC
6n63wBQG3IMNzMyUbsL35p7sz6pn8yk+WUB+NFFrIUbxlDMzRJg73ZZoivELBZik
KWTQS9fP5aQBXz5eNM7KE8v/+BIaNw4dG1i7pZKiFz5qGOkR8M0=
=0Ueh
-----END PGP PUBLIC KEY BLOCK-----
Bruno Haible
2018-01-04 09:22:24 UTC
Permalink
Hi,
Post by Charlie Sale
Is there a way that I can install a gnulib header
file with the rest of my project's installation?
The answer is different for POSIX headers and for utility module headers.

* In all cases, when you install such a header file, rename it.
Rationale: Another package than yours may want to install the same
gnulib header file. But the other package will likely use a different
version of gnulib than your package. Bad things will happen if your
package uses the other package's version of the gnulib header file, and
vice versa.

* For POSIX header replacements, you should normally avoid to install
gnulib-provided header files.
Rationale:
- These header files represent workarounds which change over time.
- These header files are tailored for a particular compiler, but the
user of your public header files may be using a different compiler.
- A good library API design means that your public header files use
types that are independent of the interface between your library
and libc or the kernel.
However, in some cases, you want to use <stdint.h> files. This is hairy.
Look how it's done in GNU libunistring.
http://git.savannah.gnu.org/gitweb/?p=libunistring.git;a=blob;f=lib/Makefile.am
Alternatively, prefix the types: use my_uint32_t instead of uint32_t etc.

* For utility module headers (such as the gl_list.h in your case).
I would try to get away without it, by presenting a purely functional API
(rather than a data-oriented API). For example, instead of having a function
gl_list_t my_foo (arg_t);
define a type
typedef struct foo_iterator *foo_iterator_t;
and functions
foo_iterator_t my_foo (arg_t);
void foo_iterator_free (foo_iterator_t);
foo foo_iterator_next (foo_iterator_t);
void foo_insert (foo_iterator_t, foo);
Rationale: The API of a shared library is easier to evolve without bumping
the shared library major version number if the API is in such a functional
style.
Other than that, you *can* use a renamed gl_list.h in a public API. Just, be
prepared to bump the shared library major version number more often. [1]

Bruno

[1] https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
Bruno Haible
2018-01-05 14:04:38 UTC
Permalink
I do implement a purely functional API with my project. A gl_list_t is
never used by the user
and is instead wrapped inside of a structure defined by me. All API
functions operate on said
data structure instead of using a gl_list_t structure.
Good, fine.
My problem is that the header file in which this data type is defined
includes gl_list.h. When I try
removing this include statement, the gl_list_t type is undeclared and
throws and error.
There are at least two ways to solve it:

a) Put the declaration of the data type in a private header file.
E.g. foo.h:
struct foo;
int bar (struct foo *);
foo-private.h:
#include <foo.h>
#include "gl_list.h"
struct foo { ...; gl_list_t member; ... };

b) Use 'struct gl_list_impl *' instead of gl_list_t, since that what it really
is.
E.g. foo.h:
struct gl_list_impl;
struct foo { ...; struct gl_list_impl * member; ... };
int bar (struct foo *);
foo-private.h:
#include <foo.h>
#include "gl_list.h"

Bruno

Loading...