diff options
| author | ruki <[email protected]> | 2022-04-02 15:31:51 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-04-02 15:31:51 +0800 |
| commit | 403a5a5ebf8286465a1e7d9e2a06a49281bc4008 (patch) | |
| tree | 2b9e84a76435cb65d2ebcf29292e1f4776cabb52 | |
| parent | 8b687b4bff48f28bcd991408b0ca0fece7605515 (diff) | |
| parent | bcf8fe42e129bb8f350d812041a9005ebbb589b6 (diff) | |
Merge pull request #2235 from xmake-io/cargo
Improve cargo package with Cargo.toml file
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | tests/projects/rust/cargo_deps_with_toml/Cargo.toml | 9 | ||||
| -rw-r--r-- | tests/projects/rust/cargo_deps_with_toml/src/main.rs | 12 | ||||
| -rw-r--r-- | tests/projects/rust/cargo_deps_with_toml/xmake.lua | 7 | ||||
| -rw-r--r-- | xmake/modules/package/manager/cargo/configurations.lua | 1 | ||||
| -rw-r--r-- | xmake/modules/package/manager/cargo/find_package.lua | 48 | ||||
| -rw-r--r-- | xmake/modules/package/manager/cargo/install_package.lua | 40 |
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"), [[ |
