package("rust")
set_kind("toolchain")
set_homepage("https://rust-lang.org")
set_description("Rust is a general-purpose programming language emphasizing performance, type safety, and concurrency.")
add_versions("1.86.0", "")
add_deps("ca-certificates", {host = true, private = true})
add_deps("rustup", {host = true, private = true, system = false})
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})
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()
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
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())
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)
on_test(function (package)
os.vrun("cargo --version")
os.vrun("rustc --version")
end)