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