Discussion:
Why configure failed to search libws2_32.a in MinGW+MSYS ?
Guo Leaveye
2013-12-27 08:58:27 UTC
Permalink
I am porting a library and some utils from linux to windows.

My build PC is a Windows 7, with MSYS+MinGW installed in both D:\MinGW (first choice) and C:\MinGW (installer default).

Given a short WinSock program source _testlib.c_ here:

/* testlib.c */
#include <stdio.h>
#include <windows.h>
#include <winsock2.h>
int main( void ) {
printf( "%d\n", WSAGetLastError() );
return 0;
}

Directly compile of the testlib.c goes just fine. So I think the MSYS+MinGW works well. To simulate the autotools' progress, I tried that compile to testlib.o and then link the execution. It works too.

$ gcc -c -o testlib.o testlib.c && gcc -o out testlib.o -lws2_32 && ls -l out*
-rwxr-xr-x 1 Administrator Administrators 48899 Dec 27 16:27 out.exe

After that, I turn it into autotools:

# configure.ac
AC_PREREQ([2.61])
AC_INIT([testlib], [0.0.0], [<***@a.bc>])
AM_INIT_AUTOMAKE([-Wall foreign])
AC_PROG_CC
AC_CHECK_LIB([ws2_32], [WSAGetLastError])
AC_CHECK_LIB([libws2_32], [WSAGetLastError])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

# Makefile.am
noinst_PROGRAMS = out
out_SOURCES = testlib.c

Note that, in the configure.ac file, I check both ws2_32 and libws2_32 to confirm the library file name rules.
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.exe
checking for suffix of executables... .exe
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for WSAGetLastError in -lws2_32... no
checking for WSAGetLastError in -llibws2_32... no
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
Note that, (1) both library libws2_32.a check report `no', and (2) the compiler is exactly my simulation target `gcc'.

I know that I can add a check into configure.ac to examine whether building in mingw or cygwin, but is this checking supposed to be fully examination for the real build environment ? If it works fine, LIB variable should be full filled with all required library link options. If there a simple way by adjust my MSYS+MinGW environment to make autoconf works, please tell me.

Regards.

Levi G.
Haskell is a beautiful language.
Warren Young
2013-12-27 19:46:24 UTC
Permalink
Care to post your config.log so someone doesn't have to dummy up a whole
project just to test this for you?
Keith Marshall
2013-12-27 20:47:50 UTC
Permalink
Post by Guo Leaveye
/* testlib.c */
#include <stdio.h>
#include <windows.h>
#include <winsock2.h>
I'm astonished that this works! If you include winsock2.h, then you
either should *not* include windows.h, or you should ensure that you
include winsock2.h first. (Microsoft document the former option, but
not the latter; their documented alternative, if you need to include
both headers, is to define WIN32_LEAN_AND_MEAN, before you include either).
Post by Guo Leaveye
int main( void ) {
printf( "%d\n", WSAGetLastError() );
return 0;
}
Directly compile of the testlib.c goes just fine. So I think the MSYS+MinGW works well. To simulate the autotools' progress, I tried that compile to testlib.o and then link the execution. It works too.
$ gcc -c -o testlib.o testlib.c && gcc -o out testlib.o -lws2_32 && ls -l out*
-rwxr-xr-x 1 Administrator Administrators 48899 Dec 27 16:27 out.exe
See above; I'm surprised that it works, as you've shown your example,
but with correct usage, there should be no problem.
Post by Guo Leaveye
# configure.ac
. . .
AC_PROG_CC
AC_CHECK_LIB([ws2_32], [WSAGetLastError])
AC_CHECK_LIB([libws2_32], [WSAGetLastError])
This simply *cannot* work as you hope. See, WSAGetLastError() is a
__stdcall function, which requires the appropriate headers to have been
included at compile time, to get the correct __stdcall qualification of
the symbol references for the linker. IIRC, AC_CHECK_LIB deliberately
omits the headers, providing a dummy prototype instead; this is only
suitable for __cdecl functions, so failure to detect libws2_32.a must
always be the expected outcome here.

