From bb0b31301a43e740f30cf438f9f2b3e68fbd7698 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 25 May 2013 18:07:38 +0800 Subject: [PATCH] Add MingW support. --- makefile | 19 ++++++--- mingw.cmd | 1 + src/inet.c | 80 ++++++++++++++++------------------- src/makefile | 114 ++++++++++++++++++++++++++++++++++---------------- src/udp.c | 34 +++++++-------- src/wsocket.c | 8 +++- src/wsocket.h | 4 ++ 7 files changed, 157 insertions(+), 103 deletions(-) create mode 100644 mingw.cmd diff --git a/makefile b/makefile index f9fa6fe..04cd894 100644 --- a/makefile +++ b/makefile @@ -3,13 +3,14 @@ # see src/makefile for description of how to customize the build # # Targets: -# install install system independent support -# install-unix also install unix-only support -# install-both install both lua5.1 and lua5.2 socket support -# print print the build settings +# install install system independent support +# install-unix also install unix-only support +# install-both install for both lua5.1 and lua5.2 +# install-both-unix also install unix-only +# print print the build settings PLAT?= linux -PLATS= macosx linux win32 +PLATS= macosx linux win32 mingw all: $(PLAT) @@ -23,6 +24,14 @@ test: lua test/hello.lua install-both: + $(MAKE) clean + @cd src; $(MAKE) $(PLAT) LUAV=5.1 + @cd src; $(MAKE) install LUAV=5.1 + $(MAKE) clean + @cd src; $(MAKE) $(PLAT) LUAV=5.2 + @cd src; $(MAKE) install LUAV=5.2 + +install-both-unix: $(MAKE) clean @cd src; $(MAKE) $(PLAT) LUAV=5.1 @cd src; $(MAKE) install-unix LUAV=5.1 diff --git a/mingw.cmd b/mingw.cmd new file mode 100644 index 0000000..bf2b7ed --- /dev/null +++ b/mingw.cmd @@ -0,0 +1 @@ +make PLAT=mingw LUAINC_mingw_base=/home/diego/build/mingw/include LUALIB_mingw_base=/home/diego/build/mingw/bin LUAPREFIX_mingw=/home/diego/build/mingw/bin DEBUG=DEBUG install-both diff --git a/src/inet.c b/src/inet.c index 1017022..1530fef 100644 --- a/src/inet.c +++ b/src/inet.c @@ -385,7 +385,6 @@ const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm) struct in6_addr addrany = IN6ADDR_ANY_INIT; memset((char *) &sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_UNSPEC; -fprintf(stderr, "disconnecting\n"); sin6.sin6_addr = addrany; return socket_strerror(socket_connect(ps, (SA *) &sin6, sizeof(sin6), tm)); @@ -507,54 +506,49 @@ int inet_aton(const char *cp, struct in_addr *inp) } #endif -// inet_ntop/inet_pton for MinGW from http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html +/*-------------------------------------------------------------------------*\ +* inet_ntop/inet_pton for MinGW from +* http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html +\*-------------------------------------------------------------------------*/ #ifdef INET_PTON -const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) +const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { - if (af == AF_INET) - { - struct sockaddr_in in; - memset(&in, 0, sizeof(in)); - in.sin_family = AF_INET; - memcpy(&in.sin_addr, src, sizeof(struct in_addr)); - getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); - return dst; - } - else if (af == AF_INET6) - { - struct sockaddr_in6 in; - memset(&in, 0, sizeof(in)); - in.sin6_family = AF_INET6; - memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); - getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); - return dst; - } - return NULL; + if (af == AF_INET) { + struct sockaddr_in in; + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + memcpy(&in.sin_addr, src, sizeof(struct in_addr)); + getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), + dst, cnt, NULL, 0, NI_NUMERICHOST); + return dst; + } else if (af == AF_INET6) { + struct sockaddr_in6 in; + memset(&in, 0, sizeof(in)); + in.sin6_family = AF_INET6; + memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); + getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), + dst, cnt, NULL, 0, NI_NUMERICHOST); + return dst; + } + return NULL; } -int inet_pton(int af, const char *src, void *dst) +int inet_pton(int af, const char *src, void *dst) { - struct addrinfo hints, *res, *ressave; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = af; - - if (getaddrinfo(src, NULL, &hints, &res) != 0) - { - return -1; - } - - ressave = res; - - while (res) - { - memcpy(dst, res->ai_addr, res->ai_addrlen); - res = res->ai_next; - } - - freeaddrinfo(ressave); - return 0; + struct addrinfo hints, *res, *ressave; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + if (getaddrinfo(src, NULL, &hints, &res) != 0) { + return -1; + } + ressave = res; + while (res) { + memcpy(dst, res->ai_addr, res->ai_addrlen); + res = res->ai_next; + } + freeaddrinfo(ressave); + return 0; } #endif diff --git a/src/makefile b/src/makefile index a75d5a6..a6e0033 100644 --- a/src/makefile +++ b/src/makefile @@ -12,7 +12,7 @@ # # make PLAT=linux DEBUG=DEBUG LUAV=5.2 prefix=/sw -# PLAT: linux macosx win32 +# PLAT: linux macosx win32 mingw # platform to build for PLAT?=linux @@ -33,6 +33,9 @@ LUAINC_macosx?=$(LUAINC_macosx_base)/lua$(LUAV) # FIXME default should this default to fink or to macports? # What happens when more than one Lua version is installed? LUAPREFIX_macosx?=/opt/local +CDIR_macosx?=lib/lua/$(LUAV) +LDIR_macosx?=share/lua/$(LUAV) + # LUAINC_linux: # /usr/include/lua$(LUAV) @@ -42,19 +45,38 @@ LUAPREFIX_macosx?=/opt/local LUAINC_linux_base?=/usr/include LUAINC_linux?=$(LUAINC_linux_base)/lua$(LUAV) LUAPREFIX_linux?=/usr/local +CDIR_linux?=lib/lua/$(LUAV) +LDIR_linux?=share/lua/$(LUAV) + +# where lua headers are found for mingw builds +# LUAINC_mingw: +# /opt/local/include +LUAINC_mingw_base?=/usr/include +LUAINC_mingw?=$(LUAINC_mingw_base)/lua/$(LUAV) +LUALIB_mingw_base?=/usr/bin +LUALIB_mingw?=$(LUALIB_mingw_base)/lua/$(LUAV)/lua$(subst .,,$(LUAV)).dll +LUAPREFIX_mingw?=/usr +CDIR_mingw?=lua/$(LUAV) +LDIR_mingw?=lua/$(LUAV)/lua + # LUAINC_win32: # LUALIB_win32: # where lua headers and libraries are found for win32 builds LUAINC_win32?="../../lua-5.1.3/src" -LUALIB_win32?="../../lua-5.1.3" +LUALIB_win32?=/LIBPATH:"../../lua-5.1.3" lua$(LUAV).lib + LUAPREFIX_win32?= -# FIXME default should be where lua-for-windows puts lua +CDIR_win32?=lua/$(LUAV) +LDIR_win32?=lua/$(LUAV)/lua # prefix: /usr/local /usr /opt/local /sw # the top of the default install tree prefix?=$(LUAPREFIX_$(PLAT)) +CDIR?=$(CDIR_$(PLAT)) +LDIR?=$(LDIR_$(PLAT)) + # DESTDIR: (no default) # used by package managers to install into a temporary destination DESTDIR= @@ -63,13 +85,6 @@ DESTDIR= # Definitions below can be overridden on the make command line, but # shouldn't have to be. -print: - @echo PLAT=$(PLAT) - @echo LUAV=$(LUAV) - @echo DEBUG=$(DEBUG) - @echo prefix=$(prefix) - @echo LUAINC_$(PLAT)=$(LUAINC_$(PLAT)) - @echo LUALIB_$(PLAT)=$(LUALIB_$(PLAT)) #------ # Install directories @@ -80,18 +95,28 @@ INSTALL_DATA=install -m644 INSTALL_EXEC=install INSTALL_TOP=$(DESTDIR)$(prefix) -INSTALL_TOP_SHARE=$(INSTALL_TOP)/share/lua/$(LUAV) -INSTALL_TOP_LIB=$(INSTALL_TOP)/lib/lua/$(LUAV) +INSTALL_TOP_LDIR=$(INSTALL_TOP)/$(LDIR) +INSTALL_TOP_CDIR=$(INSTALL_TOP)/$(CDIR) -INSTALL_SOCKET_SHARE=$(INSTALL_TOP_SHARE)/socket -INSTALL_SOCKET_LIB=$(INSTALL_TOP_LIB)/socket -INSTALL_MIME_SHARE=$(INSTALL_TOP_SHARE)/mime -INSTALL_MIME_LIB=$(INSTALL_TOP_LIB)/mime +INSTALL_SOCKET_LDIR=$(INSTALL_TOP_LDIR)/socket +INSTALL_SOCKET_CDIR=$(INSTALL_TOP_CDIR)/socket +INSTALL_MIME_LDIR=$(INSTALL_TOP_LDIR)/mime +INSTALL_MIME_CDIR=$(INSTALL_TOP_CDIR)/mime + +print: + @echo PLAT=$(PLAT) + @echo LUAV=$(LUAV) + @echo DEBUG=$(DEBUG) + @echo prefix=$(prefix) + @echo LUAINC_$(PLAT)=$(LUAINC_$(PLAT)) + @echo LUALIB_$(PLAT)=$(LUALIB_$(PLAT)) + @echo INSTALL_TOP_CDIR=$(INSTALL_TOP_CDIR) + @echo INSTALL_TOP_LDIR=$(INSTALL_TOP_LDIR) #------ # Supported platforms # -PLATS= macosx linux win32 +PLATS= macosx linux win32 mingw #------ # Compiler and linker settings @@ -117,12 +142,28 @@ CC_linux=gcc DEF_linux=-DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE \ -DLUASOCKET_API='__attribute__((visibility("default")))' \ -DMIME_API='__attribute__((visibility("default")))' -CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra -Wimplicit -O2 -ggdb3 -fpic \ - -fvisibility=hidden +CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra \ + -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden LDFLAGS_linux=-O -shared -fpic -o LD_linux=gcc SOCKET_linux=usocket.o +#------ +# Compiler and linker settings +# for MingW +SO_mingw=dll +O_mingw=o +CC_mingw=gcc +DEF_mingw= -DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE -DWINVER=0x0501 \ + -DLUASOCKET_API='__declspec(dllexport)' \ + -DMIME_API='__declspec(dllexport)' +CFLAGS_mingw= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \ + -fvisibility=hidden +LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lwsock32 -lws2_32 -o +LD_mingw=gcc +SOCKET_mingw=wsocket.o + + #------ # Compiler and linker settings # for Win32 @@ -135,12 +176,10 @@ DEF_win32= /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" \ /D "LUASOCKET_$(DEBUG)" CFLAGS_win32=/I "$(LUAINC)" $(DEF) /O2 /Ot /MD /W3 /nologo LDFLAGS_win32= /nologo /link /NOLOGO /DLL /INCREMENTAL:NO \ - /LIBPATH:"$(LUALIB)" \ - /MANIFEST \ - /MANIFESTFILE:"intermediate.manifest" \ + /MANIFEST /MANIFESTFILE:"intermediate.manifest" \ /MANIFESTUAC:"level='asInvoker' uiAccess='false'" \ /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /DYNAMICBASE:NO \ - /MACHINE:X86 ws2_32.lib lua$(LUAV).lib /OUT: + /MACHINE:X86 $(LUALIB) ws2_32.lib /OUT: LD_win32=cl SOCKET_win32=wsocket.obj @@ -223,7 +262,7 @@ SERIAL_OBJS:=\ #------ # Files to install # -TO_SOCKET_SHARE= \ +TO_SOCKET_LDIR= \ http.lua \ url.lua \ tp.lua \ @@ -231,7 +270,7 @@ TO_SOCKET_SHARE= \ headers.lua \ smtp.lua -TO_TOP_SHARE= \ +TO_TOP_LDIR= \ ltn12.lua \ socket.lua \ mime.lua @@ -250,6 +289,9 @@ win32: linux: $(MAKE) all-unix PLAT=linux +mingw: + $(MAKE) all PLAT=mingw + none: @echo "Please run" @echo " make PLATFORM" @@ -273,21 +315,21 @@ $(SERIAL_SO): $(SERIAL_OBJS) $(LD) $(SERIAL_OBJS) $(LDFLAGS)$@ install: - $(INSTALL_DIR) $(INSTALL_TOP_SHARE) - $(INSTALL_DATA) $(TO_TOP_SHARE) $(INSTALL_TOP_SHARE) - $(INSTALL_DIR) $(INSTALL_SOCKET_SHARE) - $(INSTALL_DATA) $(TO_SOCKET_SHARE) $(INSTALL_SOCKET_SHARE) - $(INSTALL_DIR) $(INSTALL_SOCKET_LIB) - $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(SO) - $(INSTALL_DIR) $(INSTALL_MIME_LIB) - $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(SO) + $(INSTALL_DIR) $(INSTALL_TOP_LDIR) + $(INSTALL_DATA) $(TO_TOP_LDIR) $(INSTALL_TOP_LDIR) + $(INSTALL_DIR) $(INSTALL_SOCKET_LDIR) + $(INSTALL_DATA) $(TO_SOCKET_LDIR) $(INSTALL_SOCKET_LDIR) + $(INSTALL_DIR) $(INSTALL_SOCKET_CDIR) + $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_CDIR)/core.$(SO) + $(INSTALL_DIR) $(INSTALL_MIME_CDIR) + $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_CDIR)/core.$(SO) install-unix: install - $(INSTALL_EXEC) $(UNIX_SO) $(INSTALL_SOCKET_LIB)/$(UNIX_SO) - $(INSTALL_EXEC) $(SERIAL_SO) $(INSTALL_SOCKET_LIB)/$(SERIAL_SO) + $(INSTALL_EXEC) $(UNIX_SO) $(INSTALL_SOCKET_CDIR)/$(UNIX_SO) + $(INSTALL_EXEC) $(SERIAL_SO) $(INSTALL_SOCKET_CDIR)/$(SERIAL_SO) local: - $(MAKE) install INSTALL_TOP_LIB=.. INSTALL_TOP_SHARE=.. + $(MAKE) install INSTALL_TOP_CDIR=.. INSTALL_TOP_LDIR=.. clean: rm -f $(SOCKET_SO) $(SOCKET_OBJS) $(SERIAL_OBJS) diff --git a/src/udp.c b/src/udp.c index 8e14fac..6e0de9f 100644 --- a/src/udp.c +++ b/src/udp.c @@ -159,7 +159,7 @@ static int meth_sendto(lua_State *L) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); if (!inet_pton(AF_INET, ip, &addr.sin_addr)) - luaL_argerror(L, 3, "invalid ip address"); + luaL_argerror(L, 3, "invalid ip address"); addr.sin_family = AF_INET; addr.sin_port = htons(port); timeout_markstart(tm); @@ -171,7 +171,7 @@ static int meth_sendto(lua_State *L) { struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); if (!inet_pton(AF_INET6, ip, &addr.sin6_addr)) - luaL_argerror(L, 3, "invalid ip address"); + luaL_argerror(L, 3, "invalid ip address"); addr.sin6_family = AF_INET6; addr.sin6_port = htons(port); timeout_markstart(tm); @@ -180,9 +180,9 @@ static int meth_sendto(lua_State *L) { break; } default: - lua_pushnil(L); - lua_pushfstring(L, "unknown family %d", udp->family); - return 2; + lua_pushnil(L); + lua_pushfstring(L, "unknown family %d", udp->family); + return 2; } if (err != IO_DONE) { lua_pushnil(L); @@ -259,19 +259,19 @@ static int meth_receivefrom(lua_State *L) { (SA *) &addr, &addr_len, tm); /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ if (err == IO_CLOSED) - err = IO_DONE; + err = IO_DONE; if (err == IO_DONE) { - char addrstr[INET6_ADDRSTRLEN]; - lua_pushlstring(L, buffer, got); - if (!inet_ntop(AF_INET6, &addr.sin6_addr, - addrstr, sizeof(addrstr))) { - lua_pushnil(L); - lua_pushstring(L, "invalid source address"); - return 2; - } - lua_pushstring(L, addrstr); - lua_pushnumber(L, ntohs(addr.sin6_port)); - return 3; + char addrstr[INET6_ADDRSTRLEN]; + lua_pushlstring(L, buffer, got); + if (!inet_ntop(AF_INET6, &addr.sin6_addr, + addrstr, sizeof(addrstr))) { + lua_pushnil(L); + lua_pushstring(L, "invalid source address"); + return 2; + } + lua_pushstring(L, addrstr); + lua_pushnumber(L, ntohs(addr.sin6_port)); + return 3; } break; } diff --git a/src/wsocket.c b/src/wsocket.c index d6dd004..65f76bc 100644 --- a/src/wsocket.c +++ b/src/wsocket.c @@ -400,13 +400,17 @@ const char *socket_gaistrerror(int err) { case EAI_MEMORY: return "memory allocation failure"; case EAI_NONAME: return "host or service not provided, or not known"; -// case EAI_OVERFLOW: return "argument buffer overflow"; +#ifdef EAI_OVERFLOW + case EAI_OVERFLOW: return "argument buffer overflow"; +#endif #ifdef EAI_PROTOCOL case EAI_PROTOCOL: return "resolved protocol is unknown"; #endif case EAI_SERVICE: return "service not supported for socket type"; case EAI_SOCKTYPE: return "ai_socktype not supported"; -// case EAI_SYSTEM: return strerror(errno); +#ifdef EAI_SYSTEM + case EAI_SYSTEM: return strerror(errno); +#endif default: return gai_strerror(err); } } diff --git a/src/wsocket.h b/src/wsocket.h index 0783b00..8fbc54d 100644 --- a/src/wsocket.h +++ b/src/wsocket.h @@ -16,6 +16,10 @@ typedef SOCKADDR_STORAGE t_sockaddr_storage; typedef SOCKET t_socket; typedef t_socket *p_socket; +#ifndef IPV6_V6ONLY +#define IPV6_V6ONLY 27 +#endif + #define SOCKET_INVALID (INVALID_SOCKET) #ifndef SO_REUSEPORT