Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用 nmake 编译 Lua 及扩展库 #9

Open
hanxi opened this issue Jul 27, 2015 · 0 comments
Open

使用 nmake 编译 Lua 及扩展库 #9

hanxi opened this issue Jul 27, 2015 · 0 comments

Comments

@hanxi
Copy link
Owner

hanxi commented Jul 27, 2015

起因

本来一直没想过还会在 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 主要是要加上面提到的预定义。

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

编译 Lua 的扩展库

我主要是为了编译 xlsx 库,所以就以这个为例子。
主要就是为了生成 zip.sobase64.so。 生成 base64.so 比较简单就一个文件,生成一个obj,
然后再 link 成 dll。主要关键点在引用 Lua.lib 和 两个预定义 -DLUA_LIB -DLUA_BUILD_AS_DLL
Lua.lib 是上面编译 Lua 的时候生成的,要使用绝对路径。两个预定义的话还是要依据 luaconf.h
也是根据而来。改了这么多还不够,还要改 lbase64.cluazip.cxxx_open 函数的定义,
需要在前面加上 LUA_API/MD 需要改为 /MT,要不然移植到没有安装 vc++ 环境的机器上就跑不起来。历经N次尝试和谷歌搜索,就这样结束了。luazip.c 里面有行代码不兼容VC编译器:char tmp[szfn];,这是C99的用法,需要自行修改下。

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

编译 luasocket

makefile 见 https://github.com/hanxi/luasocket-nmake

跟上面的不同的是 lua.exe 和 luac.exe 都为静态编译的方式

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant