Add MingW support.

This commit is contained in:
unknown 2013-05-25 18:07:38 +08:00
parent cbc77440c8
commit bb0b31301a
7 changed files with 157 additions and 103 deletions

View File

@ -3,13 +3,14 @@
# see src/makefile for description of how to customize the build # see src/makefile for description of how to customize the build
# #
# Targets: # Targets:
# install install system independent support # install install system independent support
# install-unix also install unix-only support # install-unix also install unix-only support
# install-both install both lua5.1 and lua5.2 socket support # install-both install for both lua5.1 and lua5.2
# print print the build settings # install-both-unix also install unix-only
# print print the build settings
PLAT?= linux PLAT?= linux
PLATS= macosx linux win32 PLATS= macosx linux win32 mingw
all: $(PLAT) all: $(PLAT)
@ -23,6 +24,14 @@ test:
lua test/hello.lua lua test/hello.lua
install-both: 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 $(MAKE) clean
@cd src; $(MAKE) $(PLAT) LUAV=5.1 @cd src; $(MAKE) $(PLAT) LUAV=5.1
@cd src; $(MAKE) install-unix LUAV=5.1 @cd src; $(MAKE) install-unix LUAV=5.1

1
mingw.cmd Normal file
View File

@ -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

View File

@ -385,7 +385,6 @@ const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm)
struct in6_addr addrany = IN6ADDR_ANY_INIT; struct in6_addr addrany = IN6ADDR_ANY_INIT;
memset((char *) &sin6, 0, sizeof(sin6)); memset((char *) &sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_UNSPEC; sin6.sin6_family = AF_UNSPEC;
fprintf(stderr, "disconnecting\n");
sin6.sin6_addr = addrany; sin6.sin6_addr = addrany;
return socket_strerror(socket_connect(ps, (SA *) &sin6, return socket_strerror(socket_connect(ps, (SA *) &sin6,
sizeof(sin6), tm)); sizeof(sin6), tm));
@ -507,54 +506,49 @@ int inet_aton(const char *cp, struct in_addr *inp)
} }
#endif #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 #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) if (af == AF_INET) {
{ struct sockaddr_in in;
struct sockaddr_in in; memset(&in, 0, sizeof(in));
memset(&in, 0, sizeof(in)); in.sin_family = AF_INET;
in.sin_family = AF_INET; memcpy(&in.sin_addr, src, sizeof(struct in_addr));
memcpy(&in.sin_addr, src, sizeof(struct in_addr)); getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in),
getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); dst, cnt, NULL, 0, NI_NUMERICHOST);
return dst; return dst;
} } else if (af == AF_INET6) {
else if (af == AF_INET6) struct sockaddr_in6 in;
{ memset(&in, 0, sizeof(in));
struct sockaddr_in6 in; in.sin6_family = AF_INET6;
memset(&in, 0, sizeof(in)); memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
in.sin6_family = AF_INET6; getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6),
memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); dst, cnt, NULL, 0, NI_NUMERICHOST);
getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); return dst;
return dst; }
} return NULL;
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; struct addrinfo hints, *res, *ressave;
memset(&hints, 0, sizeof(struct addrinfo));
memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = af;
hints.ai_family = af; if (getaddrinfo(src, NULL, &hints, &res) != 0) {
return -1;
if (getaddrinfo(src, NULL, &hints, &res) != 0) }
{ ressave = res;
return -1; while (res) {
} memcpy(dst, res->ai_addr, res->ai_addrlen);
res = res->ai_next;
ressave = res; }
freeaddrinfo(ressave);
while (res) return 0;
{
memcpy(dst, res->ai_addr, res->ai_addrlen);
res = res->ai_next;
}
freeaddrinfo(ressave);
return 0;
} }
#endif #endif

View File

