xmake-io / xmake

🔥 A cross-platform build utility based on Lua
https://xmake.io
Apache License 2.0
9.87k stars 776 forks source link

希望提供一个全局脚本域做一些处理函数,避免每个 target 重复执行 #5213

Closed TOMO-CAT closed 3 months ago

TOMO-CAT commented 3 months ago

你在什么场景下需要该功能?

当前我有多个单测 target 需要依赖一些测试数据,当前的做法是写了一个 rule,让每个 test target 都去依赖:

rule("prepare_test_data", function()
    add_deps("external_confs")

    local function prepare_test_data_impl(target)
        os.trycp("localization/loc_archon/*.conf", target:rundir(), {rootdir = "."})
        os.trycp("localization/loc_archon/*.yaml", target:rundir(), {rootdir = "."})
        os.trycp("localization/**.conf", target:rundir(), {rootdir = "."})
        os.trycp("localization/test_data/**", target:rundir(), {rootdir = "."})
    end

    before_run(prepare_test_data_impl)
    before_test(prepare_test_data_impl)
end)

target("localization.multi_sensor_fusion_component.multi_sensor_fusion_test",
       function()
    set_kind("binary")
    set_default(false)
    add_tests("default", {run_timeout = 60 * 1000})
    add_files("multi_sensor_fusion_test.cc")
    add_deps("localization.controller",
             "localization.multi_sensor_fusion_component")
    add_packages("gtest")
    add_packages("zcore")
    add_rules("prepare_test_data")  -- 依赖 rule 准备文件
end)

在我这个场景下全局只需要拷贝一次文件就行,但是现在每个文件都要拷贝一次,在并发运行单测的时候会失败: image

重试一次就成功了。

描述可能的解决方案

目前我是强制 xmake test -j1 去掉并发,但是这样会导致运行单测速度很慢。如果是写一堆 if else 判断文件是否存在也不太合适,希望提供一个每次执行 xmake 只运行一次脚本的方法,让我每次运行单测只拷贝一次数据。

描述你认为的候选方案

No response

其他信息

No response

Issues-translate-bot commented 3 months ago

Bot detected the issue body's language is not English, translate it automatically.


Title: Hope to provide a global script domain to do some processing functions to avoid repeated execution of each target

In what scenario do you need this feature?

Currently I have multiple single test targets that need to rely on some test data. The current approach is to write a rule so that each test target depends on:

rule("prepare_test_data", function()
    add_deps("external_confs")

    local function prepare_test_data_impl(target)
        os.trycp("localization/loc_archon/*.conf", target:rundir(), {rootdir = "."})
        os.trycp("localization/loc_archon/*.yaml", target:rundir(), {rootdir = "."})
        os.trycp("localization/**.conf", target:rundir(), {rootdir = "."})
        os.trycp("localization/test_data/**", target:rundir(), {rootdir = "."})
    end

    before_run(prepare_test_data_impl)
    before_test(prepare_test_data_impl)
end)

target("localization.multi_sensor_fusion_component.multi_sensor_fusion_test",
       function()
    set_kind("binary")
    set_default(false)
    add_tests("default", {run_timeout = 60 * 1000})
    add_files("multi_sensor_fusion_test.cc")
    add_deps("localization.controller",
             "localization.multi_sensor_fusion_component")
    add_packages("gtest")
    add_packages("zcore")
    add_rules("prepare_test_data") -- Dependency rule preparation file
end)

In my scenario, you only need to copy the file once globally, but now each file needs to be copied once, and it will fail when running single tests concurrently: image

One more try and it worked.

Describe possible solutions

At present, I force xmake test -j1 to remove concurrency, but this will cause the running speed of single test to be very slow. It is not appropriate to write a bunch of if else to determine whether the file exists. I hope to provide a method that only runs the script once every time xmake is executed, so that I can only copy the data once every time I run a single test.

Describe your alternatives

No response

other information

No response

waruqi commented 3 months ago
rule("foo")
    before_run(function (target)
        if not _g.first then
            _g.first = true
            print("run once")
        end
    end)
TOMO-CAT commented 3 months ago
rule("foo")
    before_run(function (target)
        if not _g.first then
            _g.first = true
            print("run once")
        end
    end)

可以的高级。