Normal practice for Windows ports is to simply assume that the requisite
libraries are always present. If you feel that you really need to test
for it, either just check for availability of the header, and assume
that is always accompanied by the requisite library, or you must write a
custom AC_LINK_IFELSE test; AC_CHECK_LIB will not be of much use to you
here.
--
Regards,
Keith.
Bob Friesenhahn
2013-12-27 23:18:53 UTC
Permalink
Post by Guo Leaveye
checking dependency style of gcc... gcc3
checking for WSAGetLastError in -lws2_32... no
checking for WSAGetLastError in -llibws2_32... no
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
Note that, (1) both library libws2_32.a check report `no', and (2) the compiler is exactly my simulation target `gcc'.
I know that I can add a check into configure.ac to examine whether building in mingw or cygwin, but is this checking supposed to be fully examination for the real build environment ? If it works fine, LIB variable should be full filled with all required library link options. If there a simple way by adjust my MSYS+MinGW environment to make autoconf works, please tell me.
Look in the generated config.log for the errors produced while testing
for WSAGetLastError. The errors may provide a clue as to what has
actually gone wrong and lead to fixing the problem. Autoconf tests
for library functions by linking a small test program. Sometimes it
is necessary to supply additional libraries in order to successfully
link with a library.

Bob
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Guo Leaveye
2013-12-28 04:15:26 UTC
Permalink
Thanks a lot for your tip.

Acoording to the log file, it just compiles a source code like this, I only keep the lines matters.

char WSAGetLastError ();
int
main ()
{
return WSAGetLastError ();
}

When compiling this simple source, GCC reports a error that "undefined reference to `WSAGetLastError'", even though there is a linker option "-lws2_32". I tried to replace the declaration of WSAGetLastError() with includes of windows.h and winsock2.h, then it works. I have no idea on this behaviour, that why linking the same library leads different result. Is there any advice ?

BTW, here is the error output by GCC with option "-v".
$ gcc -o out.exe -g -O2 testlib.c -lws2_32 -v
specs
COLLECT_GCC=D:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/lto-wrapper.exe
mingw32
../gcc-4.6.2/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions -
-with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --en
able-version-specific-runtime-libs --build=mingw32 --prefix=/mingw
win32
gcc 4.6.2 (GCC)
COLLECT_GCC_OPTIONS='-o' 'out.exe' '-g' '-O2' '-v' '-mtune=i386' '-march=i386'
d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/cc1.exe -quiet -v -iprefix d:\mingw\bin\../lib/gcc/mingw3
2/4.6.2/ testlib.c -quiet -dumpbase testlib.c -mtune=i386 -march=i386 -auxbase testlib -g -O2 -versi
on -o C:\Users\ADMINI~1\AppData\Local\Temp\cc6Urmwg.s
GNU C (GCC) 4.6.2 (mingw32)
GNU C 4.6.2 GMP 5.0.1MPFR 2.4.1MPC 0.8.1
GGC --param ggc-min-expand=100 --param ggc-min-heapsize=131072
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/../../../../mingw32/include
d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.6.2/include
/mingw/lib/gcc/mingw32/4.6.2/../../../../include
d:/mingw/lib/gcc/../../include
d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.6.2/include-fixed
d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.6.2/../../../../mingw32/include
/mingw/include
#include "..."
#include <...>
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/include
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/../../../../include
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/include-fixed
GNU C (GCC) 4.6.2 (mingw32)
GNU C 4.6.2 GMP 5.0.1MPFR 2.4.1MPC 0.8.1
GGC --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c20aed7c018482d7b62efcd5dcab2a9d
COLLECT_GCC_OPTIONS='-o' 'out.exe' '-g' '-O2' '-v' '-mtune=i386' '-march=i386'
d:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/as.exe -o C:\Users\ADMINI~1\AppData\L
ocal\Temp\ccFvAZop.o C:\Users\ADMINI~1\AppData\Local\Temp\cc6Urmwg.s
COMPILER_PATH=d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/;d:/mingw/bin/../libexec/gcc/;d:/mingw/bin/.
./lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/
LIBRARY_PATH=d:/mingw/bin/../lib/gcc/mingw32/4.6.2/;d:/mingw/bin/../lib/gcc/;d:/mingw/bin/../lib/gcc
/mingw32/4.6.2/../../../../mingw32/lib/;d:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../;/mingw/lib/
COLLECT_GCC_OPTIONS='-o' 'out.exe' '-g' '-O2' '-v' '-mtune=i386' '-march=i386'
d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/collect2.exe -Bdynamic -o out.exe d:/mingw/bin/../lib/gcc
/mingw32/4.6.2/../../../crt2.o d:/mingw/bin/../lib/gcc/mingw32/4.6.2/crtbegin.o -Ld:/mingw/bin/../li
b/gcc/mingw32/4.6.2 -Ld:/mingw/bin/../lib/gcc -Ld:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mi
ngw32/lib -Ld:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../.. -L/mingw/lib C:\Users\ADMINI~1\AppData\Lo
cal\Temp\ccFvAZop.o -lws2_32 -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshe
ll32 -luser32 -lkernel32 -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt d:/mingw/bin/../lib/
gcc/mingw32/4.6.2/crtend.o
d:\Projects\libisl\build/testlib.c:22: undefined reference to `WSAGetLastError'
collect2: ld 1
Regards.

Levi G.
Haskell is a beautiful language.
Look in the generated config.log for the errors produced while testing for WSAGetLastError. The errors may provide a clue as to what has actually gone wrong and lead to fixing the problem. Autoconf tests for library functions by linking a small test program. Sometimes it is necessary to supply additional libraries in order to successfully link with a library.
Bob
--
Bob Friesenhahn
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Václav Zeman
2013-12-28 08:00:15 UTC
Permalink
Post by Guo Leaveye
Thanks a lot for your tip.
Acoording to the log file, it just compiles a source code like this, I only keep the lines matters.
char WSAGetLastError ();
int
main ()
{
return WSAGetLastError ();
}
When compiling this simple source, GCC reports a error that "undefined reference to `WSAGetLastError'", even though there is a linker option "-lws2_32". I tried to replace the declaration of WSAGetLastError() with includes of windows.h and winsock2.h, then it works. I have no idea on this behaviour, that why linking the same library leads different result. Is there any advice ?
The problem here is that without including windows.h or winsock2.h the
compiler does not see the function declaration and the one declaration
it supplies is wrong for the function. It is wrong because Win32 API is
using the stdcall calling convention which means the function name is
So, instead of using AC_CHECK_LIB, you will need to craft something of
your own that will add the headers includes to the test source.
--
VZ
Guo Leaveye
2013-12-30 03:04:28 UTC
Permalink
I have found the answer, and another question still here.

