Add an autoconf macro to check WINAPI functions
PATCH 1/1 Add an autoconf macro to check WINAPI functions
This adds a macro file with a permissive license. Its small so I don't mind inlining the macro into configure.ac if that is preferred. -------8<--------
Makes configure tests for Windows API neater and consistent.
--- check_symbols_in.m4 | 43 +++++++++++++++++++++++++++++++++++++++++++ configure.ac | 35 +++++++---------------------------- 2 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 check_symbols_in.m4
check_symbols_in.m4 new file +43 -0
@@ -0,0 +1,43 @@ +dnl AX_CHECK_SYMBOL - check for a symbol in specified header files +dnl +dnl Usage: AX_CHECK_SYMBOL_IN(symbol, header [,action-if-found [,action-if-not-found]]) +dnl AX_CHECK_SYMBOLS_IN(symbol..., header [,action-if-found [,action-if-not-found]]) +dnl If the symbol is found define HAVE_SYMBOL (with symbol capitalised) in addition to +dnl running the optional 'action-if-found' +dnl +dnl Works as a complement to AC_CHECK_FUNCS for detecting stdcall +dnl functions or functions renamed in headers. Especially useful +dnl for Windows API +dnl +dnl Copyright (c) 2015 Selva Nair <[email protected]...> +dnl +dnl LICENSE +dnl Copying and distribution of this file, with or without modification, +dnl are permitted in any medium without royalty provided the copyright +dnl notice and this notice are preserved. This file is offered as-is, +dnl without any warranty. +dnl +AC_DEFUN([AX_CHECK_SYMBOL_IN], + [AC_CACHE_CHECK([for $1 in $2], + [AS_TR_SH([ac_cv_have_symbol_$1])], + [AC_TRY_COMPILE([#include <$2>], [(void) $1;], + [eval "AS_TR_SH([ac_cv_have_symbol_$1])=yes"], + [eval "AS_TR_SH([ac_cv_have_symbol_$1])=no"])dnl + ]) +if eval test "x$AS_TR_SH([ac_cv_have_symbol_$1])" = xyes; then + AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1]), [1], + [Define to 1 if you have $1.])dnl + [$3] +else + ifelse([$4], ,[:], [$4]) +fi +])dnl +dnl +dnl check for multiple symbols +dnl Usage: AX_CHECK_SYMBOLS_IN(symbol..., header [,action-if-found [,action-if-not-found]]) +dnl +AC_DEFUN([AX_CHECK_SYMBOLS_IN], [ +for ac_symbol in $1; do + AX_CHECK_SYMBOL_IN([$ac_symbol], [$2], [$3], [$4])dnl +done +])dnl
configure.ac +7 -28
@@ -627,7 +627,8 @@ AC_SUBST([SOCKETS_LIBS]) old_LIBS="${LIBS}" LIBS="${LIBS} ${SOCKETS_LIBS}" AC_CHECK_FUNCS([sendmsg recvmsg]) -# Windows use stdcall for winsock so we cannot auto detect these +# Windows use stdcall for winsock so use AX_CHECK_SYMBOLS_IN to detect these +m4_include(check_symbols_in.m4) m4_define( [SOCKET_FUNCS], [socket recv recvfrom send sendto listen dnl
@@ -638,33 +639,11 @@ m4_define( [setsockopt getsockopt getsockname poll]dnl ) if test "${WIN32}" = "yes"; then -# normal autoconf function checking does not find inet_ntop/inet_pton -# because they need to include the actual header file and link ws2_32.dll - LIBS="${LIBS} -lws2_32" - AC_MSG_CHECKING([for MinGW inet_ntop()/inet_pton()]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include <ws2tcpip.h> - ]], - [[ -int r = (int) inet_ntop (0, NULL, NULL, 0); - r += inet_pton(AF_INET, NULL, NULL); -return r; - ]] - )], - [AC_MSG_RESULT([OK]) - AC_DEFINE([HAVE_INET_NTOP],[1],[MinGW inet_ntop]) - AC_DEFINE([HAVE_INET_PTON],[1],[MinGW inet_pton]) - ], - [AC_MSG_RESULT([not found])] - ) - m4_foreach( - [F], - m4_split(SOCKET_FUNCS SOCKET_OPT_FUNCS), - m4_define([UF], [[m4_join([_], [HAVE], m4_toupper(F))]]) - AC_DEFINE([UF], [1], [Win32 builtin]) - ) + AX_CHECK_SYMBOLS_IN([inet_ntop inet_pton], [ws2tcpip.h]) + AX_CHECK_SYMBOLS_IN(SOCKET_FUNCS, [ws2tcpip.h], , + [AC_MSG_ERROR([Required library function not found])] + ) + AX_CHECK_SYMBOLS_IN(SOCKET_OPT_FUNCS, [ws2tcpip.h]) else AC_CHECK_FUNCS([inet_ntop inet_pton]) AC_CHECK_FUNCS(
Signature · 1 line
1.7.10.4
PATCH 1/1 Add an autoconf macro to check WINAPI functions
--- check_symbols_in.m4 | 43 +++++++++++++++++++++++++++++++++++++++++++ configure.ac | 17 +++++++++-------- 2 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 check_symbols_in.m4
check_symbols_in.m4 new file +43 -0
@@ -0,0 +1,43 @@ +dnl AX_CHECK_SYMBOL - check for a symbol in specified header files +dnl +dnl Usage: AX_CHECK_SYMBOL_IN(symbol, header [,action-if-found [,action-if-not-found]]) +dnl AX_CHECK_SYMBOLS_IN(symbol..., header [,action-if-found [,action-if-not-found]]) +dnl If the symbol is found define HAVE_SYMBOL (with symbol capitalised) in addition to +dnl running the optional 'action-if-found' +dnl +dnl Works as a complement to AC_CHECK_FUNCS for detecting stdcall +dnl functions or functions renamed in headers. Especially useful +dnl for Windows API +dnl +dnl Copyright (c) 2015 Selva Nair <[email protected]...> +dnl +dnl LICENSE +dnl Copying and distribution of this file, with or without modification, +dnl are permitted in any medium without royalty provided the copyright +dnl notice and this notice are preserved. This file is offered as-is, +dnl without any warranty. +dnl +AC_DEFUN([AX_CHECK_SYMBOL_IN], + [AC_CACHE_CHECK([for $1 in $2], + [AS_TR_SH([ac_cv_have_symbol_$1])], + [AC_TRY_COMPILE([#include <$2>], [(void) $1;], + [eval "AS_TR_SH([ac_cv_have_symbol_$1])=yes"], + [eval "AS_TR_SH([ac_cv_have_symbol_$1])=no"])dnl + ]) +if eval test "x$AS_TR_SH([ac_cv_have_symbol_$1])" = xyes; then + AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1]), [1], + [Define to 1 if you have $1.])dnl + [$3] +else + ifelse([$4], ,[:], [$4]) +fi +])dnl +dnl +dnl check for multiple symbols +dnl Usage: AX_CHECK_SYMBOLS_IN(symbol..., header [,action-if-found [,action-if-not-found]]) +dnl +AC_DEFUN([AX_CHECK_SYMBOLS_IN], [ +for ac_symbol in $1; do + AX_CHECK_SYMBOL_IN([$ac_symbol], [$2], [$3], [$4])dnl +done +])dnl
configure.ac +9 -8
@@ -609,8 +609,9 @@ AC_SUBST([SOCKETS_LIBS]) old_LIBS="${LIBS}" LIBS="${LIBS} ${SOCKETS_LIBS}" -AC_CHECK_FUNCS([sendmsg recvmsg inet_ntop inet_pton]) -# Windows use stdcall for winsock so we cannot auto detect these +AC_CHECK_FUNCS([sendmsg recvmsg]) +# Windows use stdcall for winsock so use AX_CHECK_SYMBOLS_IN to detect these +m4_include(check_symbols_in.m4) m4_define( [SOCKET_FUNCS], [socket recv recvfrom send sendto listen dnl
@@ -621,13 +622,13 @@ m4_define( [setsockopt getsockopt getsockname poll]dnl ) if test "${WIN32}" = "yes"; then - m4_foreach( - [F], - m4_split(SOCKET_FUNCS SOCKET_OPT_FUNCS), - m4_define([UF], [[m4_join([_], [HAVE], m4_toupper(F))]]) - AC_DEFINE([UF], [1], [Win32 builtin]) - ) + AX_CHECK_SYMBOLS_IN([inet_ntop inet_pton], [ws2tcpip.h]) + AX_CHECK_SYMBOLS_IN(SOCKET_FUNCS, [ws2tcpip.h], , + [AC_MSG_ERROR([Required library function not found])] + ) + AX_CHECK_SYMBOLS_IN(SOCKET_OPT_FUNCS, [ws2tcpip.h]) else + AC_CHECK_FUNCS([inet_ntop inet_pton]) AC_CHECK_FUNCS( SOCKET_FUNCS, ,
Signature · 1 line
1.7.10.4
Hi,
Quoted 1 line · Selva Nair
Signed-off-by Selva Nair <[email protected]...>
NAK for 2.3 - what we have there works well enough.
Prettyfying things will only be done in master (unless the 2.3 stuff does not *work*, in which case "cleanup when fixing bugs" is fine - but it does work)
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Hi,
Quoted 5 lines · Selva Nair
Quoted 1 line
Signed-off-by Selva Nair <[email protected]...>NAK for 2.3 - what we have there works well enough.
The reason for adding it to 2.3 was anticipating it will have to be built for vista+ if the dns-leak patch goes in.
In fact I wrote it the intet_ntop issue showed up (fixed by commit f96baabc6cf1.. in master) -- had I seen that commit first, wouldn't have though of this macro, probably.
As for how the macro works, will write separately.
Selva
Hi
Quoted 11 lines · Selva Nair
Quoted 4 lines · Selva Nair
Quoted 1 line
Signed-off-by Selva Nair <[email protected]...>NAK for 2.3 - what we have there works well enough.
The reason for adding it to 2.3 was anticipating it will have to be built for vista+ if the dns-leak patch goes in.
In fact I wrote it the
intet_ntopissue showed up (fixed by commitf96baabc6cf1.. in master) -- had I seen that commit first, wouldn't have though of this macro, probably.
You're right - as soon as we'll try to build with VISTA settings, it will blow up on mingw ("as it happened for me on master"). So maybe we need to backport that commit at least, or Samuli will need to apply it to the local tree that is used for building vista+-binaries-from-2.3
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Hi,
Quoted 3 lines · Selva Nair
This adds a macro file with a permissive license. Its small so I don't mind inlining the macro into configure.ac if that is preferred. -------8<--------
This looks interesting, but I'm not convinced that this actually *works* - the reason why I had to add an explicit compile test is that the standard configure.ac test will claim "inet_pton is not there" because the way the test program is built conflicts with the definitions in wstcpip.h
Which environments did you test this on? It needs to work on mingw as shipped with ubuntu 12.04 (no inet_pton), mingw as shipped with 14.04 (inet_pton, *and* the definition its using conflicts with our compat/ libraries, so a false negative will fail later) and cygwin.
It's not pretty, but it's the way it is for a reason :-)
Quoted 1 line
+ [AC_TRY_COMPILE([#include <$2>], [(void) $1;],
This is wrong on multiple levels, actually
- it will only try compilation, not linking - so all we know is "we did not conflict with a header file", not "this function exists and this combination of header files and function calls will make us link the right stuff" (from the docs "This macro does not try to link; use AC_TRY_LINK if you need to do that")
- it will build a test program that will not call the function searched correctly, just "(void) inet_pton()". Which will actually make it *fail* on MinGW on ubuntu 14.04 - there *is* a prototype, so it must be called correctly.
There's a reason for commit f96baabc6cf10edddedda1819a27a6927f274d8e :-)
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Hi,
If it was such a sucker, I wouldn't have posted it :)
The innards of an autoconf macro could be unnerving, but please try it.
Quoted 12 lines · Gert Doering
Hi,
Quoted 3 lines · Selva Nair
This adds a macro file with a permissive license. Its small so I don't mind inlining the macro into configure.ac if that is preferred. -------8<--------
This looks interesting, but I'm not convinced that this actually *works* - the reason why I had to add an explicit compile test is that the standard configure.ac test will claim "
inet_ptonis not there" because the way the test program is built conflicts with the definitions inwstcpip.h
I saw that commit in master after I wrote the macro. The commit works well, but a macro makes it scalable. There is no reason to force define HAVE_POLL in
windows when it doesn't really have poll etc.. Not that it matters in the current code..
Why AC_CHECK_FUNC doesnt detect inet_ntop or many other winsock functions is because
(i) the function name is redefined in the header (inet_ntop is actually InetNtopA in the librray)
(ii) declared as stdcall.
AC_CHECK_FUNC essentially does
char symbol();main() { (void) symbol(); return}
That "char trick" has served us for years, but was never designed to handle either of those two situations. Note AC_FUNC_CHECK, like most most autoconf macros, provide only heuristics -- a symbol with that name exists in the linked libraries, kind of..
AC_CHECK_DECL would detect inet_pton etc., because it only looks for the declaration in a header. The macro I submitted works almost exactly like AC_CHECK_DECL but defines HAVE_symbol instead of HAVE_DECL_symbol.
Quoted 3 lines
Which environments did you test this on? It needs to work on mingw as
I use debian jessie, but it should work elsewhere.
Quoted 10 lines
shipped with ubuntu 12.04 (no
inet_pton), mingw as shipped with 14.04 (inet_pton, *and* the definition its using conflicts with our compat/ libraries, so a false negative will fail later) and cygwin.It's not pretty, but it's the way it is for a reason :-)
Quoted 1 line
+ [AC_TRY_COMPILE([#include <$2>], [(void) $1;],
This is wrong on multiple levels, actually
Its the AC_CHECK_DECL way of testing for a symbol. One could replace the COMPILE with a LINk and it will still work, though that doesn't test anything more than the copile in this case.
Note that its not (void) $1(), its just (void) $1.
If you prefer I can rewrite the macro completely in terms of AC_CHECK_DECL
Selva
Hi,
Quoted 11 lines · Selva Nair
Quoted 5 lines
This looks interesting, but I'm not convinced that this actually *works* - the reason why I had to add an explicit compile test is that the standard configure.ac test will claim "
inet_ptonis not there" because the way the test program is built conflicts with the definitions inwstcpip.hI saw that commit in master after I wrote the macro. The commit works well, but a macro makes it scalable. There is no reason to force define
HAVE_POLLin windows when it doesn't really have poll etc.. Not that it matters in the current code..
Quoted 5 lines
Why
AC_CHECK_FUNCdoesnt detectinet_ntopor many other winsock functions is because
(i) the function name is redefined in the header (inet_ntopis actually InetNtopA in the librray)
(ii) declared as stdcall.
Understood :-)
Quoted 3 lines
AC_CHECK_FUNCessentially does
charsymbol();main(){ (void)symbol(); return}
... and that totally blows up here, for multiple reasons... the include file is not there, so the redefinition does not apply and the library indeed does not have inet_ntop() - and if you add <ws2tcpip.h>, it will still blow up because it now redefines the prototype...
Quoted 3 lines
AC_CHECK_DECLwould detectinet_ptonetc., because it only looks for the declaration in a header. The macro I submitted works almost exactly likeAC_CHECK_DECLbut definesHAVE_symbolinstead ofHAVE_DECL_symbol.
Not good enough. I want to be sure that the symbol is there, and that we actually have the right libraries (so maybe a double check "the symbol is there, but we cannot link, so fail" might be even better).
Quoted 6 lines
Quoted 1 line
Which environments did you test this on? It needs to work on mingw as
I use debian jessie, but it should work elsewhere.
Quoted 3 lines
shipped with ubuntu 12.04 (no
inet_pton), mingw as shipped with 14.04 (inet_pton, *and* the definition its using conflicts with our compat/ libraries, so a false negative will fail later) and cygwin.
Well, the reason why I pointed out these two is that they are different regarding header file brokenness - I'm not sure I remember the details, but stuff that broke for me on 12.04 worked for samuli on 14.04.
It's not like unix where stuff like this just works :-)
Quoted 4 lines
Quoted 4 lines
It's not pretty, but it's the way it is for a reason :-)
Quoted 1 line
+ [AC_TRY_COMPILE([#include <$2>], [(void) $1;],
Quoted 8 lines
Quoted 2 lines
This is wrong on multiple levels, actually
Its the
AC_CHECK_DECLway of testing for a symbol. One could replace the COMPILE with a LINk and it will still work, though that doesn't test anything more than the copile in this case.Note that its not (void) $1(), its just (void) $1.
So it's building a test program that does this?
#include <ws2tcpip.h>main()
{
(void) inet_ntop;
}
... which shouldn't compile at all...?
Quoted 1 line
If you prefer I can rewrite the macro completely in terms of
AC_CHECK_DECL
Convince me that it improves things :-)
Right now, it makes stuff *less* clear to the autoconf-non-enlightened, like me. I do understand the check that we have no, I do not understand your stuff (quite obvious from my dumb questions)...
(I agree that we shouldn't force-define HAVE_POLL if we don't use that stuff on windows at all - so I'm happy to see such things just go out...)
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Hi,
Quoted 9 lines
Quoted 4 lines
AC_CHECK_DECLwould detectinet_ptonetc., because it only looks for the declaration in a header. The macro I submitted works almost exactly likeAC_CHECK_DECLbut definesHAVE_symbolinstead ofHAVE_DECL_symbol.Not good enough. I want to be sure that the symbol is there, and that we actually have the right libraries (so maybe a double check "the symbol is there, but we cannot link, so fail" might be even better).
Agree with the "not good enough" part. But every AC_CHECK_FUNC test is also equally not good enough. Headers are not included (and cannot be included, the way it works), so no guarantee that the detected symbol is the right one. But the purpose of autoconf is to only to get heuristics that may to combined with other independent knowledge about the OS to make a decision.
Quoted 11 lines
Quoted 6 lines
Quoted 1 line
Which environments did you test this on? It needs to work on mingw as
I use debian jessie, but it should work elsewhere.
Quoted 3 lines
shipped with ubuntu 12.04 (no
inet_pton), mingw as shipped with 14.04 (inet_pton, *and* the definition its using conflicts with our compat/ libraries, so a false negative will fail later) and cygwin.Well, the reason why I pointed out these two is that they are different regarding header file brokenness - I'm not sure I remember the details, but stuff that broke for me on 12.04 worked for samuli on 14.04.
I don't think AC_FUNC_CHECK can detect intet_pton in any version of windows API. It just tries to link
(all defines so far goes here)
char inet_pton();
int main()
{
return inet_pton();
}
That will succeed on linux, fail on windows (cross compiled or otherwise).
This test is "not good enough" even on linux/unix --- the ultimate test is building of the application which will fail if the detected inet_pton symbol was something else.
Quoted 11 lines
So it's building a test program that does this?
#include <
ws2tcpip.h>main()
{
(void)inet_ntop;
}... which shouldn't compile at all...?
Make it "int main" , and add a return 0; (both provided by AC_COMPILE..) That will compile for vista, but fail for winxp (which doesn't have inet_ntop). The actual test will also include all defines so far, but that's details.
Quoted 5 lines
Quoted 1 line
If you prefer I can rewrite the macro completely in terms of
AC_CHECK_DECLConvince me that it improves things :-)
I think the current macro already improves things :) Except that it shows how the test is done.
Just as AC_CHECK_FUNC hides all the gory details (or absence of details), use of .._DECL it will hide the program that will be tested :) I said that just because one seldom questions macros included in autoconf distribution.
Quoted 3 lines
Right now, it makes stuff *less* clear to the autoconf-non-enlightened, like me. I do understand the check that we have
That opinion may change after looking through configure to see how any function is checked for.
Quoted 1 line
no, I do not understand
your stuff (quite obvious from my dumb questions)...
Quoted 1 line
The first time skimming through a configure script generated by autoconf is kind of shocking. Over time one gets used to it, no enlightenment...
(I agree that we shouldn't force-define HAVE_POLL if we don't use that
Quoted 1 line
stuff on windows at all - so I'm happy to see such things just go out...)
Totally agree..
Selva
Hi,
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 1 line
Which environments did you test this on? It needs to work on mingw as
I use debian jessie, but it should work elsewhere.
Quoted 3 lines
shipped with ubuntu 12.04 (no
inet_pton), mingw as shipped with 14.04 (inet_pton, *and* the definition its using conflicts with our compat/ libraries, so a false negative will fail later) and cygwin.
Quoted 8 lines
Quoted 4 lines
Well, the reason why I pointed out these two is that they are different regarding header file brokenness - I'm not sure I remember the details, but stuff that broke for me on 12.04 worked for samuli on 14.04.
I don't think
AC_FUNC_CHECKcan detectintet_ptonin any version of windows API. It just tries to link
Regarding the mingw-specific issue: I forgot to add that those two appear to be the only WINAPI functions tested using AC_CHECK_FUNC in configure.ac. These wont be detected though present in vista+. So, the build tries to use the replacement functions even on vista, which should have been ok except for the declaration mismatch with some mingw headers for vista+ --- such a mismatch is not expected, so is very likely specific to some versions of mingw, I don't know.
The failure to detect a function, but then find a mismatch while building is a good example of the limitations of AC_CHECK_FUNC -- one being, headers not included (cannot be included) during the test.
Selva
Hi,
Sorry for the piece-meal replies.
Quoted 7 lines · Gert Doering
Quoted 3 lines
AC_CHECK_DECLwould detectinet_ptonetc., because it only looks for the declaration in a header. The macro I submitted works almost exactly likeAC_CHECK_DECLbut definesHAVE_symbolinstead ofHAVE_DECL_symbol.Not good enough. I want to be sure that the symbol is there, and that we actually have the right libraries (so maybe a double check "the symbol is there, but we cannot link, so fail" might be even better).
When pushed to a corner anything is possible...
It turns out that libws2_32 exports all the required function names without any mangling (as if cdecl). Not sure this is mingw32 speciifc or not. Also unlike I wrote inet_ntop is not redefined, its InetNtopA that is redfined. Though Microsoft docs appears to indicate as if InetNtopA is the actual name.
What it means is that a simple check without my much hated macro should be possible. I'll post a version 2 tonight.
Thanks for the patience.
Selva
Quoted 11 lines · Selva Nair
When pushed to a corner anything is possible...
It turns out that
libws2_32exports all the required function names without any mangling (as if cdecl). Not sure this is mingw32 speciifc or not. Also unlike I wroteinet_ntopis not redefined, its InetNtopA that is redfined. Though Microsoft docs appears to indicate as if InetNtopA is the actual name.What it means is that a simple check without my much hated macro should be possible. I'll post a version 2 tonight.
However, that's true only for 64 bit targets. For 32 bit targets the stdcall names are mangled, as usual, with @NN.
In other words, no version 2, for now.
Thanks,
Selva