summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-07-10 09:27:29 +0800
committerGitHub <[email protected]>2025-07-10 09:27:29 +0800
commit8a632516c4ef457032067d075bc7aabf81599aa2 (patch)
treedd5caac84edec67cbeec6a68d273ce7c45806ea9
parent627075e248c4e2619964f7e17a8a1ea046001f36 (diff)
parentf1858dac8ef6e7a9f74a116610e5911b7941e72a (diff)
Merge pull request #6606 from IMXEren/rust-fix
fix: rust static and shared library failing to find extern crate in windows-msvc
-rw-r--r--xmake/rules/rust/xmake.lua43
-rw-r--r--xmake/rules/utils/inherit_links/inherit_links.lua8
-rw-r--r--xmake/templates/rust/shared/project/src/foo.rs4
-rw-r--r--xmake/templates/rust/shared/project/src/main.rs6
-rw-r--r--xmake/templates/rust/shared/project/xmake.lua10
-rw-r--r--xmake/templates/rust/shared/template.lua2
6 files changed, 70 insertions, 3 deletions
diff --git a/xmake/rules/rust/xmake.lua b/xmake/rules/rust/xmake.lua
index dfdf1d047..3875f10ff 100644
--- a/xmake/rules/rust/xmake.lua
+++ b/xmake/rules/rust/xmake.lua
@@ -32,6 +32,9 @@ rule("rust.cxxbridge")
rule("rust.build")
set_sourcekinds("rc")
on_load(function (target)
+ -- set cratename
+ local cratename = target:values("rust.cratename") or target:name()
+ target:set("basename", cratename)
-- set cratetype
local cratetype = target:values("rust.cratetype")
if cratetype == "staticlib" then
@@ -43,19 +46,32 @@ rule("rust.build")
target:add("shflags", "--crate-type=cdylib", {force = true})
target:add("shflags", "-C prefer-dynamic", {force = true})
elseif target:is_static() then
+ cratetype = "lib"
+ target:set("values", "rust.cratetype", cratetype)
+ if is_plat("windows") then
+ target:set("prefixname", "lib")
+ end
target:set("extension", ".rlib")
- target:add("arflags", "--crate-type=lib", {force = true})
+ target:add("arflags", "--crate-type=" .. cratetype, {force = true})
target:data_set("inherit.links.deplink", false)
elseif target:is_shared() then
- target:add("shflags", "--crate-type=dylib", {force = true})
+ cratetype = "dylib"
+ target:set("values", "rust.cratetype", cratetype)
+ target:add("shflags", "--crate-type=" .. cratetype, {force = true})
-- fix cannot satisfy dependencies so `std` only shows up once
-- https://github.com/rust-lang/rust/issues/19680
--
-- but it will link dynamic @rpath/libstd-xxx.dylib,
-- so we can no longer modify and set other rpath paths
target:add("shflags", "-C prefer-dynamic", {force = true})
+ -- don't add links and instead use --extern CRATE[=PATH]
+ -- also, it'll automatically link from linkdirs (-L) even if no --extern
+ -- https://github.com/xmake-io/xmake/issues/6604
+ target:data_set("inherit.links.deplink", false)
elseif target:is_binary() then
- target:add("ldflags", "--crate-type=bin", {force = true})
+ cratetype = "bin"
+ target:set("values", "rust.cratetype", cratetype)
+ target:add("ldflags", "--crate-type=" .. cratetype, {force = true})
end
-- set edition
@@ -81,6 +97,27 @@ rule("rust.build")
end)
on_build("build.target")
+ on_config(function (target)
+ import("lib.detect.find_tool")
+
+ -- Ensure libstd shared library is available when running
+ local rc = find_tool("rustc")
+ assert(rc, "rustc not found. Failed to add libstd in env")
+ local outdata, errdata = os.iorunv(rc.program, {"--print=sysroot"})
+ assert(not errdata or errdata == "", "failed to find rust sysroot:\n" .. errdata)
+ local rustc_sysroot = outdata:trim()
+ if target:is_plat("windows") then
+ local libstd = path.join(rustc_sysroot, "bin")
+ target:add("runenvs", "PATH", libstd)
+ elseif target:is_plat("macosx") then
+ local libstd = path.join(rustc_sysroot, "lib")
+ target:add("runenvs", "DYLD_LIBRARY_PATH", libstd)
+ else
+ local libstd = path.join(rustc_sysroot, "lib")
+ target:add("runenvs", "LD_LIBRARY_PATH", libstd)
+ end
+ end)
+
rule("rust")
add_deps("rust.build")
add_deps("utils.inherit.links")
diff --git a/xmake/rules/utils/inherit_links/inherit_links.lua b/xmake/rules/utils/inherit_links/inherit_links.lua
index 8a61a2874..b4b293d66 100644
--- a/xmake/rules/utils/inherit_links/inherit_links.lua
+++ b/xmake/rules/utils/inherit_links/inherit_links.lua
@@ -91,6 +91,14 @@ function main(target)
-- we need to add includedirs to support import modules for golang
_add_export_value(target, "includedirs", path.directory(targetfile))
end
+
+ if target:rule("rust") then
+ local cratetype = target:values("rust.cratetype")
+ -- only bin, lib, rlib, dylib can make use of --extern CRATE[=PATH]
+ if cratetype ~= "staticlib" and cratetype ~= "cdylib" then
+ _add_export_value(target, "frameworks", target:targetfile())
+ end
+ end
end
-- we export all links and linkdirs in self/packages/options to the parent target by default
diff --git a/xmake/templates/rust/shared/project/src/foo.rs b/xmake/templates/rust/shared/project/src/foo.rs
new file mode 100644
index 000000000..a3a3aa4a6
--- /dev/null
+++ b/xmake/templates/rust/shared/project/src/foo.rs
@@ -0,0 +1,4 @@
+pub fn add(a: i32, b: i32) -> i32 {
+ return a + b;
+}
+
diff --git a/xmake/templates/rust/shared/project/src/main.rs b/xmake/templates/rust/shared/project/src/main.rs
new file mode 100644
index 000000000..205d23da3
--- /dev/null
+++ b/xmake/templates/rust/shared/project/src/main.rs
@@ -0,0 +1,6 @@
+extern crate foo;
+
+fn main() {
+ println!("hello xmake!");
+ println!("add: {}", foo::add(1, 1));
+}
diff --git a/xmake/templates/rust/shared/project/xmake.lua b/xmake/templates/rust/shared/project/xmake.lua
new file mode 100644
index 000000000..d20b6f5d7
--- /dev/null
+++ b/xmake/templates/rust/shared/project/xmake.lua
@@ -0,0 +1,10 @@
+target("foo")
+ set_kind("shared")
+ add_files("src/foo.rs")
+
+target("${TARGETNAME}_demo")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.rs")
+
+${FAQ}
diff --git a/xmake/templates/rust/shared/template.lua b/xmake/templates/rust/shared/template.lua
new file mode 100644
index 000000000..d7ec5bae4
--- /dev/null
+++ b/xmake/templates/rust/shared/template.lua
@@ -0,0 +1,2 @@
+template("shared")
+ add_configfiles("xmake.lua")