高級特性之自定義腳本使用

xmake提供了自定義打包、安裝、運行腳本,能夠更加靈活的針對我的實際需求來操做xmakejava

這裏用一個例子詳細說明下,好比有個需求,我須要自動編譯、安裝、運行android app工程,而且可以支持jni 能夠進行以下操做android

首先建立個基於ant的android app工程,目錄結構以下:git

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的測試demogithub

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後,就能夠很方便的使用了:shell

# 從新編譯工程,生成libdemo.so到app/libs/armeabi
xmake -r

# 打包app爲apk
xmake p

# 安裝apk到設備上
xmake i

# 運行app,並獲取日誌信息
xmake r demo

若是以爲上面的步驟有點繁瑣,能夠簡化成:bash

-- 安裝的時候,會先去自動打包,因此能夠省略xmake p
xmake -r; xmake i; xmake r demo

若是是增量編譯,不須要重建,能夠繼續簡化:app

xmake i; xmake r demo

固然,因爲是根據本身的實際需求自定義的腳本,可能跨平臺性有點弱,像這裏只能支持android的編譯平臺,工具

你也可使用 if plats("android") then ... end 來作一些跨平臺處理測試


相關文章
相關標籤/搜索