I have tried `gcc -E' (only preprocessed) on the #include version, and checked the output source to view the WSAGetLastError()'s declaration. Then I know this is a conflict between cdecl and stddecl.

As google says (http://lists.gnu.org/archive/html/autoconf/2006-01/msg00109.html), there is no standard macro to handle the stddecl checking.

So before a set of stddecl-checking macros creates, to check the build envionment may be the easiest way to check the libraries' existance.

And the question is that, is there any open sourced 3rd-party macros to handle this ?

Levi G.
Haskell is a beautiful language.
Post by Guo Leaveye
Thanks a lot for your tip.
Acoording to the log file, it just compiles a source code like this, I only keep the lines matters.
char WSAGetLastError ();
int
main ()
{
return WSAGetLastError ();
}
When compiling this simple source, GCC reports a error that "undefined reference to `WSAGetLastError'", even though there is a linker option "-lws2_32". I tried to replace the declaration of WSAGetLastError() with includes of windows.h and winsock2.h, then it works. I have no idea on this behaviour, that why linking the same library leads different result. Is there any advice ?
BTW, here is the error output by GCC with option "-v".
$ gcc -o out.exe -g -O2 testlib.c -lws2_32 -v
specs
COLLECT_GCC=D:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/lto-wrapper.exe
mingw32
../gcc-4.6.2/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions -
-with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --en
able-version-specific-runtime-libs --build=mingw32 --prefix=/mingw
win32
gcc 4.6.2 (GCC)
COLLECT_GCC_OPTIONS='-o' 'out.exe' '-g' '-O2' '-v' '-mtune=i386' '-march=i386'
d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/cc1.exe -quiet -v -iprefix d:\mingw\bin\../lib/gcc/mingw3
2/4.6.2/ testlib.c -quiet -dumpbase testlib.c -mtune=i386 -march=i386 -auxbase testlib -g -O2 -versi
on -o C:\Users\ADMINI~1\AppData\Local\Temp\cc6Urmwg.s
GNU C (GCC) 4.6.2 (mingw32)
GNU C 4.6.2 GMP 5.0.1MPFR 2.4.1MPC 0.8.1
GGC --param ggc-min-expand=100 --param ggc-min-heapsize=131072
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/../../../../mingw32/include
d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.6.2/include
/mingw/lib/gcc/mingw32/4.6.2/../../../../include
d:/mingw/lib/gcc/../../include
d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.6.2/include-fixed
d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.6.2/../../../../mingw32/include
/mingw/include
#include "..."
#include <...>
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/include
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/../../../../include
d:\mingw\bin\../lib/gcc/mingw32/4.6.2/include-fixed
GNU C (GCC) 4.6.2 (mingw32)
GNU C 4.6.2 GMP 5.0.1MPFR 2.4.1MPC 0.8.1
GGC --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c20aed7c018482d7b62efcd5dcab2a9d
COLLECT_GCC_OPTIONS='-o' 'out.exe' '-g' '-O2' '-v' '-mtune=i386' '-march=i386'
d:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/as.exe -o C:\Users\ADMINI~1\AppData\L
ocal\Temp\ccFvAZop.o C:\Users\ADMINI~1\AppData\Local\Temp\cc6Urmwg.s
COMPILER_PATH=d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/;d:/mingw/bin/../libexec/gcc/;d:/mingw/bin/.
./lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/
LIBRARY_PATH=d:/mingw/bin/../lib/gcc/mingw32/4.6.2/;d:/mingw/bin/../lib/gcc/;d:/mingw/bin/../lib/gcc
/mingw32/4.6.2/../../../../mingw32/lib/;d:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../;/mingw/lib/
COLLECT_GCC_OPTIONS='-o' 'out.exe' '-g' '-O2' '-v' '-mtune=i386' '-march=i386'
d:/mingw/bin/../libexec/gcc/mingw32/4.6.2/collect2.exe -Bdynamic -o out.exe d:/mingw/bin/../lib/gcc
/mingw32/4.6.2/../../../crt2.o d:/mingw/bin/../lib/gcc/mingw32/4.6.2/crtbegin.o -Ld:/mingw/bin/../li
b/gcc/mingw32/4.6.2 -Ld:/mingw/bin/../lib/gcc -Ld:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mi
ngw32/lib -Ld:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../.. -L/mingw/lib C:\Users\ADMINI~1\AppData\Lo
cal\Temp\ccFvAZop.o -lws2_32 -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshe
ll32 -luser32 -lkernel32 -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt d:/mingw/bin/../lib/
gcc/mingw32/4.6.2/crtend.o
d:\Projects\libisl\build/testlib.c:22: undefined reference to `WSAGetLastError'
collect2: ld 1
Regards.
Levi G.
Haskell is a beautiful language.
Guo Leaveye
2013-12-30 08:07:52 UTC
Permalink
As a result/summary of the original question, to make all the elsewhere code simple and as a replacement of AC_CHECK_LIB, I use the autoconf macro like this:

AC_CHECK_HEADER([winsock2.h],
[AC_DEFINE([HAVE_LIBWS2_32], [1], [Define if libws2_32 exists.])
LIBS="-lws2_32 $LIBS"],
[],
[#include <windows.h>])

Which suppose that a build environment should have installed a libws2_32.a in case of winsock2.h can be founded in default include directories.

Levi G.
Haskell is a beautiful language.
Post by Guo Leaveye
I have found the answer, and another question still here.
I have tried `gcc -E' (only preprocessed) on the #include version, and checked the output source to view the WSAGetLastError()'s declaration. Then I know this is a conflict between cdecl and stddecl.
As google says (http://lists.gnu.org/archive/html/autoconf/2006-01/msg00109.html), there is no standard macro to handle the stddecl checking.
So before a set of stddecl-checking macros creates, to check the build envionment may be the easiest way to check the libraries' existance.
And the question is that, is there any open sourced 3rd-party macros to handle this ?
Levi G.
Haskell is a beautiful language.
Loading...