bug-gnulib
[Top][All Lists]
Advanced

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

libunistring: Fix build on Windows, when a libunistring is installed


From: Bruno Haible
Subject: libunistring: Fix build on Windows, when a libunistring is installed
Date: Sun, 23 Apr 2023 17:24:03 +0200

On a mingw system, with libunistring-1.0 installed as a DLL, I see
this warning and error when building a testdir of all of Gnulib:

../../gllib/uninorm/nfc.c:25:41: warning: 'uninorm_nfc' redeclared without 
dllimport attribute: previous dllimport ignored [-Wattributes]
 const struct unicode_normalization_form uninorm_nfc =
                                         ^~~~~~~~~~~
../../gllib/uninorm/nfc.c:30:5: error: initializer element is not constant
     &uninorm_nfd
     ^
../../gllib/uninorm/nfc.c:30:5: note: (near initialization for 
'uninorm_nfc.decomposing_variant')
make[4]: *** [Makefile:10784: uninorm/nfc.o] Error 1

Both the warning and the error are caused by the installed <uninorm.h> file,
that declares all variables with attribute '__declspec(dllimport)'.

This is just a small symptom of a bigger problem.


Recall that '__declspec(dllimport)' is meant for accessing functions or
variables defined in DLLs, see
<https://learn.microsoft.com/en-us/cpp/build/importing-into-an-application-using-declspec-dllimport?view=msvc-170>
For functions, this marker is just a micro-optimization; libunistring does not
use it. But for variables, it is needed, depending in situation. And
we need to use it if and only if it is needed, because:

  * If we use dllimport although it is not needed, we might get a
    compilation error such as the above:
      ../../gllib/uninorm/nfc.c:30:5: error: initializer element is not constant
  * If we don't use dllimport although it is needed, we get link errors
    (at least with MSVC), such as:
      unresolved external symbol UC_CATEGORY_Zs


Now assume a system where a libunistring 1.0 is installed (as a shared library),
and the user compiles a program that uses the Gnulib modules
unictype/property-space, unictype/property-soft-dotted, libunistring-optional.

Since the two modules have this version info:

property-space:gl_LIBUNISTRING_MODULE([0.9.8], [unictype/property-space])
property-soft-dotted:gl_LIBUNISTRING_MODULE([1.1], 
[unictype/property-soft-dotted])

Gnulib should arrange the configuration such that
  - The code for property-space comes from the installed libunistring.
    This is the variable UC_PROPERTY_SPACE, and it must be declared *with*
    __declspec(dllimport).
  - The code for property-soft-dotted comes from the included gnulib parts.
    This is the variable UC_PROPERTY_SOFT_DOTTED, and it must be declared
    *without* __declspec(dllimport).

So, although both UC_PROPERTY_SPACE and UC_PROPERTY_SOFT_DOTTED are declared
in the same file unictype.h, they must get different treatment regarding
dllimport. So, the current approach that declares all these variables with
LIBUNISTRING_DLL_VARIABLE is wrong.

This patch provides a fix.


2023-04-23  Bruno Haible  <bruno@clisp.org>

        libunistring: Fix build on Windows, when a libunistring is installed.
        * lib/unicase.in.h: Include <unistring/woe32dll.h>.
        (unicase_empty_prefix_context, unicase_empty_suffix_context): Declare
        with GNULIB_UNICASE_..._DLL_VARIABLE.
        * lib/unictype.in.h: Include <unistring/woe32dll.h>.
        (UC_CATEGORY_*, UC_PROPERTY_*): Declare with
        GNULIB_UNICTYPE_..._DLL_VARIABLE.
        * lib/uninorm.in.h: Include <unistring/woe32dll.h>.
        (unicode_normalization_form uninorm_nf*): Declare with
        GNULIB_UNINORM_..._DLL_VARIABLE.
        * m4/libunistring-base.m4 (gl_LIBUNISTRING_MODULE_WITH_VARIABLE): New
        macro.
        (gl_LIBUNISTRING_LIB_PREPARE): Set HAVE_UNISTRING_WOE32DLL_H.
        * m4/unicase_h.m4: New file.
        * m4/unictype_h.m4: New file.
        * m4/uninorm_h.m4: New file.
        * modules/unicase/base (Files): Add m4/unicase_h.m4.
        (configure.ac): Bump version number. Invoke gl_UNICASE_H,
        gl_UNICASE_H_REQUIRE_DEFAULTS.
        (Makefile.am): Substitute all GNULIB_UNICASE_*_DLL_VARIABLE.
        * modules/unicase/empty-*-context (configure.ac): Invoke
        gl_UNICASE_H_REQUIRE_DEFAULTS. Use gl_LIBUNISTRING_MODULE_WITH_VARIABLE.
        * modules/unictype/base (Files): Add m4/unictype_h.m4.
        (configure.ac): Bump version number. Invoke gl_UNICTYPE_H,
        gl_UNICTYPE_H_REQUIRE_DEFAULTS.
        (Makefile.am): Substitute all GNULIB_UNICTYPE_*_DLL_VARIABLE.
        * modules/unictype/category-* (configure.ac): Invoke
        gl_UNICTYPE_H_REQUIRE_DEFAULTS. Use
        gl_LIBUNISTRING_MODULE_WITH_VARIABLE.
        * modules/unictype/property-* (configure.ac): Likewise.
        * modules/uninorm/base (Files): Add m4/uninorm_h.m4.
        (configure.ac): Bump version number. Invoke gl_UNINORM_H,
        gl_UNINORM_H_REQUIRE_DEFAULTS.
        (Makefile.am): Substitute all GNULIB_UNINORM_*_DLL_VARIABLE.
        * modules/uninorm/nf* (configure.ac): Invoke
        gl_UNINORM_H_REQUIRE_DEFAULTS. Use gl_LIBUNISTRING_MODULE_WITH_VARIABLE.

Attachment: 0001-libunistring-Fix-build-on-Windows-when-a-libunistrin.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]