Open hanxi opened 9 years ago
本来一直没想过还会在 windows 下开发的,但是一想到我的处理 Excel 的转表工具可能需要提供给策划本地使用,我就想方设法了,安装 mingw 的话应该更好解决,但是不了解发布版需不需要安装 mingw,而且刚好电脑已经安装好了 vs。所以就有了这篇文章。其实不用 nmake ,完全用 cl 和 link 命令也是可以的。只不过 nmake 和 make 一样,更适合管理。
为了能编译并使用扩展,需要在生成 .dll 的时候生成 .lib 文件。生成 DLL 使用 /DLL 参数。但是生成的 lib 文件有问题,编译扩展库的时候会出现 unresolved xxx。搜到这个 https://ci.appveyor.com/project/xpol/lua-rapidjson/build/0.1.0.4/job/93u2pxa808er1huc 。最有用了,虽然是用 CMake 生成的 Make 日志,但是都把编译命令输出来了。需要添加 -DLUA_BUILD_AS_DLL ,至于为什么的话可以去 src/luaconf.h 中搜就知道了。
.dll
.lib
/DLL
unresolved xxx
-DLUA_BUILD_AS_DLL
src/luaconf.h
下面的 makefile 就是使用 nmake 执行的。生成 Lua.exe 比较简单。生成 Lua.lib 主要是要加上面提到的预定义。
STD_INC=/I "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" \ /I "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include" \ /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt" \ /I "C:\Program Files (x86)\Windows Kits\8.1\Include\um" \ /I "C:\Program Files (x86)\Windows Kits\8.1\Include\shared" \ /I "C:\Program Files (x86)\Windows Kits\8.1\Include\winrt" STD_LIB_PATH=/LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib" \ /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\lib" \ /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.10150.0\ucrt\x86" \ /LIBPATH:"C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x86" \ /LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Lib\um\x86" SRC_DIR=src OBJ_DIR=objs LUA_INC=/I $(SRC_DIR) INCLUDE_DIR=$(STD_INC) $(LUA_INC) LIB_PATH=$(STD_LIB_PATH) OBJS=$(OBJ_DIR)\lapi.obj \ $(OBJ_DIR)\lauxlib.obj \ $(OBJ_DIR)\lbaselib.obj \ $(OBJ_DIR)\lbitlib.obj \ $(OBJ_DIR)\lcode.obj \ $(OBJ_DIR)\lcorolib.obj \ $(OBJ_DIR)\lctype.obj \ $(OBJ_DIR)\ldblib.obj \ $(OBJ_DIR)\ldebug.obj \ $(OBJ_DIR)\ldo.obj \ $(OBJ_DIR)\ldump.obj \ $(OBJ_DIR)\lfunc.obj \ $(OBJ_DIR)\lgc.obj \ $(OBJ_DIR)\linit.obj \ $(OBJ_DIR)\liolib.obj \ $(OBJ_DIR)\llex.obj \ $(OBJ_DIR)\lmathlib.obj \ $(OBJ_DIR)\lmem.obj \ $(OBJ_DIR)\loadlib.obj \ $(OBJ_DIR)\lobject.obj \ $(OBJ_DIR)\lopcodes.obj \ $(OBJ_DIR)\loslib.obj \ $(OBJ_DIR)\lparser.obj \ $(OBJ_DIR)\lstate.obj \ $(OBJ_DIR)\lstring.obj \ $(OBJ_DIR)\lstrlib.obj \ $(OBJ_DIR)\ltable.obj \ $(OBJ_DIR)\ltablib.obj \ $(OBJ_DIR)\ltm.obj \ $(OBJ_DIR)\lundump.obj \ $(OBJ_DIR)\lutf8lib.obj \ $(OBJ_DIR)\lvm.obj \ $(OBJ_DIR)\lzio.obj all: Lua.dll Lua.exe Luac.exe #compile {$(SRC_DIR)}.c{$(OBJ_DIR)}.obj:: @if not exist $(OBJ_DIR) mkdir $(OBJ_DIR) $(CC) /nologo $(INCLUDE_DIR) /Fo$B /c -DLUA_BUILD_AS_DLL $< @move *.obj $(OBJ_DIR) # link Lua.exe: Lua.lib $(OBJ_DIR)\lua.obj LINK /nologo /OUT:$@ $(LIB_PATH) $? Luac.exe: $(OBJS) $(OBJ_DIR)\luac.obj LINK /nologo /OUT:$@ $(LIB_PATH) $? Lua.dll: $(OBJS) LINK /nologo /DLL /OUT:$@ $(LIB_PATH) $? clean: rd /S /Q $(OBJ_DIR) del *.exe del *.dll del *.exp del *.lib
对应的 Lua 源码目录结构是这样的
E:\workspace\lua\ | .---src\ | .---objs\ | .---Makefile
我主要是为了编译 xlsx 库,所以就以这个为例子。 主要就是为了生成 zip.so 和 base64.so。 生成 base64.so 比较简单就一个文件,生成一个obj, 然后再 link 成 dll。主要关键点在引用 Lua.lib 和 两个预定义 -DLUA_LIB -DLUA_BUILD_AS_DLL。 Lua.lib 是上面编译 Lua 的时候生成的,要使用绝对路径。两个预定义的话还是要依据 luaconf.h 也是根据而来。改了这么多还不够,还要改 lbase64.c 和 luazip.c 的 xxx_open 函数的定义, 需要在前面加上 LUA_API。/MD 需要改为 /MT,要不然移植到没有安装 vc++ 环境的机器上就跑不起来。历经N次尝试和谷歌搜索,就这样结束了。luazip.c 里面有行代码不兼容VC编译器:char tmp[szfn];,这是C99的用法,需要自行修改下。
zip.so
base64.so
-DLUA_LIB -DLUA_BUILD_AS_DLL
luaconf.h
lbase64.c
luazip.c
xxx_open
LUA_API
/MD
/MT
char tmp[szfn];
STD_INC=/I "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" \ /I "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include" \ /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt" \ /I "C:\Program Files (x86)\Windows Kits\8.1\Include\um" \ /I "C:\Program Files (x86)\Windows Kits\8.1\Include\shared" \ /I "C:\Program Files (x86)\Windows Kits\8.1\Include\winrt" STD_LIB_PATH=/LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib" \ /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\lib" \ /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.10150.0\ucrt\x86" \ /LIBPATH:"C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x86" \ /LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Lib\um\x86" CFLAGS=/nologo /MT /O2 /c LUA_INC=/I "E:\workspace\lua\src" LUA_LIB= E:\workspace\lua\Lua.lib LUA_LIB_PATH=/LIBPATH:"E:\workspace\lua" ZLIB_SRC=zlib MINIZIP_SRC=minizip INCLUDE_DIR=$(STD_INC) $(LUA_INC) /I $(ZLIB_SRC) /I $(MINIZIP_SRC) LIB_PATH=$(STD_LIB_PATH) $(LUA_LIB_PATH) OBJ_DIR=objs ZLIB_OBJS=$(OBJ_DIR)\adler32.obj \ $(OBJ_DIR)\compress.obj \ $(OBJ_DIR)\crc32.obj \ $(OBJ_DIR)\deflate.obj \ $(OBJ_DIR)\gzclose.obj \ $(OBJ_DIR)\gzlib.obj \ $(OBJ_DIR)\gzread.obj \ $(OBJ_DIR)\gzwrite.obj \ $(OBJ_DIR)\infback.obj \ $(OBJ_DIR)\inffast.obj \ $(OBJ_DIR)\inflate.obj \ $(OBJ_DIR)\inftrees.obj \ $(OBJ_DIR)\trees.obj \ $(OBJ_DIR)\uncompr.obj \ $(OBJ_DIR)\zutil.obj MINIZIP_OBJS=$(OBJ_DIR)\ioapi.obj \ $(OBJ_DIR)\iowin32.obj \ $(OBJ_DIR)\miniunz.obj \ $(OBJ_DIR)\mztools.obj \ $(OBJ_DIR)\unzip.obj \ $(OBJ_DIR)\zip.obj all: base64.dll zip.dll #compile .c{$(OBJ_DIR)}.obj:: @if not exist $(OBJ_DIR) mkdir $(OBJ_DIR) $(CC) $(CFLAGS) $(INCLUDE_DIR) /Fo$B -DLUA_LIB -DLUA_BUILD_AS_DLL $< @move *.obj $(OBJ_DIR) {$(MINIZIP_SRC)}.c{$(OBJ_DIR)}.obj:: @if not exist $(OBJ_DIR) mkdir $(OBJ_DIR) $(CC) $(CFLAGS) $(INCLUDE_DIR) /Fo$B -DLUA_LIB -DLUA_BUILD_AS_DLL $< @move *.obj $(OBJ_DIR) {$(ZLIB_SRC)}.c{$(OBJ_DIR)}.obj:: @if not exist $(OBJ_DIR) mkdir $(OBJ_DIR) $(CC) $(CFLAGS) $(INCLUDE_DIR) /Fo$B -DLUA_LIB -DLUA_BUILD_AS_DLL $< @move *.obj $(OBJ_DIR) # link base64.dll: $(OBJ_DIR)\lbase64.obj LINK /nologo /DLL /OUT:$@ $(LIB_PATH) $(LUA_LIB) $? zip.dll: $(OBJ_DIR)\luazip.obj $(ZLIB_OBJS) $(MINIZIP_OBJS) LINK /nologo /DLL /OUT:$@ $(LIB_PATH) $(LUA_LIB) $? clean: rd /S /Q $(OBJ_DIR) del *.exe del *.dll del *.exp del *.lib
目录结构
luaclib\ | .---minizip\ | .---zlib\ | .---objs\ | .---lbase64.c | .---luazip.c | .---Makefile
makefile 见 https://github.com/hanxi/luasocket-nmake
跟上面的不同的是 lua.exe 和 luac.exe 都为静态编译的方式
起因
本来一直没想过还会在 windows 下开发的,但是一想到我的处理 Excel 的转表工具可能需要提供给策划本地使用,我就想方设法了,安装 mingw 的话应该更好解决,但是不了解发布版需不需要安装 mingw,而且刚好电脑已经安装好了 vs。所以就有了这篇文章。其实不用 nmake ,完全用 cl 和 link 命令也是可以的。只不过 nmake 和 make 一样,更适合管理。
编译 Lua
为了能编译并使用扩展,需要在生成
.dll
的时候生成.lib
文件。生成 DLL 使用/DLL
参数。但是生成的 lib 文件有问题,编译扩展库的时候会出现unresolved xxx
。搜到这个 https://ci.appveyor.com/project/xpol/lua-rapidjson/build/0.1.0.4/job/93u2pxa808er1huc 。最有用了,虽然是用 CMake 生成的 Make 日志,但是都把编译命令输出来了。需要添加-DLUA_BUILD_AS_DLL
,至于为什么的话可以去src/luaconf.h
中搜就知道了。下面的 makefile 就是使用 nmake 执行的。生成 Lua.exe 比较简单。生成 Lua.lib 主要是要加上面提到的预定义。
对应的 Lua 源码目录结构是这样的
编译 Lua 的扩展库
我主要是为了编译 xlsx 库,所以就以这个为例子。 主要就是为了生成
zip.so
和base64.so
。 生成 base64.so 比较简单就一个文件,生成一个obj, 然后再 link 成 dll。主要关键点在引用 Lua.lib 和 两个预定义-DLUA_LIB -DLUA_BUILD_AS_DLL
。 Lua.lib 是上面编译 Lua 的时候生成的,要使用绝对路径。两个预定义的话还是要依据luaconf.h
也是根据而来。改了这么多还不够,还要改lbase64.c
和luazip.c
的xxx_open
函数的定义, 需要在前面加上LUA_API
。/MD
需要改为/MT
,要不然移植到没有安装 vc++ 环境的机器上就跑不起来。历经N次尝试和谷歌搜索,就这样结束了。luazip.c
里面有行代码不兼容VC编译器:char tmp[szfn];
,这是C99的用法,需要自行修改下。目录结构
编译 luasocket
makefile 见 https://github.com/hanxi/luasocket-nmake
跟上面的不同的是 lua.exe 和 luac.exe 都为静态编译的方式