summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-04-02 15:31:51 +0800
committerGitHub <[email protected]>2022-04-02 15:31:51 +0800
commit403a5a5ebf8286465a1e7d9e2a06a49281bc4008 (patch)
tree2b9e84a76435cb65d2ebcf29292e1f4776cabb52
parent8b687b4bff48f28bcd991408b0ca0fece7605515 (diff)
parentbcf8fe42e129bb8f350d812041a9005ebbb589b6 (diff)
Merge pull request #2235 from xmake-io/cargo
Improve cargo package with Cargo.toml file
-rw-r--r--CHANGELOG.md2
-rw-r--r--tests/projects/rust/cargo_deps_with_toml/Cargo.toml9
-rw-r--r--tests/projects/rust/cargo_deps_with_toml/src/main.rs12
-rw-r--r--tests/projects/rust/cargo_deps_with_toml/xmake.lua7
-rw-r--r--xmake/modules/package/manager/cargo/configurations.lua1
-rw-r--r--xmake/modules/package/manager/cargo/find_package.lua48
-rw-r--r--xmake/modules/package/manager/cargo/install_package.lua40
7 files changed, 99 insertions, 20 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e17b945f5..e259bd069 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
* [#2138](https://github.com/xmake-io/xmake/issues/2138): Support template package
* [#2185](https://github.com/xmake-io/xmake/issues/2185): Add `--appledev=simulator` to improve apple simulator support
+* [#2227](https://github.com/xmake-io/xmake/issues/2227): Improve cargo package with Cargo.toml file
### Changes
@@ -1237,6 +1238,7 @@
* [#2138](https://github.com/xmake-io/xmake/issues/2138): 支持模板包
* [#2185](https://github.com/xmake-io/xmake/issues/2185): 添加 `--appledev=simulator` 去改进 Apple 模拟器目标编译支持
+* [#2227](https://github.com/xmake-io/xmake/issues/2227): 改进 cargo 包,支持指定 Cargo.toml 文件
### 改进
diff --git a/tests/projects/rust/cargo_deps_with_toml/Cargo.toml b/tests/projects/rust/cargo_deps_with_toml/Cargo.toml
new file mode 100644
index 000000000..81919c567
--- /dev/null
+++ b/tests/projects/rust/cargo_deps_with_toml/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "test"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+base64 = "0.13.0"
+flate2 = {version = "1.0.17", features = ["zlib"]}
+
diff --git a/tests/projects/rust/cargo_deps_with_toml/src/main.rs b/tests/projects/rust/cargo_deps_with_toml/src/main.rs
new file mode 100644
index 000000000..f1ec987bf
--- /dev/null
+++ b/tests/projects/rust/cargo_deps_with_toml/src/main.rs
@@ -0,0 +1,12 @@
+extern crate base64;
+
+use base64::{encode, decode};
+
+fn main() {
+ let a = b"hello world";
+ let b = "aGVsbG8gd29ybGQ=";
+
+ assert_eq!(encode(a), b);
+ assert_eq!(a, &decode(b).unwrap()[..]);
+ println!("{}", encode(a));
+}
diff --git a/tests/projects/rust/cargo_deps_with_toml/xmake.lua b/tests/projects/rust/cargo_deps_with_toml/xmake.lua
new file mode 100644
index 000000000..b9f878c13
--- /dev/null
+++ b/tests/projects/rust/cargo_deps_with_toml/xmake.lua
@@ -0,0 +1,7 @@
+add_rules("mode.release", "mode.debug")
+add_requires("cargo::test", {configs = {cargo_toml = path.join(os.projectdir(), "Cargo.toml")}})
+
+target("test")
+ set_kind("binary")
+ add_files("src/main.rs")
+ add_packages("cargo::test")
diff --git a/xmake/modules/package/manager/cargo/configurations.lua b/xmake/modules/package/manager/cargo/configurations.lua
index a3f85a0ea..9a8b7f89f 100644
--- a/xmake/modules/package/manager/cargo/configurations.lua
+++ b/xmake/modules/package/manager/cargo/configurations.lua
@@ -24,5 +24,6 @@ function main()
{
features = {description = "set the features of dependency."},
default_features = {description = "enables or disables any defaults provided by the dependency.", default = true},
+ cargo_toml = {description = "set Cargo.toml file path"}
}
end
diff --git a/xmake/modules/package/manager/cargo/find_package.lua b/xmake/modules/package/manager/cargo/find_package.lua
index 08b3acb39..68fc60445 100644
--- a/xmake/modules/package/manager/cargo/find_package.lua
+++ b/xmake/modules/package/manager/cargo/find_package.lua
@@ -21,11 +21,44 @@
-- imports
import("core.base.option")
import("core.base.semver")
+import("core.base.hashset")
import("core.project.config")
import("core.project.target")
import("lib.detect.find_tool")
import("lib.detect.find_file")
+-- get the name set of libraries
+function _get_names_of_libraries(name, configs)
+ local names = hashset.new()
+ if configs.cargo_toml then
+ local dependencies = false
+ local cargo_file = io.open(configs.cargo_toml)
+ for line in cargo_file:lines() do
+ line = line:trim()
+ if not dependencies and line == "[dependencies]" then
+ dependencies = true
+ elseif dependencies then
+ if not line:startswith("[") then
+ local splitinfo = line:split("=", {plain = true})
+ if splitinfo and #splitinfo > 1 then
+ name = splitinfo[1]:trim()
+ if #name > 0 then
+ names:insert("lib" .. name:gsub("-", "_"))
+ end
+ end
+ else
+ break
+ end
+ end
+ end
+ cargo_file:close()
+ else
+ -- rust packages like actix-web will produce a file named actix_web-<...>
+ names:insert("lib" .. name:gsub("-", "_"))
+ end
+ return names
+end
+
-- find package using the cargo package manager
--
-- @param name the package name
@@ -33,8 +66,13 @@ import("lib.detect.find_file")
--
function main(name, opt)
- -- Rust packages like actix-web will produce a file named actix_web-<...>
- name = name:gsub("-", "_")
+ -- get configs
+ opt = opt or {}
+ local configs = opt.configs or {}
+
+ -- get names of libraries
+ local names = _get_names_of_libraries(name, configs)
+ assert(not names:empty())
local frameworkdirs
local frameworks
@@ -42,19 +80,19 @@ function main(name, opt)
local libfiles = os.files(path.join(librarydir, "*.rlib"))
for _, libraryfile in ipairs(libfiles) do
local filename = path.filename(libraryfile)
- if filename:startswith("lib" .. name .. "-") then
+ local libraryname = filename:split('-', {plain = true})[1]
+ if names:has(libraryname) then
frameworkdirs = frameworkdirs or {}
frameworks = frameworks or {}
table.insert(frameworkdirs, librarydir)
table.insert(frameworks, libraryfile)
- break
end
end
local result
if frameworks and frameworkdirs then
result = result or {}
result.libfiles = libfiles
- result.frameworkdirs = frameworkdirs
+ result.frameworkdirs = frameworkdirs and table.unique(frameworkdirs) or nil
result.frameworks = frameworks
result.version = opt.require_version
end
diff --git a/xmake/modules/package/manager/cargo/install_package.lua b/xmake/modules/package/manager/cargo/install_package.lua
index 9ea709dd7..60c811291 100644
--- a/xmake/modules/package/manager/cargo/install_package.lua
+++ b/xmake/modules/package/manager/cargo/install_package.lua
@@ -29,6 +29,7 @@ import("lib.detect.find_tool")
-- add_requires("cargo::base64")
-- add_requires("cargo::base64 0.13.0")
-- add_requires("cargo::flate2 1.0.17", {configs = {features = {"zlib"}, ["default-features"] = false}})
+-- add_requires("cargo::xxx", {configs = {cargo_toml = path.join(os.projectdir(), "Cargo.toml")}})
--
-- @param name the package name, e.g. cargo::base64
-- @param opt the options, e.g. { verbose = true, mode = "release", plat = , arch = , require_version = "x.x.x"}
@@ -51,25 +52,34 @@ function main(name, opt)
require_version = "*"
end
- -- build dependencies
- local sourcedir = path.join(opt.cachedir, "source")
+ -- @note we cannot use local cachedir as sourcedir, because it maybe will conflict with the parent root Cargo.toml
+ -- @see https://github.com/rust-lang/cargo/issues/10534
+ -- local sourcedir = path.join(opt.cachedir, "source")
+ local sourcedir = path.join(os.tmpfile({ramdisk = true}) .. ".dir", "cargo", "source")
+
+ -- generate Cargo.toml
local cargotoml = path.join(sourcedir, "Cargo.toml")
os.tryrm(sourcedir)
- local tomlfile = io.open(cargotoml, "w")
- tomlfile:print("[package]")
- tomlfile:print("name = \"cargodeps\"")
- tomlfile:print("version = \"0.1.0\"")
- tomlfile:print("edition = \"2018\"")
- tomlfile:print("")
- tomlfile:print("[dependencies]")
- local features = configs.features
- if features then
- features = table.wrap(features)
- tomlfile:print("%s = {version = \"%s\", features = [\"%s\"], default-features = %s}", name, require_version, table.concat(features, "\", \""), configs.default_features)
+ if configs.cargo_toml then
+ assert(os.isfile(configs.cargo_toml), "%s not found!", configs.cargo_toml)
+ os.cp(configs.cargo_toml, cargotoml)
else
- tomlfile:print("%s = \"%s\"", name, require_version)
+ local tomlfile = io.open(cargotoml, "w")
+ tomlfile:print("[package]")
+ tomlfile:print("name = \"cargodeps\"")
+ tomlfile:print("version = \"0.1.0\"")
+ tomlfile:print("edition = \"2018\"")
+ tomlfile:print("")
+ tomlfile:print("[dependencies]")
+ local features = configs.features
+ if features then
+ features = table.wrap(features)
+ tomlfile:print("%s = {version = \"%s\", features = [\"%s\"], default-features = %s}", name, require_version, table.concat(features, "\", \""), configs.default_features)
+ else
+ tomlfile:print("%s = \"%s\"", name, require_version)
+ end
+ tomlfile:close()
end
- tomlfile:close()
-- generate main.rs
io.writefile(path.join(sourcedir, "src", "main.rs"), [[