I'm trying to build Botan on MinGW, which is really MinGW-w64 (x86_64-pc-msys). It is failing on MinGW as shown below. I think I have it reduced to an MCVE :
#include <sys/select.h>
#include <winsock2.h>
#include <windows.h>
#include <memory>
int main(int argc, char* argv[])
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
int rc = select(1, &fds, NULL, NULL, &tv);
return 0;
}
It results in:
$ g++ -m64 -pthread -std=c++11 test.cxx -o test.exe
In file included from /usr/include/w32api/winsock2.h:56:0,
from test.cxx:2:
/usr/include/w32api/psdk_inc/_fd_types.h:100:2: warning: #warning "fd_set and associated macros have been defined in sys/types. This can cause runtime problems with W32 sockets" [-Wcpp]
#warning "fd_set and associated macros have been defined in sys/types. \
^~~~~~~
In file included from test.cxx:2:0:
/usr/include/w32api/winsock2.h:995:34: error: conflicting declaration of C function ‘int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, PTIMEVAL)’
WINSOCK_API_LINKAGE int WSAAPI select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,const PTIMEVAL timeout);
^~~~~~
In file included from test.cxx:1:0:
/usr/include/sys/select.h:73:5: note: previous declaration ‘int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, timeval*)’
int select __P ((int __n, fd_set *__readfds, fd_set *__writefds,
^~~~~~
Including <sys/select.h>
first is important. Including it after the Windows headers does not witness the problem. Including <memory>
is important. <memory>
includes additional headers like <sys/select.h>
, which has already been included.
The best I can tell, MinGW headers are causing the problem. They provide the same function with two different signatures:
/usr/include/w32api/winsock2.h
:
int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, PTIMEVAL)
/usr/include/sys/select.h
int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, timeval*)
The problem appears to be the last argument. In one case it is PTIMEVAL
and in the other case it is timeval*
. This seems to be related from the mailing list, but I don't understand what I should be doing: Replace struct timeval usage with PTIMEVAL and define TIMEVAL differently on LP64.
There may be some pointer size problems as detailed at What do I have to look out for when porting applications to 64 bit Cygwin?, but it is MinGW code (and not Botan code).
What is the problem, and how do I fix it?
Here is Botan's src/lib/utils/socket/socket.cpp
.
Here is the compile error:
g++ -fstack-protector -m64 -pthread -std=c++11 -D_REENTRANT -O3 -momit-leaf-frame-pointer \
-Wall -Wextra -Wpedantic -Wstrict-aliasing -Wcast-align -Wmissing-declarations \
-Wpointer-arith -Wcast-qual -Wzero-as-null-pointer-constant -Wnon-virtual-dtor \
-Ibuild/include -c src/lib/utils/socket/socket.cpp -o build/obj/lib/utils_socket.o
In file included from /usr/include/w32api/winsock2.h:56:0,
from src/lib/utils/socket/socket.cpp:35:
/usr/include/w32api/psdk_inc/_fd_types.h:100:2: warning: #warning "fd_set and associated macros have been defined in sys/types. This can cause runtime problems with W32 sockets" [-Wcpp]
#warning "fd_set and associated macros have been defined in sys/types. \
^~~~~~~
In file included from src/lib/utils/socket/socket.cpp:35:0:
/usr/include/w32api/winsock2.h:995:34: error: conflicting declaration of C function ‘int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, PTIMEVAL)’
WINSOCK_API_LINKAGE int WSAAPI select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,const PTIMEVAL timeout);
^~~~~~
In file included from /usr/include/sys/types.h:68:0,
from /usr/include/pthread.h:11,
from /usr/lib/gcc/x86_64-pc-msys/6.3.0/include/c++/x86_64-pc-msys/bits/gthr-default.h:35,
from /usr/lib/gcc/x86_64-pc-msys/6.3.0/include/c++/x86_64-pc-msys/bits/gthr.h:148,
from /usr/lib/gcc/x86_64-pc-msys/6.3.0/include/c++/ext/atomicity.h:35,
from /usr/lib/gcc/x86_64-pc-msys/6.3.0/include/c++/memory:73,
from build/include/botan/types.h:17,
from build/include/botan/internal/socket.h:11,
from src/lib/utils/socket/socket.cpp:8:
/usr/include/sys/select.h:73:5: note: previous declaration ‘int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, timeval*)’
int select __P ((int __n, fd_set *__readfds, fd_set *__writefds,
^~~~~~
make: *** [Makefile:1066: build/obj/lib/utils_socket.o] Error 1