发布于 2016-01-11 23:14:06 | 205 次阅读 | 评论: 0 | 来源: PHPERZ
XMake 自动构建工具
XMake 是一个跨平台自动构建工具,支持在各种主流平台上构建项目,类似 cmake、automake、premake,但是更加的方便易用,工程描述语法更简洁直观,支持平台更多,并且集创建、配置、编译、打包、安装、卸载、运行于一体。
xmake提供了自定义打包、安装、运行脚本,可以更加灵活的针对个人实际需求来操作xmake
这里用一个例子详细说明下,比如有个需求,我需要自动编译、安装、运行android app工程,并且能够支持jni
可以进行如下操作
首先创建个基于ant的android app工程,目录结构如下:
app
└── android
├── AndroidManifest.xml
├── ant.properties
├── bin
│ └── Demo-debug.apk
├── build.xml
├── jni
│ └── demo.c
├── libs
│ └── armeabi
│ └── libdemo.so
├── local.properties
├── proguard-project.txt
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ └── main.xml
│ └── values
│ └── strings.xml
├── src
│ └── com
│ └── demo
│ └── DemoTest.java
└── xmake.lua
-- 添加一个android app的测试demo
add_target("demo")
-- 生成动态库:libdemo.so
set_kind("shared")
-- 设置对象的输出目录,可选
set_objectdir("$(buildir)/.objs")
-- 每次编译完的libdemo.so的生成目录,设置为app/libs/armeabi
set_targetdir("libs/armeabi")
-- 添加jni的代码文件
add_files("jni/*.c")
-- 设置自定义打包脚本,在使用xmake编译完libdemo.so后,执行xmake p进行打包
-- 会自动使用ant将app编译成apk文件
--
-- target参数提供了一些编译目标的信息,例如:目标文件路径,目标类型等等
-- 具体有哪些信息,可以调用 utils.dump(target) 打印出来
-- 当然首先得import("utils")导入这个utils模块
set_packagescript( function (target)
-- 导入一些内置模块
local os = import("os")
local path = import("path")
local project = import("project")
assert(target and os and path and project)
-- 获取编译错误输出的日志文件,用于重定向输出,可选
-- 一般用于隐藏ant工具的内部输出信息,但是编译出错后,xmake会去自动显示出来
local logfile = path.absolute(project.logfile())
-- 首先清除app的bin的目录
os.rmdir("bin")
-- 打印一些信息
print("buiding app")
-- 使用ant编译app成apk文件,输出信息重定向到日志文件
if 0 ~= os.execute(string.format("ant debug > %s 2>&1", logfile)) then
-- 出错后,显示日志文件中的信息
os.cat(logfile)
return -1
end
-- 如果成功打包,返回1,就不再执行内置默认的打包流程了
-- 如果返回0,会继续执行内部默认的打包程序
-- 如果返回-1,说明打包失败,终止运行
return 1
end)
-- 设置自定义安装脚本,自动安装apk文件
set_installscript( function (target)
-- 导入一些内置模块
local os = import("os")
local path = import("path")
local project = import("project")
assert(target and os and path and project)
-- trace
print("installing app")
-- the logfile
local logfile = path.absolute(project.logfile())
-- 使用adb安装打包生成的apk文件
if 0 ~= os.execute(string.format("adb install -r ./bin/Demo-debug.apk > %s 2>&1", logfile)) then
-- failed
os.cat(logfile)
return -1
end
-- ok
return 1
end)
-- 设置自定义运行脚本,自动运行安装好的app程序,并且自动获取设备输出信息
set_runscript( function (target)
-- 导入一些内置模块
local os = import("os")
assert(target and os)
-- 设置过滤器,来过滤设备输出信息,当然默认也可以不设置
-- 使用如下:xmake r demo filter
local filter = nil
if target.arguments ~= nil then
filter = target.arguments[1]
end
local cmd = "adb shell am start -n com.demo/com.demo.DemoTest ; adb logcat"
if filter ~= nil then
cmd = cmd .. " | grep " .. filter
end
-- 使用adb运行app程序
if 0 ~= os.execute(cmd) then
return -1
end
-- ok
return 1
end)
修改完xmake.lua后,就可以很方便的使用了:
# 重新编译工程,生成libdemo.so到app/libs/armeabi
xmake -r
# 打包app为apk
xmake p
# 安装apk到设备上
xmake i
# 运行app,并获取日志信息
xmake r demo
如果觉得上面的步骤有点繁琐,可以简化成:
-- 安装的时候,会先去自动打包,所以可以省略xmake p
xmake -r; xmake i; xmake r demo
如果是增量编译,不需要重建,可以继续简化:
xmake i; xmake r demo
当然,由于是根据自己的实际需求自定义的脚本,可能跨平台性有点弱,像这里只能支持android的编译平台,
你也可以使用 if plats("android") then ... end
来做一些跨平台处理