@ -12,7 +12,7 @@
# #
# make PLAT=linux DEBUG=DEBUG LUAV=5.2 prefix=/sw # make PLAT=linux DEBUG=DEBUG LUAV=5.2 prefix=/sw
# PLAT: linux macosx win32 # PLAT: linux macosx win32 mingw
# platform to build for # platform to build for
PLAT?=linux PLAT?=linux
@ -33,6 +33,9 @@ LUAINC_macosx?=$(LUAINC_macosx_base)/lua$(LUAV)
# FIXME default should this default to fink or to macports? # FIXME default should this default to fink or to macports?
# What happens when more than one Lua version is installed? # What happens when more than one Lua version is installed?
LUAPREFIX_macosx?=/opt/local LUAPREFIX_macosx?=/opt/local
CDIR_macosx?=lib/lua/$(LUAV)
LDIR_macosx?=share/lua/$(LUAV)
# LUAINC_linux: # LUAINC_linux:
# /usr/include/lua$(LUAV) # /usr/include/lua$(LUAV)
@ -42,19 +45,38 @@ LUAPREFIX_macosx?=/opt/local
LUAINC_linux_base?=/usr/include LUAINC_linux_base?=/usr/include
LUAINC_linux?=$(LUAINC_linux_base)/lua$(LUAV) LUAINC_linux?=$(LUAINC_linux_base)/lua$(LUAV)
LUAPREFIX_linux?=/usr/local 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: # LUAINC_win32:
# LUALIB_win32: # LUALIB_win32:
# where lua headers and libraries are found for win32 builds # where lua headers and libraries are found for win32 builds
LUAINC_win32?="../../lua-5.1.3/src" 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?= 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 # prefix: /usr/local /usr /opt/local /sw
# the top of the default install tree # the top of the default install tree
prefix?=$(LUAPREFIX_$(PLAT)) prefix?=$(LUAPREFIX_$(PLAT))
CDIR?=$(CDIR_$(PLAT))
LDIR?=$(LDIR_$(PLAT))
# DESTDIR: (no default) # DESTDIR: (no default)
# used by package managers to install into a temporary destination # used by package managers to install into a temporary destination
DESTDIR= DESTDIR=
@ -63,13 +85,6 @@ DESTDIR=
# Definitions below can be overridden on the make command line, but # Definitions below can be overridden on the make command line, but
# shouldn't have to be. # 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 # Install directories
@ -80,18 +95,28 @@ INSTALL_DATA=install -m644
INSTALL_EXEC=install INSTALL_EXEC=install
INSTALL_TOP=$(DESTDIR)$(prefix) INSTALL_TOP=$(DESTDIR)$(prefix)
INSTALL_TOP_SHARE=$(INSTALL_TOP)/share/lua/$(LUAV) INSTALL_TOP_LDIR=$(INSTALL_TOP)/$(LDIR)
INSTALL_TOP_LIB=$(INSTALL_TOP)/lib/lua/$(LUAV) INSTALL_TOP_CDIR=$(INSTALL_TOP)/$(CDIR)
INSTALL_SOCKET_SHARE=$(INSTALL_TOP_SHARE)/socket INSTALL_SOCKET_LDIR=$(INSTALL_TOP_LDIR)/socket
INSTALL_SOCKET_LIB=$(INSTALL_TOP_LIB)/socket INSTALL_SOCKET_CDIR=$(INSTALL_TOP_CDIR)/socket
INSTALL_MIME_SHARE=$(INSTALL_TOP_SHARE)/mime INSTALL_MIME_LDIR=$(INSTALL_TOP_LDIR)/mime
INSTALL_MIME_LIB=$(INSTALL_TOP_LIB)/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 # Supported platforms
# #
PLATS= macosx linux win32 PLATS= macosx linux win32 mingw
#------ #------
# Compiler and linker settings # Compiler and linker settings
@ -117,12 +142,28 @@ CC_linux=gcc
DEF_linux=-DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE \ DEF_linux=-DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE \
-DLUASOCKET_API='__attribute__((visibility("default")))' \ -DLUASOCKET_API='__attribute__((visibility("default")))' \
-DMIME_API='__attribute__((visibility("default")))' -DMIME_API='__attribute__((visibility("default")))'
CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra -Wimplicit -O2 -ggdb3 -fpic \ CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra \
-fvisibility=hidden -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden
LDFLAGS_linux=-O -shared -fpic -o LDFLAGS_linux=-O -shared -fpic -o
LD_linux=gcc LD_linux=gcc
SOCKET_linux=usocket.o 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 # Compiler and linker settings
# for Win32 # for Win32
@ -135,12 +176,10 @@ DEF_win32= /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" \
/D "LUASOCKET_$(DEBUG)" /D "LUASOCKET_$(DEBUG)"
CFLAGS_win32=/I "$(LUAINC)" $(DEF) /O2 /Ot /MD /W3 /nologo CFLAGS_win32=/I "$(LUAINC)" $(DEF) /O2 /Ot /MD /W3 /nologo
LDFLAGS_win32= /nologo /link /NOLOGO /DLL /INCREMENTAL:NO \ LDFLAGS_win32= /nologo /link /NOLOGO /DLL /INCREMENTAL:NO \
/LIBPATH:"$(LUALIB)" \ /MANIFEST /MANIFESTFILE:"intermediate.manifest" \
/MANIFEST \
/MANIFESTFILE:"intermediate.manifest" \
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" \ /MANIFESTUAC:"level='asInvoker' uiAccess='false'" \
/SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /DYNAMICBASE:NO \ /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 LD_win32=cl
SOCKET_win32=wsocket.obj SOCKET_win32=wsocket.obj
@ -223,7 +262,7 @@ SERIAL_OBJS:=\
#------ #------
# Files to install # Files to install
# #
TO_SOCKET_SHARE= \ TO_SOCKET_LDIR= \
http.lua \ http.lua \
url.lua \ url.lua \
tp.lua \ tp.lua \
@ -231,7 +270,7 @@ TO_SOCKET_SHARE= \
headers.lua \ headers.lua \
smtp.lua smtp.lua
TO_TOP_SHARE= \ TO_TOP_LDIR= \
ltn12.lua \ ltn12.lua \
socket.lua \ socket.lua \
mime.lua mime.lua
@ -250,6 +289,9 @@ win32:
linux: linux:
$(MAKE) all-unix PLAT=linux $(MAKE) all-unix PLAT=linux
mingw:
$(MAKE) all PLAT=mingw
none: none:
@echo "Please run" @echo "Please run"
@echo " make PLATFORM" @echo " make PLATFORM"
@ -273,21 +315,21 @@ $(SERIAL_SO): $(SERIAL_OBJS)
$(LD) $(SERIAL_OBJS) $(LDFLAGS)$@ $(LD) $(SERIAL_OBJS) $(LDFLAGS)$@
install: install:
$(INSTALL_DIR) $(INSTALL_TOP_SHARE) $(INSTALL_DIR) $(INSTALL_TOP_LDIR)
$(INSTALL_DATA) $(TO_TOP_SHARE) $(INSTALL_TOP_SHARE) $(INSTALL_DATA) $(TO_TOP_LDIR) $(INSTALL_TOP_LDIR)
$(INSTALL_DIR) $(INSTALL_SOCKET_SHARE) $(INSTALL_DIR) $(INSTALL_SOCKET_LDIR)
$(INSTALL_DATA) $(TO_SOCKET_SHARE) $(INSTALL_SOCKET_SHARE) $(INSTALL_DATA) $(TO_SOCKET_LDIR) $(INSTALL_SOCKET_LDIR)
$(INSTALL_DIR) $(INSTALL_SOCKET_LIB) $(INSTALL_DIR) $(INSTALL_SOCKET_CDIR)
$(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(SO) $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_CDIR)/core.$(SO)
$(INSTALL_DIR) $(INSTALL_MIME_LIB) $(INSTALL_DIR) $(INSTALL_MIME_CDIR)
$(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(SO) $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_CDIR)/core.$(SO)
install-unix: install install-unix: install
$(INSTALL_EXEC) $(UNIX_SO) $(INSTALL_SOCKET_LIB)/$(UNIX_SO) $(INSTALL_EXEC) $(UNIX_SO) $(INSTALL_SOCKET_CDIR)/$(UNIX_SO)
$(INSTALL_EXEC) $(SERIAL_SO) $(INSTALL_SOCKET_LIB)/$(SERIAL_SO) $(INSTALL_EXEC) $(SERIAL_SO) $(INSTALL_SOCKET_CDIR)/$(SERIAL_SO)
local: local:
$(MAKE) install INSTALL_TOP_LIB=.. INSTALL_TOP_SHARE=.. $(MAKE) install INSTALL_TOP_CDIR=.. INSTALL_TOP_LDIR=..
clean: clean:
rm -f $(SOCKET_SO) $(SOCKET_OBJS) $(SERIAL_OBJS) rm -f $(SOCKET_SO) $(SOCKET_OBJS) $(SERIAL_OBJS)

