diff options
| -rw-r--r-- | README.md | 296 | ||||
| -rw-r--r-- | manual.md | 16 | ||||
| -rw-r--r-- | zh/README.md | 296 | ||||
| -rw-r--r-- | zh/manual.md | 16 |
4 files changed, 624 insertions, 0 deletions
@@ -386,6 +386,31 @@ target("qt_widgetapp") add_frameworks("QtWidgets") ``` +##### Android Application + +After the 2.2.6 version, you can directly switch to the android platform to compile the Quick/Widgets application, generate the apk package, and install it to the device via the `xmake install` command. + +```console +$ xmake create -t quickapp_qt -l c ++ appdemo +$ cd appdemo +$ xmake f -p android --ndk=~/Downloads/android-ndk-r19c/ --android_sdk=~/Library/Android/sdk/ -c +$ xmake +[0%]: compiling.qt.qrc src/qml.qrc +[ 50%]: ccache compiling.release src/main.cpp +[100%]: linking.release libappdemo.so +[100%]: generating.qt.app appdemo.apk +``` + +Then install to the device: + +```console +$ xmake install +installing appdemo ... +installing build/android/armv7-a/release/appdemo.apk .. +success +install ok!👌 +``` + #### Cuda Program Create an empty project: @@ -926,6 +951,277 @@ $ xmake f -p iphoneos -c $ xmake ``` +## Syntax Description + +xmake's project description file xmake.lua is based on the lua syntax, but in order to make the project build logic more convenient and concise, xmake encapsulates it, making writing xmake.lua not as cumbersome as some makefiles. + +Basically write a simple project build description, just three lines, for example: + +```lua +target("test") + set_kind("binary") + add_files("src/*.c") +``` + +#### Scope + +The description syntax of xmake is divided by scope, which is mainly divided into: + +- external scope +- Internal scope +- Interface scope + +Which ones belong to the outside and which ones belong to the inside? if you look at the comments below, you know what it is: + +```lua +-- external scope +target("test") + + -- external scope + set_kind("binary") + add_files("src/*.c") + + on_run(function () + -- Internal scope + end) + + after_package(function () + -- Internal scope + end) + +-- external scope +task("hello") + + -- external scope + on_run(function () + -- Internal scope + end) +``` + +Simply put, all within the custom script `function () end` belongs to the internal scope, which is the script scope, and all other places belong to the external scope. . + +##### external Scope + +For most projects, you don't need complicated engineering descriptions, and you don't need custom scripting support. You just need a simple `set_xxx` or `add_xxx` to meet your needs. + +Then according to the 28th law, 80% of the cases, we only need to write: + +```lua +target("test") + set_kind("static") + add_files("src/test/*.c") + +target("demo") + add_deps("test") + set_kind("binary") + add_links("test") + add_files("src/demo/*.c") +``` + +No complicated api calls, no complicated variable definitions, and if judgments and for loops. It's succinct and readable. At a glance, it doesn't matter if you don't understand lua grammar. + +As a simple description of the syntax, it looks a bit like a function call, you will know how to configure it at a basic point of programming. + +In order to be concise and secure, in this scope, many lua built-in apis are not open, especially related to writing files and modifying the operating environment, only providing some basic read-only interfaces, and logical operations. + +The current external scope lating lua built-in apis are: + +- table +- string +- pairs +- ipairs +- print +- os + +Of course, although the built-in lua api does not provide much, xmake also provides a lot of extension APIs. It is not much to describe the api. For details, please refer to: [API Manual] (https://xmake.io/#/zh/manual) + +There are also some auxiliary apis, for example: + +- dirs: scan to get all the directories in the currently specified path +- files: scan to get all the files in the current specified path +- format: format string, short version of string.format + +There are also variable definitions and logical operations that can be used. after all, it is based on lua. The basic syntax is still there. We can switch the compiled files by if: + +```lua +target("test") + set_kind("static") + if is_plat("iphoneos") then + add_files("src/test/ios/*.c") + else + add_files("src/test/*.c") + end +``` + +It should be noted that the variable definition is divided into global variables and local variables. The local variables are only valid for the current xmake.lua, and do not affect the child xmake.lua. + +```lua +-- local variables, only valid for current xmake.lua +local var1 = 0 + +-- global variables that affect all subsmake.lua included after includes() +var2 = 1 + +Includes("src") +``` + +##### Internal Scope + +Also known as plug-ins, script scope, provide more complex and flexible script support, generally used to write some custom scripts, plug-in development, custom task tasks, custom modules, etc. + +Usually included by `function () end`, and passed to the `on_xxx`, `before_xxx` and `after_xxx` interfaces, are all self-scoped. + +E.g: + +```lua +-- custom script +target("hello") + after_build(function () + -- Internal scope + end) + +-- custom tasks, plugins +task("hello") + on_run(function () + -- Internal scope + end) +``` + +In this scope, not only can you use most lua apis, but you can also use many extension modules provided by xmake. All extension modules are imported through import. + +For details, please refer to: [import module document](https://xmake.io/#/zh/manual?id=import) + +Here we give a simple example, after the compilation is complete, ldid signature on the ios target program: + +```lua +target("iosdemo") + set_kind("binary") + add_files("*.m") + after_build(function (target) + + -- Execute signature, if it fails, automatically interrupt, giving a highlight error message + Os.run("ldid -S$(projectdir)/entitlements.plist %s", target:targetfile()) + end) +``` + +It should be noted that in the internal scope, all calls are enabled with the exception catching mechanism. if the operation is wrong, xmake will be automatically interrupted and an error message will be given. + +Therefore, the script is written without the cumbersome `if retval then` judgment, and the script logic is more clear. + +##### Interface Scope + +All descriptions of api settings in the external scope are also scoped. They are called in different places and have different scopes of influence, for example: + +```lua +-- global root scope, affecting all targets, including subproject target settings in includes() +add_defines("DEBUG") + +-- define or enter the demo target scope (support multiple entry to append settings) +target("demo") + set_kind("shared") + add_files("src/*.c") + -- the current target scope only affects the current target + add_defines("DEBUG2") + +-- option settings, only local settings are supported, not affected by global api settings +option("test") + -- local scope of the current option + set_default(false) + +-- other target settings, -DDEBUG will also be set +target("demo2") + set_kind("binary") + add_files("src/*.c") + +-- re-enter the demo target scope +target("demo") + -- append macro definitions, only valid for the current demo target + add_defines("DEBUG3") +``` + +Normally, entering another target/option domain setting will automatically leave the previous target/option field, but sometimes in order to compare some scope pollution, we can show off a domain, for example: + +```lua +option("test") + set_default(false) +option_end() + +target("demo") + set_kind("binary") + add_files("src/*.c") +target_end() +``` + +Call `option_end()`, `target_end()` to explicitly leave the current target/option field setting. + +##### Scope indentation + +Indentation in xmake.lua is just a specification for more clear distinction. The current setting is for that scope, although it is ok even if it is not indented, but it is not very readable. . + +e.g: + +```lua +target("xxxx") + set_kind("binary") + add_files("*.c") +``` + +with + +```lua +target("xxxx") +set_kind("binary") +add_files("*.c") +``` + +The above two methods are the same in effect, but in understanding, the first one is more intuitive. At first glance, you know that `add_files` is only set for target, not global. + +Therefore, proper indentation helps to better maintain xmake.lua + +Finally attached, tbox's [xmake.lua](https://github.com/tboox/tbox/blob/master/src/tbox/xmake.lua) description, for reference only. . + +#### Syntax simplification + +The configuration field syntax of xmake.lua is very flexible and can be used in a variety of complex and flexible configurations in the relevant domain, but for many streamlined small block configurations, this time is slightly redundant: + +```lua +option("test1") + set_default(true) + set_showmenu(true) + set_description("test1 option") + +option("test2") + set_default(true) + set_showmeu(true) + +option("test3") + set_default("hello") +``` + +xmake 2.2.6 or later, for the above small block option domain settings, we can simplify the description into a single line: + +```lua +option("test1", {default = true, showmenu = true, description = "test1 option"}) +option("test2", {default = true, showmenu = true}) +option("test3", {default = "hello"}) +``` + +In addition to the option field, this simplified writing is also supported for other domains, such as: + +```lua +target("demo") + set_kind("binary") + add_files("src/*.c") +``` + +Simplified to: + +```lua +target("demo", {kind = "binary", files = "src/*.c"}) +``` + +Of course, if the configuration requirements are more complicated, or the original multi-line setting method is more convenient, this depends on your own needs to evaluate which method is used. + ## Dependency Package Management #### Local Package Mode @@ -752,6 +752,22 @@ please input: y (y/n) We can see https://github.com/xmake-io/xmake/issues/339 to know more details. +Add a clib dependency package: + +Clib is a source-based dependency package manager. The dependent package is downloaded directly to the corresponding library source code, integrated into the project to compile, rather than binary library dependencies. + +It is also very convenient to integrate in xmake. The only thing to note is that you need to add the source code of the corresponding library to xmake.lua, for example: + +```lua +add_requires("clib::clibs/bytes@0.0.4", {alias = "bytes"}) + +target("xmake-test") + set_kind("binary") + add_files("clib/bytes/*.c") + add_files("src/*.c") + add_packages("bytes") +``` + ##### add_repositories ###### Add 3rd package repositories diff --git a/zh/README.md b/zh/README.md index 785635f9..af6ba511 100644 --- a/zh/README.md +++ b/zh/README.md @@ -416,6 +416,31 @@ target("qt_widgetapp") add_frameworks("QtWidgets") ``` +##### Android应用程序 + +2.2.6之后版本,可以直接切到android平台编译Quick/Widgets应用程序,生成apk包,并且可通过`xmake install`命令安装到设备。 + +```console +$ xmake create -t quickapp_qt -l c++ appdemo +$ cd appdemo +$ xmake f -p android --ndk=~/Downloads/android-ndk-r19c/ --android_sdk=~/Library/Android/sdk/ -c +$ xmake +[ 0%]: compiling.qt.qrc src/qml.qrc +[ 50%]: ccache compiling.release src/main.cpp +[100%]: linking.release libappdemo.so +[100%]: generating.qt.app appdemo.apk +``` + +然后安装到设备: + +```console +$ xmake install +installing appdemo ... +installing build/android/armv7-a/release/appdemo.apk .. +Success +install ok!👌 +``` + #### Cuda程序 创建一个空工程: @@ -987,6 +1012,277 @@ $ xmake f -p iphoneos -c $ xmake ``` +## 语法说明 + +xmake的工程描述文件xmake.lua虽然基于lua语法,但是为了使得更加方便简洁得编写项目构建逻辑,xmake对其进行了一层封装,使得编写xmake.lua不会像些makefile那样繁琐 + +基本上写个简单的工程构建描述,只需三行就能搞定,例如: + +```lua +target("test") + set_kind("binary") + add_files("src/*.c") +``` + +#### 作用域 + +xmake的描述语法是按作用域划分的,主要分为: + +- 外部作用域 +- 内部作用域 +- 接口作用域 + +那哪些属于外部,哪些又属于内部呢,看看下面的注释,就知道个大概了: + +```lua +-- 外部作用域 +target("test") + + -- 外部作用域 + set_kind("binary") + add_files("src/*.c") + + on_run(function () + -- 内部作用域 + end) + + after_package(function () + -- 内部作用域 + end) + +-- 外部作用域 +task("hello") + + -- 外部作用域 + on_run(function () + -- 内部作用域 + end) +``` + +简单的说,就是在自定义脚本`function () end`之内的都属于内部作用域,也就是脚本作用域,其他地方都是都属于于外部作用域。。 + +##### 外部作用域 + +对于大部分工程来说,并不需要很复杂的工程描述,也不需要自定义脚本支持,只需要简单的 `set_xxx` 或者 `add_xxx` 就能满足需求了 + +那么根据二八定律,80%的情况下,我们只需要这么写: + +```lua +target("test") + set_kind("static") + add_files("src/test/*.c") + +target("demo") + add_deps("test") + set_kind("binary") + add_links("test") + add_files("src/demo/*.c") +``` + +不需要复杂的api调用,也不需要各种繁琐的变量定义,以及 if 判断 和 for 循环,要的就是简洁可读,一眼看过去,就算不懂lua语法也没关系 + +就当做简单的描述语法,看上去有点像函数调用而已,会点编程的基本一看就知道怎么配置。 + +为了做到简洁、安全,在这个作用域内,很多lua 内置api是不开放出来的,尤其是跟写文件、修改操作环境相关的,仅仅提供一些基本的只读接口,和逻辑操作 + +目前外部作用域开放的lua内置api有: + +- table +- string +- pairs +- ipairs +- print +- os + +当然虽然内置lua api提供不多,但xmake还提供了很多扩展api,像描述api就不多说,详细可参考:[API手册](https://xmake.io/#/zh/manual) + +还有些辅助api,例如: + +dirs:扫描获取当前指定路径中的所有目录 +files:扫描获取当前指定路径中的所有文件 +format: 格式化字符串,string.format的简写版本 + +还有变量定义、逻辑操作也是可以使用的,毕竟是基于lua的,该有的基础语法,还是要有的,我们可以通过if来切换编译文件: + +```lua +target("test") + set_kind("static") + if is_plat("iphoneos") then + add_files("src/test/ios/*.c") + else + add_files("src/test/*.c") + end +``` + +需要注意的是,变量定义分全局变量和局部变量,局部变量只对当前xmake.lua有效,不影响子xmake.lua + +```lua +-- 局部变量,只对当前xmake.lua有效 +local var1 = 0 + +-- 全局变量,影响所有之后 includes() 包含的子 xmake.lua +var2 = 1 + +includes("src") +``` + +##### 内部作用域 + +也称插件、脚本作用域,提供更加复杂、灵活的脚本支持,一般用于编写一些自定义脚本、插件开发、自定义task任务、自定义模块等等 + +一般通过`function () end`包含,并且被传入到`on_xxx`, `before_xxx`和`after_xxx`接口内的,都属于自作用域。 + +例如: + +```lua +-- 自定义脚本 +target("hello") + after_build(function () + -- 内部作用域 + end) + +-- 自定义任务、插件 +task("hello") + on_run(function () + -- 内部作用域 + end) +``` + +在此作用域中,不仅可以使用大部分lua的api,还可以使用很多xmake提供的扩展模块,所有扩展模块,通过import来导入 + +具体可参考:[import模块导入文档](https://xmake.io/#/zh/manual?id=import) + +这里我们给个简单的例子,在编译完成后,对ios目标程序进行ldid签名: + +```lua +target("iosdemo") + set_kind("binary") + add_files("*.m") + after_build(function (target) + + -- 执行签名,如果失败,自动中断,给出高亮错误信息 + os.run("ldid -S$(projectdir)/entitlements.plist %s", target:targetfile()) + end) +``` + +需要注意的是,在内部作用域中,所有的调用都是启用异常捕获机制的,如果运行出错,会自动中断xmake,并给出错误提示信息 + +因此,脚本写起来,不需要繁琐的`if retval then`判断,脚本逻辑更加一目了然 + +##### 接口作用域 + +在外部作用域中的所有描述api设置,本身也是有作用域之分的,在不同地方调用,影响范围也不相同,例如: + +```lua +-- 全局根作用域,影响所有target,包括includes() 中的子工程target设置 +add_defines("DEBUG") + +-- 定义或者进入demo目标作用域(支持多次进入来追加设置) +target("demo") + set_kind("shared") + add_files("src/*.c") + -- 当前target作用域,仅仅影响当前target + add_defines("DEBUG2") + +-- 选项设置,仅支持局部设置,不受全局api设置所影响 +option("test") + -- 当前选项的局部作用域 + set_default(false) + +-- 其他target设置,-DDEBUG 也会被设置上 +target("demo2") + set_kind("binary") + add_files("src/*.c") + +-- 重新进入demo目标作用域 +target("demo") + -- 追加宏定义,只对当前demo目标有效 + add_defines("DEBUG3") +``` + +通常情况下,进入另一个target/option域设置,会自动离开上个target/option域,但是有时候为了比较一些作用域污染情况,我们可以显示离开某个域,例如: + +```lua +option("test") + set_default(false) +option_end() + +target("demo") + set_kind("binary") + add_files("src/*.c") +target_end() +``` + +调用`option_end()`, `target_end()`即可显式的离开当前target/option域设置。 + +##### 作用域缩进 + +xmake.lua里面缩进,只是个编写规范,用于更加清楚的区分,当前的设置 是针对 那个作用域的,虽然就算不缩进,也一样ok,但是可读性上 并不是很好。。 + +例如: + +```lua +target("xxxx") + set_kind("binary") + add_files("*.c") +``` + +和 + +```lua +target("xxxx") +set_kind("binary") +add_files("*.c") +``` + +上述两种方式,效果上都是一样的,但是理解上,第一种更加直观,一看就知道`add_files`仅仅只是针对 target 设置的,并不是全局设置 + +因此,适当的进行缩进,有助于更好的维护xmake.lua + +最后附上,tbox的[xmake.lua](https://github.com/tboox/tbox/blob/master/src/tbox/xmake.lua)描述,仅供参考。。 + +#### 语法简化 + +xmake.lua的配置域语法,非常灵活,可以在相关域做各种复杂灵活的配置,但是对于许多精简的小块配置,这个时候就稍显冗余了: + +```lua +option("test1") + set_default(true) + set_showmenu(true) + set_description("test1 option") + +option("test2") + set_default(true) + set_showmeu(true) + +option("test3") + set_default("hello") +``` + +xmake 2.2.6以上版本,对于上面的这些小块option域设置,我们可以简化下成单行描述: + +```lua +option("test1", {default = true, showmenu = true, description = "test1 option"}) +option("test2", {default = true, showmenu = true}) +option("test3", {default = "hello"}) +``` + +除了option域,对于其他域也是支持这种简化写法的,例如: + +```lua +target("demo") + set_kind("binary") + add_files("src/*.c") +``` + +简化为: + +```lua +target("demo", {kind = "binary", files = "src/*.c"}) +``` + +当然,如果配置需求比较复杂的,还是原有的多行设置方式更加方便,这个就看自己的需求来评估到底使用哪种方式了。 + ## 依赖包管理 #### 本地内置模式 diff --git a/zh/manual.md b/zh/manual.md index ab35a950..d1cbb270 100644 --- a/zh/manual.md +++ b/zh/manual.md @@ -779,6 +779,22 @@ please input: y (y/n) 关于这块的更多详情见:https://github.com/xmake-io/xmake/issues/339 +添加clib的依赖包: + +clib是一款基于源码的依赖包管理器,拉取的依赖包是直接下载对应的库源码,集成到项目中编译,而不是二进制库依赖。 + +其在xmake中集成也很方便,唯一需要注意的是,还需要自己添加上对应库的源码到xmake.lua,例如: + +```lua +add_requires("clib::clibs/bytes@0.0.4", {alias = "bytes"}) + +target("xmake-test") + set_kind("binary") + add_files("clib/bytes/*.c") + add_files("src/*.c") + add_packages("bytes") +``` + ##### add_repositories ###### 添加依赖包仓库 |
