فهرست منبع

adding wgsl-validator package (and rust cross-compilation support) (#7023)

* adding wgsl-validator package

* fixing windows issues ?

* removing links only for static config

* adding shared config

* removing shared linking

* Update xmake.lua

* adding rust's stdlib installation

* disabling rust auto update

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update cross.yml

* Update xmake.lua

* Update xmake.lua

* Update cross.yml

* Final touch

* Update cross.yml

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

* Update xmake.lua

---------

Co-authored-by: Jérôme Leclercq <[email protected]>
kbz_8 3 ماه پیش
والد
کامیت
29b127c1e8
4فایلهای تغییر یافته به همراه215 افزوده شده و 10 حذف شده
  1. 76 5
      packages/r/rust/xmake.lua
  2. 72 0
      packages/r/rustlib/xmake.lua
  3. 9 5
      packages/r/rustup/xmake.lua
  4. 58 0
      packages/w/wgsl-validator/xmake.lua

+ 76 - 5
packages/r/rust/xmake.lua

@@ -5,13 +5,84 @@ package("rust")
 
     add_versions("1.86.0", "")
 
-    add_deps("rustup", {private = true})
+    add_deps("ca-certificates", {host = true, private = true})
+    add_deps("rustup", {host = true, private = true, system = false})
 
-    on_install("@windows|x86", "@windows|x64", "@windows|arm64", "@msys", "@cygwin", "@bsd", "@linux", "@macosx", function (package)
-        local rustup = package:dep("rustup"):installdir()
+    add_configs("target_plat", {description = "Target platform (for cross-compilation)", default = nil, type = "string"})
+    add_configs("target_arch", {description = "Target arch (for cross-compilation)", default = nil, type = "string"})
+    if is_plat("cross") then
+        add_configs("target_system", {description = "Target system (for cross-compilation)", default = "unknown-linux", type = "string"})
+        add_configs("target_abi", {description = "Target ABI (for cross-compilation)", default = "gnu", type = "string"})
+    end
+
+    on_load(function (package)
+        if package:config("target_plat") == nil then
+            package:config_set("target_plat", package:plat())
+        end
+        if package:config("target_arch") == nil then
+            package:config_set("target_arch", package:arch())
+        end
+    end)
+
+    on_install(function (package)
+        import("core.tools.rustc.target_triple", {try = true}) -- introduced in xmake 3.0.0
+
+        local plat = package:config("target_plat")
+        local arch = package:config("target_arch")
+
+        if not target_triple then
+            if plat == "mingw" or plat == "msys" then
+                plat = "windows"
+            end
+            local package_plat = package:plat()
+            if package_plat == "mingw" or package_plat == "msys" then
+                package_plat = "windows"
+            end
+            if plat ~= package_plat or arch ~= package:arch() then
+                os.raise("rust cross-compilation requires xmake dev or xmake 3.0.0")
+            end
+        end
+
+        local rustup = assert(os.getenv("RUSTUP_HOME"), "cannot find rustup home!")
         local version = package:version():shortstr()
-        os.vrunv("rustup", {"install", version})
-        os.mv(path.join(rustup, ".rustup", "toolchains", version .. "-*", "*"), package:installdir())
+
+        local toolchain_name = version
+        local toolchain_dir
+
+        if target_triple then
+            local host_target = assert(target_triple(package:plat(), package:arch()), "failed to build target triple for plat/arch, if you think this is a bug please create an issue")
+            toolchain_name = toolchain_name .. "-" .. host_target
+            toolchain_dir = toolchain_name
+        elseif package:is_plat("msys", "mingw") and is_host("windows") then
+            -- we have to handle mingw case because rustup will install a msvc toolchain by default on Windows
+            toolchain_name = toolchain_name .. (package:is_arch("i386") and "-x86_64-pc-windows-gnu" or "-i686-pc-windows-gnu")
+            toolchain_dir = toolchain_name
+        else
+            toolchain_dir = toolchain_name .. "-*"
+        end
+        os.vrunv("rustup", {"install", "--no-self-update", toolchain_name})
+
+        if target_triple or plat == "cross" then
+            local target
+            if plat == "cross" then
+                local system = package:config("target_system")
+                local abi = package:config("target_abi")
+                target = arch .. "-" .. system .. "-" .. abi
+            else
+                target = assert(target_triple(plat, arch), "failed to build target triple for target_plat/target_arch, if you think this is a bug please create an issue")
+            end
+
+            if target ~= host_target then
+                os.vrunv("rustup", {"target", "add", target})
+            end
+        end
+
+        os.vmv(path.join(rustup, "toolchains", toolchain_dir, "*"), package:installdir())
+
+        -- cleanup to prevent rustup to think the toolchain is still installed
+        os.vrm(path.join(rustup, "toolchains", toolchain_dir))
+        os.vrm(path.join(rustup, "update-hashes", toolchain_dir))
+
         package:addenv("RC", "bin/rustc" .. (is_host("windows") and ".exe" or ""))
         package:mark_as_pathenv("RC")
     end)

+ 72 - 0
packages/r/rustlib/xmake.lua

@@ -0,0 +1,72 @@
+package("rustlib")
+    set_kind("template")
+    set_description("Template to help with Rust libraries in xrepo")
+ 
+    on_load(function (package)
+        local toolchainconfigs = {}
+        toolchainconfigs.target_plat = package:plat()
+        toolchainconfigs.target_arch = package:arch()
+
+        if package:is_plat("cross") then
+            -- detect cross configuration from the compiler, if possible
+            local compiler, toolname = package:tool("cc")
+            if toolname == "clang" or toolname == "gcc" then
+                local outdata, errdata = os.iorunv(compiler, {"-v"})
+                local output = #outdata:trim() > 0 and outdata or errdata
+                local target = output:match("Target: ([^\r\n]*)")
+                if target then
+                    if toolname == "gcc" then
+                        target = target:replace("-none-", "-unknown-", {plain = true})
+                    end
+                    package:data_set("cross_target", target)
+                    local parts = target:split("-", {plain = true})
+                    if #parts >= 3 then
+                        toolchainconfigs.target_arch = parts[1]
+                        toolchainconfigs.target_system = table.concat(parts, "-", 2, #parts - 1)
+                        toolchainconfigs.target_abi = parts[#parts]
+                    end
+                end
+            end
+        end
+
+        package:add("deps", "rust", {configs = toolchainconfigs})
+    end)
+
+    on_check("mingw|i386", function (package)
+        -- MinGW 32bits exception model must match rustc LLVM exception model (dwarf2)
+        local mingw = package:toolchain("mingw")
+        if not mingw then
+            return
+        end
+
+        local compiler, toolname = mingw:tool("cc")
+        if toolname ~= "gcc" then
+            return
+        end
+
+        local output, errdata = os.iorunv(compiler, {"-v"})
+        -- for some reason the output is in stderr
+        if #output:trim() == 0 then
+            output = errdata
+        end
+        assert(output:find("--with-dwarf2", 1, true), "rustc is only compatible with dwarf2 exception model in 32bits mode, please use dwarf2 MinGW")
+    end)
+
+    on_install(function (package)
+        -- pass rust toolchain configuration
+        local rust = package:dep("rust")
+        local rcfile_path = os.tmpfile() .. ".lua"
+        local rcfile = io.open(rcfile_path, 'w')
+        rcfile:print("add_requires(\"rust\", %s)", string.serialize(rust:requireinfo(), {strip = true, indent = false}))
+        local cross_target = package:data("cross_target")
+        if cross_target then
+            rcfile:print("add_requireconfs(\"cargo::naga\", {arch = \"%s\", override = true})", cross_target)
+            rcfile:print("add_rcflags(\"--target=%s\")", cross_target)
+        end
+        rcfile:close()
+
+        local envs = import("package.tools.xmake").buildenvs(package)
+        table.insert(envs.XMAKE_RCFILES, rcfile_path)
+
+        package:data_set("xmake_envs", envs)
+    end)

+ 9 - 5
packages/r/rustup/xmake.lua

@@ -30,11 +30,7 @@ package("rustup")
         add_extsources("brew::rustup")
     end
 
-    on_install("@windows|x86", "@windows|x64", "@windows|arm64", "@msys", "@cygwin", "@bsd", "@linux", "@macosx", function (package)
-        local installdir = package:installdir()
-        local argv = {"--no-modify-path", "--profile=minimal", "--default-toolchain=none", "-y"}
-        local envs = {CARGO_HOME = path.join(installdir, ".cargo"), RUSTUP_HOME = path.join(installdir, ".rustup"), RUSTUP_INIT_SKIP_PATH_CHECK = "yes", RUSTUP_VERSION = package:version():shortstr()}
-        os.vrunv(package:originfile(), argv, {envs = envs, shell = not is_host("windows")})
+    on_load(function (package)
         package:addenv("PATH", path.join(".cargo", "bin"))
         package:setenv("CARGO_HOME", ".cargo")
         package:setenv("RUSTUP_HOME", ".rustup")
@@ -42,6 +38,14 @@ package("rustup")
         package:mark_as_pathenv("RUSTUP_HOME")
     end)
 
+    on_install("@windows|x86", "@windows|x64", "@windows|arm64", "@msys", "@cygwin", "@bsd", "@linux", "@macosx", function (package)
+        local installdir = package:installdir()
+        local argv = {"--no-modify-path", "--no-update-default-toolchain", "--profile=minimal", "--default-toolchain=none", "-y"}
+        local envs = {CARGO_HOME = path.join(installdir, ".cargo"), RUSTUP_HOME = path.join(installdir, ".rustup"), RUSTUP_INIT_SKIP_PATH_CHECK = "yes", RUSTUP_VERSION = package:version():shortstr()}
+        os.vrunv(package:originfile(), argv, {envs = envs, shell = not is_host("windows")})
+        os.vrunv(path.join(installdir, ".cargo", "bin", "rustup" .. (is_host("windows") and ".exe" or "")), {"set", "auto-self-update", "disable"}, {envs = envs})
+    end)
+
     on_test(function (package)
         os.vrunv("rustup", {"--version"})
     end)

+ 58 - 0
packages/w/wgsl-validator/xmake.lua

@@ -0,0 +1,58 @@
+package("wgsl-validator")
+    set_base("rustlib")
+    set_kind("library")
+    set_homepage("https://github.com/NazaraEngine/wgsl-validator")
+    set_description("WGSL validator in Rust with C bindings.")
+    set_license("MIT")
+
+    add_urls("https://github.com/NazaraEngine/wgsl-validator/archive/refs/tags/$(version).tar.gz",
+             "https://github.com/NazaraEngine/wgsl-validator.git")
+
+    add_versions("v1.0.0", "1ea4c13cc548bc785920d5b80ff94ccb97587ca69389c6b7d41f734e9f6b056b")
+
+    add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = true})
+
+    if is_plat("windows", "mingw") then
+        add_syslinks("Advapi32", "User32", "Userenv", "WS2_32", "RuntimeObject", "NtDll")
+    elseif is_plat("linux", "bsd") then
+        add_syslinks("pthread")
+    end
+
+    on_install(function (package)
+        package:base():script("install")(package)
+        local envs = package:data("xmake_envs")
+
+        io.writefile("xmake.lua", [[
+            add_requires("cargo::naga latest", {configs = {features = "wgsl-in"}})
+
+            target("wgsl-validator")
+                set_kind("static")
+                set_toolchains("rust@rust")
+                add_files("src/lib.rs")
+                add_headerfiles("ffi/*.h")
+                set_values("rust.cratetype", "staticlib")
+                add_packages("cargo::naga")
+        ]])
+        import("package.tools.xmake").install(package, nil, {envs = envs})
+    end)
+
+    on_test(function (package)
+        assert(package:check_csnippets({test = [[
+            #include <wgsl_validator.h>
+            #define WGSL_SOURCE(...) #__VA_ARGS__
+            const char* wgsl_source = WGSL_SOURCE(
+                @fragment
+                fn main_fs() -> @location(0) vec4<f32> {
+                    return vec4<f32>(1.0, 1.0, 1.0, 1.0);
+                }
+            );
+
+            void test() {
+                char* error;
+                wgsl_validator_t* validator = wgsl_validator_create();
+                if(wgsl_validator_validate(validator, wgsl_source, &error))
+                    wgsl_validator_free_error(error);
+                wgsl_validator_destroy(validator);
+            }
+        ]]}, { configs = { languages = "c17" } }))
+    end)