目录
1、编译工具和环境说明
2、基础编译tolua
大家好,我是阿赵。
继续来讲tolua的各个常用平台的编译。
这里使用官方的tolua_runtime-master项目来做编译
具体需要的编译软件和源码地址,在上一篇文章已经介绍过了,先把环境准备好,然后就开始编译了。
一、编译Windows用的dll
首先拿比较容易编译成功的Windows平台的dll来做一个练手。
1、编译32位的dll
执行mingw32_shell.bat
出现命令行提示之后
1.先跳转到项目所在路径
我的路径是放在G盘的tolua文件夹,所以我用cd命令这样跳转:
admin@DESKTOP-DL702DH MINGW32 ~
$ cd /g/
admin@DESKTOP-DL702DH MINGW32 /g
$ cd tolua
admin@DESKTOP-DL702DH MINGW32 /g/tolua
2.可以用dir命令去展示出当前文件夹所有文件
$ dir
android build_ubuntu.sh iOS luasocket struct.c
bit.c build_win32.sh LICENSE macjit tolua.c
build_arm.sh build_win64.sh link_arm64.bat macnojit tolua.h
build_arm64.sh build_x86.sh lpeg.c pb.c ubuntu
build_ios.sh cjson lpeg.h Plugins uint64.c
build_osx.sh int64.c luajit-2.1 README.md window
3.调用build_win32.sh来编译
admin@DESKTOP-DL702DH MINGW32 /g/tolua
$ ./build_win32.sh
这时候会看到一大堆的输出
E:/Software/msys64/mingw64/bin/mingw32-make -C src clean
mingw32-make[1]: Entering directory ‘G:/tolua/luajit-2.1/src’ rm -f
luajit.exe libluajit.a lua51.dll host/minilua.exe host/buildvm.exe
lj_vm.S lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h
host/buildvm_arch.h jit/vmdef.lua .o host/.o *.obj *.lib *.exp *.dll
*.exe *.manifest *.pdb *.ilk mingw32-make[1]: Leaving directory ‘G:/tolua/luajit-2.1/src’
==== Building LuaJIT 2.1.0-beta3 ==== E:/Software/msys64/mingw64/bin/mingw32-make -C src mingw32-make[1]:
Entering directory ‘G:/tolua/luajit-2.1/src’ HOSTCC host/minilua.o
HOSTLINK host/minilua.exe DYNASM host/buildvm_arch.h HOSTCC
host/buildvm.o HOSTCC host/buildvm_asm.o HOSTCC
host/buildvm_peobj.o HOSTCC host/buildvm_lib.o HOSTCC
host/buildvm_fold.o HOSTLINK host/buildvm.exe BUILDVM lj_vm.o CC
lj_gc.o BUILDVM lj_ffdef.h CC lj_err.o CC lj_char.o
BUILDVM lj_bcdef.h CC lj_bc.o CC lj_obj.o CC
lj_buf.o CC lj_str.o CC lj_tab.o CC lj_func.o CC
lj_udata.o CC lj_meta.o CC lj_debug.o CC
lj_state.o CC lj_dispatch.o CC lj_vmevent.o CC
lj_vmmath.o CC lj_strscan.o CC lj_strfmt.o CC
lj_strfmt_num.o CC lj_api.o CC lj_profile.o CC
lj_lex.o CC lj_parse.o CC lj_bcread.o CC
lj_bcwrite.o CC lj_load.o CC lj_ir.o CC
lj_opt_mem.o BUILDVM lj_folddef.h CC lj_opt_fold.o CC
lj_opt_narrow.o CC lj_opt_dce.o CC lj_opt_loop.o CC
lj_opt_split.o CC lj_opt_sink.o CC lj_mcode.o CC
lj_snap.o CC lj_record.o CC lj_crecord.o BUILDVM
lj_recdef.h CC lj_ffrecord.o CC lj_asm.o CC
lj_trace.o CC lj_gdbjit.o CC lj_ctype.o CC
lj_cdata.o CC lj_cconv.o CC lj_ccall.o CC
lj_ccallback.o CC lj_carith.o CC lj_clib.o CC
lj_cparse.o CC lj_lib.o CC lj_alloc.o lj_alloc.c:176:14:
warning: ‘DIRECT_MMAP’ defined but not used [-Wunused-function]
static void *DIRECT_MMAP(size_t size)
^ CC lib_aux.o BUILDVM lj_libdef.h CC lib_base.o CC lib_math.o CC lib_bit.o CC
lib_string.o CC lib_table.o CC lib_io.o CC
lib_os.o CC lib_package.o CC lib_debug.o CC
lib_jit.o CC lib_ffi.o CC lib_init.o AR
libluajit.a CC luajit.o BUILDVM jit/vmdef.lua LINK
luajit.exe OK Successfully built LuaJIT mingw32-make[1]:
Leaving directory ‘G:/tolua/luajit-2.1/src’
==== Successfully built LuaJIT 2.1.0-beta3 ==== E:/Software/msys64/mingw64/bin/mingw32-make -C src clean
mingw32-make[1]: Entering directory ‘G:/tolua/luajit-2.1/src’ rm -f
luajit.exe libluajit.a lua51.dll host/minilua.exe host/buildvm.exe
lj_vm.S lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h
host/buildvm_arch.h jit/vmdef.lua .o host/.o *.obj *.lib *.exp *.dll
*.exe *.manifest *.pdb *.ilk mingw32-make[1]: Leaving directory ‘G:/tolua/luajit-2.1/src’
这些输出其实都是批处理在执行每个步骤里面的打印输出。如果没有发现什么错误提示,最后应该就是编译成功了,
4.编译成功
可以在Plugins\x86文件夹里面找到编译完成的dll文件。
2、编译64位的dll
注意,因为是编译64位,所以执行mingw64_shell.bat
在出来命令行之后,步骤和上面的32位一样,跳转到tolua所在目录,这次要执行build_win64.sh。
具体的过程和32位差不多,所以不再贴出过程了
编译成功后,在Plugins/x86_64文件夹找到生成的dll文件
这里稍微看看build_64.sh是做了什么的,把文件用文本编辑器打开
#!/bin/bash
# 64 Bit Version
mkdir -p window/x86_64
cd luajit-2.1
mingw32-make clean
mingw32-make BUILDMODE=static CC="gcc -m64 -O2" XCFLAGS=-DLUAJIT_ENABLE_GC64
cp src/libluajit.a ../window/x86_64/libluajit.a
mingw32-make clean
cd ..
gcc -m64 -O2 -std=gnu99 -shared \
tolua.c \
int64.c \
uint64.c \
pb.c \
lpeg.c \
struct.c \
cjson/strbuf.c \
cjson/lua_cjson.c \
cjson/fpconv.c \
luasocket/auxiliar.c \
luasocket/buffer.c \
luasocket/except.c \
luasocket/inet.c \
luasocket/io.c \
luasocket/luasocket.c \
luasocket/mime.c \
luasocket/options.c \
luasocket/select.c \
luasocket/tcp.c \
luasocket/timeout.c \
luasocket/udp.c \
luasocket/wsocket.c \
-o Plugins/x86_64/tolua.dll \
-I./ \
-Iluajit-2.1/src \
-Iluasocket \
-lws2_32 \
-Wl,--whole-archive window/x86_64/libluajit.a -Wl,--no-whole-archive -static-libgcc -static-libstdc++
从这个批处理脚本可以看到,实际上它做了以下这些事情:
1.创建window/x86_64文件夹
mkdir -p window/x86_64
2.进入luajit-2.1文件夹,并且用make来编译出来libluajit.a
cd luajit-2.1
mingw32-make clean
mingw32-make BUILDMODE=static CC="gcc -m64 -O2" XCFLAGS=-DLUAJIT_ENABLE_GC64
cp src/libluajit.a ../window/x86_64/libluajit.a
mingw32-make clean
3.返回到上一层文件夹、
cd ..
4.用gcc编译,指定需要编译的内容和需要自动查找的文件夹
gcc -m64 -O2 -std=gnu99 -shared \
tolua.c \
int64.c \
uint64.c \
pb.c \
lpeg.c \
struct.c \
cjson/strbuf.c \
cjson/lua_cjson.c \
cjson/fpconv.c \
luasocket/auxiliar.c \
luasocket/buffer.c \
luasocket/except.c \
luasocket/inet.c \
luasocket/io.c \
luasocket/luasocket.c \
luasocket/mime.c \
luasocket/options.c \
luasocket/select.c \
luasocket/tcp.c \
luasocket/timeout.c \
luasocket/udp.c \
luasocket/wsocket.c \
-o Plugins/x86_64/tolua.dll \
-I./ \
-Iluajit-2.1/src \
-Iluasocket \
-lws2_32 \
-Wl,--whole-archive window/x86_64/libluajit.a -Wl,--no-whole-archive -static-libgcc -static-libstdc++
一般来说,编译Windows的dll是最简单的,中途也不会出什么错误,所以可以先用这个来试试。
二、编译安卓用的so
1、编译32位的so
执行mingw32_shell.bat,并跳转到tolua所在目录
这次要执行build_arm.sh
执行了之后,发现了提示一堆报错,主要的都是这样的:
D:/android-ndk-r10e/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-gcc:命令未找到
这是因为,在build_arm.sh里面,需要先指定NDK的目录,而默认是D:/android-ndk-r10e,我的电脑本地没有这个NDK目录,所以肯定是找不到的。
接下来需要下载NDK了。这个下载可以自己百度。不过建议先看完我下面说的,再去下载,不然可能会浪费很多时间。
举个例子,我下载了比较新的NDK版本r25c,然后把地址填入到build_arm.sh,然后再执行编译,这次出现了新的报错:
G:/android-ndk-r25c/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-gcc:命令未找到
这是因为,Android后面的版本彻底的移除了gcc编译,默认改为了使用clang编译的缘故,在ndk18之后就没有gcc了
解决这个问题估计只能有2种方案:
1、使用旧版本包含gcc的ndk
2、学习用clang编译
简单的处理就是使用旧版本ndk了,不过需要注意的是,就算是旧版ndk,他包含的gcc方法也会因为版本而不一样,比如我下周了r16去编译,会报错:
g:\ndk\android-ndk-r16b-windows-x86_64\android-ndk-r16b\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\lib\gcc\aarch64-linux-android\4.9.x\include-fixed\limits.h:34,
from luaconf.h:12,
from lua.h:16,
from lj_obj.h:12,
from lj_gc.c:12:
所以,如果是要拿就版本的ndk去编译,最好还是用ndk-r10e这个版本
下载了ndk-r10e,指定了路径,编译,这次通过了。在Plugins\Android\libs\armeabi-v7a里面可以看到了tolua.so文件
2、编译64位的so
执行mingw64_shell.bat,跳转到tolua的目录,把NDK的路径填入build_arm64.sh,然后执行build_arm64.sh
发现执行完成,android/jni/libluajit.a已经重新生成了,但并没有在Plugins\Android\libs\arm64-v8a目录发现有新生成的tolua.so文件
打开build_arm64.sh看看
cd luajit-2.1/src
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS)
NDK=G:/ndk/android-ndk-r13b-windows-x86_64/android-ndk-r13b
NDKABI=21
NDKTRIPLE=aarch64-linux-android
NDKVER=$NDK/toolchains/aarch64-linux-android-4.9
NDKP=$NDKVER/prebuilt/windows-x86_64/bin/aarch64-linux-android-
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm64"
NDKARCH="-DLJ_ABI_SOFTFP=0 -DLJ_ARCH_HASFPU=1 -DLUAJIT_ENABLE_GC64=1"
make clean
make HOST_CC="gcc -m64" CROSS=$NDKP TARGET_SYS=Linux TARGET_FLAGS="$NDKF $NDKARCH"
cp ./libluajit.a ../../android/jni/libluajit.a
make clean
if [[ "$OSTYPE" == "msys" ]]; then
cd ../../
# can't pass $NDK to bat
cmd /c "link_arm64.bat"
else
cd ../../android
$NDK/ndk-build clean APP_ABI="armeabi-v7a,x86,arm64-v8a" APP_PLATFORM=android-21
$NDK/ndk-build APP_ABI="arm64-v8a" APP_PLATFORM=android-21
cp libs/arm64-v8a/libtolua.so ../Plugins/Android/libs/arm64-v8a
$NDK/ndk-build clean APP_ABI="armeabi-v7a,x86,arm64-v8a" APP_PLATFORM=android-21
fi
可以看到
if [[ "$OSTYPE" == "msys" ]]; then
cd ../../
# can't pass $NDK to bat
cmd /c "link_arm64.bat"
我们是用msys执行的,所以他实际上在是调用了link_arm64.bat这个批处理。
打开link_arm64.bat看看
@echo off
set ndkPath=D:/android-ndk-r15c
cd ./android
call %ndkPath%/ndk-build clean APP_ABI="armeabi-v7a,x86,arm64-v8a" APP_PLATFORM=android-21
call %ndkPath%/ndk-build APP_ABI="arm64-v8a" APP_PLATFORM=android-21
copy libs\arm64-v8a\libtolua.so ..\Plugins\Android\libs\arm64-v8a
call %ndkPath%/ndk-build clean APP_ABI="armeabi-v7a,x86,arm64-v8a" APP_PLATFORM=android-21
echo Successfully linked
exit
发现这里也有需要指定NDK的路径,所以也指定一下自己的NDK路径。
再次编译,发现成功了,在Plugins\Android\libs\arm64-v8a目录发现有新生成的tolua.so文件。
再回头来看一下build_arm64.sh的内容,他里面做的事情有:
1.指定编译参数
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS)
NDK=D:/android-ndk-r15c
NDKABI=21
NDKTRIPLE=aarch64-linux-android
NDKVER=$NDK/toolchains/aarch64-linux-android-4.9
NDKP=$NDKVER/prebuilt/windows-x86_64/bin/aarch64-linux-android-
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm64"
NDKARCH="-DLJ_ABI_SOFTFP=0 -DLJ_ARCH_HASFPU=1 -DLUAJIT_ENABLE_GC64=1"
2.编译libluajit.a
make clean
make HOST_CC="gcc -m64" CROSS=$NDKP TARGET_SYS=Linux TARGET_FLAGS="$NDKF $NDKARCH"
cp ./libluajit.a ../../android/jni/libluajit.a
make clean
3.实际编译
if [[ "$OSTYPE" == "msys" ]]; then
cd ../../
# can't pass $NDK to bat
cmd /c "link_arm64.bat"
else
cd ../../android
$NDK/ndk-build clean APP_ABI="armeabi-v7a,x86,arm64-v8a" APP_PLATFORM=android-21
$NDK/ndk-build APP_ABI="arm64-v8a" APP_PLATFORM=android-21
cp libs/arm64-v8a/libtolua.so ../Plugins/Android/libs/arm64-v8a
$NDK/ndk-build clean APP_ABI="armeabi-v7a,x86,arm64-v8a" APP_PLATFORM=android-21
fi
最后的实际编译,其实就是调用NDK的ndk-build方法把so文件编译出来
三、编译OSX用的bundle
编译osx和ios都不能在Windows编译,因为是需要命令行调用xcode编译的。
所以在mac准备好xcode,然后把tolua项目拷贝到mac上,尝试编译
在mac下面不需要安装任何的软件,直接打开命令行终端,然后输入命令就行了
可以通过cd命令跳转文件夹,通过ls命令列出文件夹里面的内容,然后调用./build_osx.sh
直接编译,发现了2个错误
1、提示i386不支持
打开macnojit文件夹下的tolua.xcodeproj工程,在Build Settings里面搜索ARCHS然后修改一下红框里面的内容,把i386删除掉
2、发现cjson报错
去下载最新版的cjson
下载地址
然后拷贝到tolua项目内的cjson文件夹内。
然后再次编译,就看到了Plugins文件夹下的tolua.bundle
四、编译iOS用的a文件
和编译OSX一样,用命令行终端跳转到tolua项目路径,然后执行build_ios.sh
发现2个问题
1.提示IPHONEOS_DEPLOYMENT_TARGET错误
warning: The iOS deployment target ‘IPHONEOS_DEPLOYMENT_TARGET’ is set
to
8.0, but the range of supported deployment target versions is 9.0 to
14.1.99. (in target ‘FMDB’ from project ‘Pods’)
根据提示打开tolua项目的iOS文件夹下的tolua.xcodeproj项目
然后在Build Settings里面找到deployment的iOS Deployment Target选项,选择一个提示里面支持的版本9.0 to 14.1.99就行了,比如就选择9.0
2.提示Armv7错误
Build Settings 中搜索 “Excluded Architectures”, 复制以下内容添加即可:
EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8EXCLUDED_ARCHS=$(inherited)$(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT))
warning: The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to
8.0, but the range of supported deployment target versions is 9.0 to
再次执行编译,在Plugins\iOS文件夹下就看到libtolua.a
因为OSX和iOS的编译都是基于xcode的,所以其实出现报错,都需要取对应的xcode项目里面去修改。