Building GnuTLS 3.0.9 on MS-Windows

Eli Zaretskii eliz at gnu.org
Sat Jan 7 14:41:07 CET 2012


About a week ago, I've built GnuTLS 3.0.9 on MS-Windows using MinGW
GCC-based development environment and MSYS shell and tools (the latter
are needed for having Bash and related programs necessary to run Unix
shell scripts such as `configure' and `libtool').

This message is a report on the problems I found.  Some of them might
be Windows-specific, but I think that at least some are not.

I see that versions 3.0.10 and 3.0.11 were released since then.
Therefore, it could be that some of the problems below are already
fixed.  (I've read the announcements, but the changes and bugfixes
they cited didn't seem to be related to any of the problems below.)

Here's the description of the problems I bumped into.

Problem #1: Compilation fails in lib/accelerated/x86:

     make[4]: Entering directory `/d/usr/eli/utils/gnutls-3.0.9/lib/accelerated/x86'
     /bin/sh ../../../libtool  --tag=CC --tag=CC  --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../../..  -I./../../../gl -I./../../../gl -I./../../includes -I./../../includes -I./../../ -I./../ -I./../../minitasn1 -I/d/usr/include     -DASM_X86_32 -DASM_X86 -g -O2 -MT sha-padlock.lo -MD -MP -MF .deps/sha-padlock.Tpo -c -o sha-padlock.lo sha-padlock.c
     libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../../.. -I./../../../gl -I./../../../gl -I./../../includes -I./../../includes -I./../../ -I./../ -I./../../minitasn1 -I/d/usr/include -DASM_X86_32 -DASM_X86 -g -O2 -MT sha-padlock.lo -MD -MP -MF .deps/sha-padlock.Tpo -c sha-padlock.c  -DDLL_EXPORT -DPIC -o .libs/sha-padlock.o
     sha-padlock.c:24:24: gnutls_int.h: No such file or directory
     sha-padlock.c:25:29: gnutls_hash_int.h: No such file or directory
     sha-padlock.c:26:27: gnutls_errors.h: No such file or directory
     In file included from ./aes-padlock.h:5,
		      from sha-padlock.c:30:
     ./aes-x86.h:24: error: syntax error before "size_t"
     ./aes-x86.h:28: error: syntax error before "size_t"

   followed by many more error messages.

   This happens because no -I flag points to the ../../../lib
   directory, where the headers live.

   I solved this by adding -I$(top_builddir)/lib to DEFAULT_INCLUDES
   in .../x86/Makefile.in:

     DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir) -I$(top_builddir)/lib

   (The actual change should probably be to AM_CPPFLAGS in
   Makefile.am, but I didn't have Automake installed to do that.)

Problem #2: Creation of libgnutlsxx.la produces a warning:

     make[1]: Entering directory `/d/usr/eli/utils/gnutls-3.0.9/lib'
     /bin/sh ../libtool  --tag=CXX   --mode=link g++ -I./includes -I./includes -g -O2 -no-undefined -version-info 28:0:0 -Wl,--version-script=./libgnutlsxx.map  -o libgnutlsxx.la -rpath /d/usr/lib libgnutlsxx_la-gnutlsxx.lo libgnutls.la

     *** Warning: This system can not link to static lib archive libgnutls.la.
     *** I have the capability to make that library automatically link in when
     *** you link to this library.  But I can only do this if you have a
     *** shared version of the library, which you do not appear to have.
     Creating library file: .libs/libgnutlsxx.dll.a

   followed by a gazillion of "undefined reference" errors.

   My analysis of this was that it is impossible to build both static
   and dynamic libraries on Windows in the same build.  If that is
   true, then the `configure' script should be modified to not try
   that by default; the default should probably build only the dynamic
   libraries.

   In any case, configuring with

     ./configure --build=i686-pc-mingw32 --prefix=/d/usr --disable-shared

   succeeds and produces a static library libgnutls.a (but not before
   bumping into a couple of more problems, described below).

Problem #3: The linker fails in src/:

       CC     udp-serv.o
     udp-serv.c: In function `udp_server':
     udp-serv.c:107: warning: implicit declaration of function `usleep'
       CC     common.o
       CC     p11common.o
       CCLD   gnutls-serv.exe
     udp-serv.o(.text+0x417): In function `udp_server':
     d:/usr/eli/utils/gnutls-3.0.9/src/udp-serv.c:107: undefined reference to `usleep'

   This is because there's no `usleep' on Windows in the standard
   libraries.  I solved this by adding an implementation of `usleep'
   to udp_serv.c, which is the only source file that needs it.

   Let me know if you want me to send a patch with that
   implementation.

Problem #4: Linker fails in src/:

       CC     serv.o
     serv.c: In function `human_addr':
     serv.c:620: warning: implicit declaration of function `getnameinfo'
     serv.c: In function `listen_socket':
     serv.c:697: warning: implicit declaration of function `getaddrinfo'
     serv.c:776: warning: implicit declaration of function `freeaddrinfo'
       CC     common.o
       CC     p11common.o
       CCLD   gnutls-serv.exe
     serv.o(.text+0x369): In function `human_addr':
     d:/usr/eli/utils/gnutls-3.0.9/src/serv.c:620: undefined reference to `getnameinfo'
     serv.o(.text+0x3cb):d:/usr/eli/utils/gnutls-3.0.9/src/serv.c:633: undefined reference to `getnameinfo'
     serv.o(.text+0x617): In function `listen_socket':
     d:/usr/eli/utils/gnutls-3.0.9/src/serv.c:697: undefined reference to `getaddrinfo'
     serv.o(.text+0x7ce):d:/usr/eli/utils/gnutls-3.0.9/src/serv.c:776: undefined reference to `freeaddrinfo'

   This happens because the prototypes of getnameinfo and getaddrinfo
   (actually, their #define's to w32 API functions) in ws2tcpip.h are
   not visible in w32api headers unless _WIN32_WINNT >= 0x0501.  (The
   fallback implementation provided by MS in wspapi.h is not available
   for MinGW.)

   My solution was to set _WIN32_WINNT on the Make command line:

     make DEFS='-DHAVE_CONFIG_H -D_WIN32_WINNT=0x0501'

   However, I believe that the build on Windows should set
   _WIN32_WINNT by default, since that's the only way to build GnuTLS
   with MinGW, AFAICS.

Problem #5: Compilation of doc/printlist.c fails:

     make[4]: Entering directory `/d/usr/eli/utils/gnutls-3.0.9/doc'
     gcc -std=gnu99 -g -O2 -I/d/usr/include   printlist.c   -o printlist
     printlist.c:21:20: config.h: No such file or directory
     printlist.c:25:27: gnutls/gnutls.h: No such file or directory
     printlist.c:26:25: gnutls/x509.h: No such file or directory
     printlist.c:27:28: gnutls/openpgp.h: No such file or directory
     printlist.c: In function `main_texinfo':
     printlist.c:49: error: `gnutls_kx_algorithm_t' undeclared (first use in this function)
     printlist.c:49: error: (Each undeclared identifier is reported only once
     printlist.c:49: error: for each function it appears in.)
     printlist.c:49: error: syntax error before "kx"
     printlist.c:50: error: `gnutls_cipher_algorithm_t' undeclared (first use in this function)
     printlist.c:51: error: `gnutls_mac_algorithm_t' undeclared (first use in this function)
     printlist.c:52: error: `gnutls_protocol_t' undeclared (first use in this function)
     printlist.c:58: warning: implicit declaration of function `gnutls_cipher_suite_info'

   and many more similar errors.

   The reason is that doc/Makefile.in used a literal "printlist"
   without $(EXEEXT), and therefore Make invokes default rules to
   build programs.  My solution was to edit Makefile.in to add the
   missing $(EXEEXT).

Problem #6: Failure to compile crywrap:

     Making all in crywrap
     make[3]: Entering directory `/d/usr/eli/utils/gnutls-3.0.9/src/crywrap'
       CC     crywrap.o
     crywrap.c:36:17: grp.h: No such file or directory
     crywrap.c:40:17: pwd.h: No such file or directory
     crywrap.c:49:22: sys/wait.h: No such file or directory
     crywrap.c:50:20: syslog.h: No such file or directory
     In file included from crywrap.c:59:
     crywrap.h:66: error: syntax error before "in_port_t"
     crywrap.h:66: warning: no semicolon at end of struct or union
     crywrap.h:66: warning: no semicolon at end of struct or union
     crywrap.h:68: error: syntax error before '}' token
     crywrap.h:68: warning: type defaults to `int' in declaration of `rpl_listen'
     crywrap.h:68: error: 'rpl_listen' redeclared as different kind of symbol
     ./../../gl/sys/socket.h:775: error: previous declaration of 'rpl_listen' was here
     crywrap.h:68: error: 'rpl_listen' redeclared as different kind of symbol
     ./../../gl/sys/socket.h:775: error: previous declaration of 'rpl_listen' was here

   and many more similar errors.

   Crywrap is completely non-portable to Windows and cannot possibly
   compile with MinGW.  I think the Windows build should simply skip
   it, as it is an non-essential component of GnuTLS.

The rest of the problems are related to the test suite.

Problem #7: "make check" fails in `tests' while compiling test
programs:

     make[2]: Entering directory `/d/usr/eli/utils/gnutls-3.0.9/tests'
     /bin/sh ../libtool  --tag=CC   --mode=link gcc -std=gnu99   -g -O2 -no-install
     -o mini-deflate.exe mini-deflate.o ../lib/libgnutls.la ../gl/libgnu.la libutils.la  -lws2_32
     libtool: link: gcc -std=gnu99 -g -O2 -o mini-deflate.exe mini-deflate.o  ../lib/.libs/libgnutls.a -L/d/usr/lib -lnettle -lhogweed /d/usr/lib/libgmp.dll.a -lz -Ld:/usr/lib /d/usr/lib/libp11-kit.dll.a ../gl/.libs/libgnu.a /d/usr/lib/libintl.dll.a /d/usr/lib/libiconv.dll.a ./.libs/libutils.a -lws2_32 -L/d/usr/lib -L/d/usr/lib
     ./.libs/libutils.a(utils.o)(.text+0x2b): In function `fail':
     d:/usr/eli/utils/gnutls-3.0.9/tests/utils.c:51: undefined reference to `rpl_vsnprintf'
     ./.libs/libutils.a(utils.o)(.text+0x9b): In function `success':
     d:/usr/eli/utils/gnutls-3.0.9/tests/utils.c:66: undefined reference to `rpl_vsnprintf'
     collect2: ld returned 1 exit status
     make[2]: *** [mini-deflate.exe] Error 1
     make[2]: Leaving directory `/d/usr/eli/utils/gnutls-3.0.9/tests'
     make[1]: *** [check-am] Error 2
     make[1]: Leaving directory `/d/usr/eli/utils/gnutls-3.0.9/tests'
     make: *** [check-recursive] Error 1

   This happens because tests/Makefile.in does not add libgnu.a after
   libutils.a, which obviously needs it, at least on systems whose
   vsnprintf is replaced by gnulib's one.  My solution was to add the
   missing library:

     LDADD = ../lib/libgnutls.la \
	     ../gl/libgnu.la \
	     libutils.la \
	     ../gl/libgnu.la \       <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	     $(LTLIBGCRYPT)	\
	     $(LIBSOCKET) $(INET_NTOP_LIB) $(INET_PTON_LIB)

Problem #8: Compilation of tests/openpgp-auth2.c fails:

       CC     openpgp-auth2.o
     openpgp-auth2.c:36:22: sys/wait.h: No such file or directory
     openpgp-auth2.c: In function `doit':
     openpgp-auth2.c:82: warning: implicit declaration of function `socketpair'
     openpgp-auth2.c:86: warning: implicit declaration of function `alloca'
     openpgp-auth2.c:96: warning: implicit declaration of function `fork'
     openpgp-auth2.c:232: warning: implicit declaration of function `wait'
     openpgp-auth2.c:239: warning: implicit declaration of function `WIFEXITED'
     openpgp-auth2.c:241: warning: implicit declaration of function `WEXITSTATUS'
     openpgp-auth2.c:244: warning: implicit declaration of function `WIFSIGNALED'
     openpgp-auth2.c:245: warning: implicit declaration of function `WTERMSIG'
     make[2]: *** [openpgp-auth2.o] Error 1
     make[2]: Leaving directory `/d/usr/eli/utils/gnutls-3.0.9/tests'
     make[1]: *** [check-am] Error 2
     make[1]: Leaving directory `/d/usr/eli/utils/gnutls-3.0.9/tests'
     make: *** [check-recursive] Error 1

   This test program cannot be built on Windows, as it uses facilities that
   are not available (fork, wait, WTERMSIG etc.).  This test should be
   skipped on MS-Windows.

Problem #9: Compilation of tests/slow/gendh.c fails:

     make  gendh.exe keygen.exe cipher-test.exe
     make[1]: Entering directory `/d/usr/eli/utils/gnutls-3.0.9/tests/slow'
     gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../..  -I../../lib/includes -I../../lib/includes -I../../tests/ -I/d/usr/include   -g -O2 -MT gendh.o -MD -MP -MF .deps/gendh.Tpo -c -o gendh.o gendh.c
     gendh.c:29:19: utils.h: No such file or directory
     gendh.c: In function `doit':
     gendh.c:34: error: `gnutls_dh_params_t' undeclared (first use in this function)
     gendh.c:34: error: (Each undeclared identifier is reported only once
     gendh.c:34: error: for each function it appears in.)
     gendh.c:34: error: syntax error before "dh_params"
     gendh.c:37: warning: implicit declaration of function `gnutls_global_init'
     gendh.c:39: warning: implicit declaration of function `fail'
     gendh.c:41: warning: implicit declaration of function `gnutls_dh_params_init'
     gendh.c:41: error: `dh_params' undeclared (first use in this function)
     gendh.c:44: warning: implicit declaration of function `gnutls_dh_params_generate2'
     gendh.c:47: warning: implicit declaration of function `success'
     make[1]: *** [gendh.o] Error 1
     make[1]: Leaving directory `/d/usr/eli/utils/gnutls-3.0.9/tests/slow'
     make: *** [check-am] Error 2

   This happens because GCC, at least on Windows, doesn't like
   trailing slashes in the directories mention in the -I switch.
   Solution: remove the slash:

     AM_CPPFLAGS = \
	     -I$(top_srcdir)/lib/includes		\
	     -I$(top_builddir)/lib/includes \
	     -I$(top_srcdir)/tests/  <<<<<<<<<<<<<<<<<<<

Lastly, there were several warning messages that, although they seem
harmless, are perhaps an evidence that some Windows-specific cleanups
are needed; I think a clean build without warnings goes a long way
towards building user's confidence that the build is successful.

Here are these warnings:

       CCLD   gnutls-serv.exe
     Info: resolving _nettle_arcfour_crypt by linking to __imp__nettle_arcfour_crypt (auto-import)

(there were a lot of these in many places).  I understand that this
means the linker resolved a function by linking against a DLL, but
perhaps some compiler or linker switch could prevent these warnings
from being emitted in the first place.

Another group of warnings looked like this:

       CCLD   libexamples.la
     libtool: link: warning: `-no-install' is ignored for i686-pc-mingw32
     libtool: link: warning: assuming `-no-fast-install' instead

   and many similar ones.

   Only by digging deep inside libtool did I understand that this is
   probably harmless, as Windows indeed does not support -no-install.
   But I think the build should avoid using -no-install on Windows by
   default.

This is all.  Hope this will be useful.

Last, but certainly not least: thank you for developing and
maintaining GnuTLS!




More information about the Gnutls-devel mailing list