View File

@ -159,7 +159,7 @@ static int meth_sendto(lua_State *L) {
struct sockaddr_in addr; struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
if (!inet_pton(AF_INET, ip, &addr.sin_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_family = AF_INET;
addr.sin_port = htons(port); addr.sin_port = htons(port);
timeout_markstart(tm); timeout_markstart(tm);
@ -171,7 +171,7 @@ static int meth_sendto(lua_State *L) {
struct sockaddr_in6 addr; struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
if (!inet_pton(AF_INET6, ip, &addr.sin6_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_family = AF_INET6;
addr.sin6_port = htons(port); addr.sin6_port = htons(port);
timeout_markstart(tm); timeout_markstart(tm);
@ -180,9 +180,9 @@ static int meth_sendto(lua_State *L) {
break; break;
} }
default: default:
lua_pushnil(L); lua_pushnil(L);
lua_pushfstring(L, "unknown family %d", udp->family); lua_pushfstring(L, "unknown family %d", udp->family);
return 2; return 2;
} }
if (err != IO_DONE) { if (err != IO_DONE) {
lua_pushnil(L); lua_pushnil(L);
@ -259,19 +259,19 @@ static int meth_receivefrom(lua_State *L) {
(SA *) &addr, &addr_len, tm); (SA *) &addr, &addr_len, tm);
/* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
if (err == IO_CLOSED) if (err == IO_CLOSED)
err = IO_DONE; err = IO_DONE;
if (err == IO_DONE) { if (err == IO_DONE) {
char addrstr[INET6_ADDRSTRLEN]; char addrstr[INET6_ADDRSTRLEN];
lua_pushlstring(L, buffer, got); lua_pushlstring(L, buffer, got);
if (!inet_ntop(AF_INET6, &addr.sin6_addr, if (!inet_ntop(AF_INET6, &addr.sin6_addr,
addrstr, sizeof(addrstr))) { addrstr, sizeof(addrstr))) {
lua_pushnil(L); lua_pushnil(L);
lua_pushstring(L, "invalid source address"); lua_pushstring(L, "invalid source address");
return 2; return 2;
} }
lua_pushstring(L, addrstr); lua_pushstring(L, addrstr);
lua_pushnumber(L, ntohs(addr.sin6_port)); lua_pushnumber(L, ntohs(addr.sin6_port));
return 3; return 3;
} }
break; break;
} }

View File

@ -400,13 +400,17 @@ const char *socket_gaistrerror(int err) {
case EAI_MEMORY: return "memory allocation failure"; case EAI_MEMORY: return "memory allocation failure";
case EAI_NONAME: case EAI_NONAME:
return "host or service not provided, or not known"; 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 #ifdef EAI_PROTOCOL
case EAI_PROTOCOL: return "resolved protocol is unknown"; case EAI_PROTOCOL: return "resolved protocol is unknown";
#endif #endif
case EAI_SERVICE: return "service not supported for socket type"; case EAI_SERVICE: return "service not supported for socket type";
case EAI_SOCKTYPE: return "ai_socktype not supported"; 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); default: return gai_strerror(err);
} }
} }

View File

@ -16,6 +16,10 @@ typedef SOCKADDR_STORAGE t_sockaddr_storage;
typedef SOCKET t_socket; typedef SOCKET t_socket;
typedef t_socket *p_socket; typedef t_socket *p_socket;
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
#endif
#define SOCKET_INVALID (INVALID_SOCKET) #define SOCKET_INVALID (INVALID_SOCKET)
#ifndef SO_REUSEPORT #ifndef SO_REUSEPORT