xmake-gradle是一个无缝整合 xmake 的 gradle 插件。
目前在 gradle 中做 android jni 相关集成开发,有两种方式,通过 ndkBuild 或者 CMake 来支持,gradle 也内置了这两工具的集成
但是维护 Android.mk 还是非常繁琐的,尤其是对于大型项目会比较痛苦,而 cmake 的 dsl 语法不够简洁直观,我个人也不是很喜欢,因此我先前整了 xmake 来实现跨平台开发,优势就是: 简单,快速,对新手友好,另外功能也很强大,具体有那些功能,大家可以到 xmake 项目主页看下相关介绍。
而之前想要用 xmake 编译 android so 库,只能通过命令行的方式比如:
xmake f -p android --ndk=xxxx
xmake
虽然已经很简单了,但是如果要跟 android apk/aar 一起打包集成,还是需要很多额外的工作,为了提高开发者的效率,我最近新整了这个 grafle 插件,来无缝集成到 gradle 的整个构建体系中去。
这样,用户就可以在 android studio 方便的用 xmake 来编译 jni 库,以及自动集成了。
另外,相关 gradle 配置基本跟 cmake 和 ndkbuild 的保持一致,大部分都是兼容的,切换成本也会降低很多。
欢迎大家来试试哦,新鲜出炉的插件,如果你想要了解更多,请参考:中
我们需要先安装好对应的xmake命令行工具,关于安装说明见:xmake。
plugins {
id 'org.tboox.gradle-xmake-plugin' version '1.0.7'
}
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'org.tboox:gradle-xmake-plugin:1.0.7'
}
repositories {
mavenCentral()
}
}
apply plugin: "org.tboox.gradle-xmake-plugin"
如果我们添加xmake.lua
文件到projectdir/jni/xmake.lua
,那么我们只需要在build.gradle中启用生效了xmake指定下对应的JNI工程路径即可。
android {
externalNativeBuild {
xmake {
path "jni/xmake.lua"
}
}
}
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验。
本文主要详细讲解下,如何通过配置子工程模块,来组织构建一个大规模的工程项目。
对于一些轻量型的小工程,通常只需要单个xmake.lua文件就能搞定,大体结构如下:
projectdir
- xmake.lua
- src
- test
- *.c
- demo
- *.c
源码下面层级简单,通常只需要在项目根目录维护一个xmake.lua来定义所有target就能完成构建,看上去并不是很复杂,也很清晰。
-- 在根域设置通用配置,当前所有targets都会生效
add_defines("COMMON")
target("test")
set_kind("static")
add_files("src/test/*.c")
add_defines("TEST")
target("demo")
set_kind("static")
add_files("src/demo/*.c")
add_defines("DEMO")
但是对于一些大型项目,通常的组织结构层次很多也很深,需要编译的target目标也可能有十几甚至上百个,这个时候如果还是都在根xmake.lua文件中维护,就有点吃不消了。
这个时候,我们就需要通过在每个子工程模块里面,单独创建xmake.lua来维护他们,然后使用xmake提供的includes接口,将他们按层级关系包含进来,最终变成一个树状结构:
projectdir
- xmake.lua
- src
- test
- xmake.lua
- test1
- xmake.lua
- test2
- xmake.lua
- test3
- xmake.lua
- demo
- xmake.lua
- demo1
- xmake.lua
- demo2
- xmake.lua
...
然后,根xmake.lua会将所有子工程的xmake.lua通过层级includes全部引用进来,那么所有定义在子工程的target配置也会完全引用进来,我们在编译的时候永远不需要单独去切到某个子工程目录下操作,只需要:
$ xmake build test1
$ xmake run test3
$ xmake install demo1
就可以编译,运行,打包以及安装指定的子工程target,所以除非特殊情况,平常不推荐来回切换目录到子工程下单独编译,非常的繁琐。
这个版本重点重构优化了下内部并行构建机制,实现多个target间源文件的并行编译,以及并行link的支持,同时优化了xmake的一些内部损耗,修复影响编译速度的一些bug。 通过测试对比,目前的整体构建速度基本跟ninja持平,相比cmake/make, meson/ninja都快了不少,因为它们还额外多了一步生成makefile/build.ninja的过程。
另外,xmake还增加了对sdcc编译工具链的支持,用于编译51/stm8等嵌入式程序。
更多优化细节可以看下:issue #589
我们在termux和macOS上做了一些对比测试,测试工程在: xmake-core
对于相对比较多的target的项目,新版xmake对其构建速度的提升更加明显。
构建系统 | Termux (8core/-j12) | 构建系统 | MacOS (8core/-j12) |
---|---|---|---|
xmake | 24.890s | xmake | 12.264s |
ninja | 25.682s | ninja | 11.327s |
cmake(gen+make) | 5.416s+28.473s | cmake(gen+make) | 1.203s+14.030s |
cmake(gen+ninja) | 4.458s+24.842s | cmake(gen+ninja) | 0.988s+11.644s |
构建系统 | Termux (-j1) | 构建系统 | MacOS (-j1) |
---|---|---|---|
xmake | 1m57.707s | xmake | 39.937s |
ninja | 1m52.845s | ninja | 38.995s |
cmake(gen+make) | 5.416s+2m10.539s | cmake(gen+make) | 1.203s+41.737s |
cmake(gen+ninja) | 4.458s+1m54.868s | cmake(gen+ninja) | 0.988s+38.022s |
这个版本功能和特性改动并不多,主要是改进了下协程的调度模块,实现对process, socket,pipe这三种对象间的统一调度支持,我们可以在协程中同时操作进程,socket还有管道。
这有赖于tbox提供的poller模块,统一封装了对epoll/kqueue/select/poll/iocp等接口,实现跨平台的等待socket/pipe对象事件,通过提供一致的reactor,实现了在协程中统一调度。
另外,poller还对进程事件的等待也加上了支持,可以通过相同的wait接口同时对process的退出事件进行等待,关于这块内部其实还是做了很多事的。
例如:
相关poller接口主要有下面四个,其中object可以是process/pipe/socket对象,然后设置上对应的事件就可以去同时wait了。
tb_bool_t tb_poller_insert(tb_poller_ref_t poller, tb_poller_object_ref_t object, tb_size_t events, tb_cpointer_t priv);
tb_bool_t tb_poller_remove(tb_poller_ref_t poller, tb_poller_object_ref_t object);
tb_bool_t tb_poller_modify(tb_poller_ref_t poller, tb_poller_object_ref_t object, tb_size_t events, tb_cpointer_t priv);
tb_long_t tb_poller_wait(tb_poller_ref_t poller, tb_poller_event_func_t func, tb_long_t timeout);
最近对xmake内部做了不少的重构来改进,并且新增了不少实用的新特性,欢迎来体验。
一些新特性:
xmake project -k ninja
工程生成插件,支持对build.ninja构建系统文件的生成一些改进点:
一些看不见的改进点:
还有一些零散的bug修复,见下文更新内容。
xmake现已支持对ninja构建文件的生成,让用户可以使用ninja来快速构建xmake维护的项目。不得不承认,目前就构建速度来讲,ninja确实比xmake快不少,后续版本我会尝试优化下xmake的构建速度。
$ xmake project -k ninja
然后调用ninja来构建:
$ ninja
或者直接使用xmake命令来调用ninja构建,见下文。
xmake v2.3.1以上版本直接对接了其他第三方构建系统,即使其他项目中没有使用xmake.lua来维护,xmake也可以直接调用其他构建工具来完成编译。
那用户直接调用使用第三方构建工具来编译不就行了,为啥还要用xmake去调用呢?主要有以下好处:
xmake config
的配置环境,复用xmake的平台探测和sdk环境检测,简化平台配置目前已支持的构建系统:
例如,对于一个使用cmake维护的项目,直接在项目根目录执行xmake,就会自动触发探测机制,检测到CMakeLists.txt,然后提示用户是否需要使用cmake来继续完成编译。
$ xmake
note: CMakeLists.txt found, try building it (pass -y or --confirm=y/n/d to skip confirm)?
please input: y (y/n)
-- Symbol prefix:
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/ruki/Downloads/libpng-1.6.35/build
[ 7%] Built target png-fix-itxt
[ 21%] Built target genfiles
[ 81%] Built target png
[ 83%] Built target png_static
...
output to /Users/ruki/Downloads/libpng-1.6.35/build/artifacts
build ok!