Closed SirLynix closed 2 years ago
It is only a static lib. Can you provide a whole test example project?
/Users/ruki/.cargo/bin//rustc --edition 2018 -L dependency=/Users/ruki/share/testrs/build/.packages/c/cargo_actix-web/4.0/8f4a704fdf4c4b41ae8b958686b2ddb0/lib -L dependency=/Users/ruki/share/testrs/build/.packages/c/cargo_env_logger/0.9/8f4a704fdf4c4b41ae8b958686b2ddb0/lib -L dependency=/Users/ruki/share/testrs/build/.packages/c/cargo_cxx/latest/8f4a704fdf4c4b41ae8b958686b2ddb0/lib -L dependency=/Users/ruki/share/testrs/build/.packages/c/cargo_tokio/1.17/abaedbc7e3b7456ebb39218449efbcfd/lib -L dependency=/Users/ruki/share/testrs/build/.packages/c/cargo_twitch-irc/4.0/8f4a704fdf4c4b41ae8b958686b2ddb0/lib --extern actix_web=/Users/ruki/share/testrs/build/.packages/c/cargo_actix-web/4.0/8f4a704fdf4c4b41ae8b958686b2ddb0/lib/libactix_web-38446e15a082db0e.rlib --extern env_logger=/Users/ruki/share/testrs/build/.packages/c/cargo_env_logger/0.9/8f4a704fdf4c4b41ae8b958686b2ddb0/lib/libenv_logger-cb0b7cebc529cd65.rlib --extern cxx=/Users/ruki/share/testrs/build/.packages/c/cargo_cxx/latest/8f4a704fdf4c4b41ae8b958686b2ddb0/lib/libcxx-4263bb78ed14d042.rlib --extern tokio=/Users/ruki/share/testrs/build/.packages/c/cargo_tokio/1.17/abaedbc7e3b7456ebb39218449efbcfd/lib/libtokio-89e3519f918141fa.rlib --extern twitch_irc=/Users/ruki/share/testrs/build/.packages/c/cargo_twitch-irc/4.0/8f4a704fdf4c4b41ae8b958686b2ddb0/lib/libtwitch_irc-e01eee7d8ce49708.rlib --crate-type=staticlib -o build/macosx/x86_64/release/libWebService.a src/test.rs
The issue is that xmake handle every cargo package separately, which means that actix-web, twitch-irc and tokio are three separate libs, and there is in fact 3 times tokio (as it's a dep of actix-web and twitch-irc).
But xmake just add three libs. like adding links actix_web tokio twitch_irc
actix_web.dylib will contains tokio codes?
--extern actix_web=/Users/ruki/share/testrs/build/.packages/c/cargo_actix-web/4.0/8f4a704fdf4c4b41ae8b958686b2ddb0/lib/libactix_web-38446e15a082db0e.rlib
--extern tokio=/Users/ruki/share/testrs/build/.packages/c/cargo_tokio/1.17/abaedbc7e3b7456ebb39218449efbcfd/lib/libtokio-89e3519f918141fa.rlib
--extern twitch_irc=/Users/ruki/share/testrs/build/.packages/c/cargo_twitch-irc/4.0/8f4a704fdf4c4b41ae8b958686b2ddb0/lib/libtwitch_irc-e01eee7d8ce49708.rlib
But xmake just add three libs. like adding links actix_web tokio twitch_irc
Yes but as static libraries, each of them will embed the code for tokio.
It is only a static lib. Can you provide a whole test example project?
Sure, it's just taking that Rust file and compiling it with Cargo and with xmake, I can make you a quick example soon.
test_actix_twitchirc.zip
Here's a small project (with a bad code but that doesn't matter) which runs fine with cargo run
but fails with xmake && xmake run
.
XMake output:
lynix@SirDesktop:/mnt/c/Projets/Perso/Tests/test_actix_twitchirc$ xmake run
run_chatservice
start_chatservice
thread 'main' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', /home/lynix/.cargo/registry/src/github.com-1ecc6299db9ec823/twitch-irc-4.0.0/src/client/event_loop.rs:84:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: execv(/mnt/c/Projets/Perso/Tests/test_actix_twitchirc/bin/linux_x86_64_release/WebService) failed(101)
Cargo output:
Finished dev [unoptimized + debuginfo] target(s) in 1m 09s
Running `target/debug/test_actix_twitchirc`
run_chatservice
start_chatservice
Joining Twitch channel
Twitch chat thread
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "CAP", params: ["*", "ACK", "twitch.tv/tags twitch.tv/commands"] }))
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "001", params: ["justinfan12345", "Welcome, GLHF!"] }))
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "002", params: ["justinfan12345", "Your host is tmi.twitch.tv"] }))
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "003", params: ["justinfan12345", "This server is rather new"] }))
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "004", params: ["justinfan12345", "-"] }))
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "375", params: ["justinfan12345", "-"] }))
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "372", params: ["justinfan12345", "You are in a maze of twisty passages, all alike."] }))
Received message: Generic(HiddenIRCMessage(IRCMessage { tags: IRCTags({}), prefix: Some(HostOnly { host: "tmi.twitch.tv" }), command: "376", params: ["justinfan12345", ">"] }))
Received message: Join(JoinMessage { channel_login: "sirlynixvanfrietjes", user_login: "justinfan12345", source: IRCMessage { tags: IRCTags({}), prefix: Some(Full { nick: "justinfan12345", user: Some("justinfan12345"), host: Some("justinfan12345.tmi.twitch.tv") }), command: "JOIN", params: ["#sirlynixvanfrietjes"] } })
...
(note that you need xmake dev for this)
That xmake collects all Cargo dependencies to build one single Cargo.toml to allow it to merge dependencies and collect the result, this is the easiest fix I think.
This solution is also not very well implemented. Each add_requires uniquely corresponds to a package instance for parallel installation. Even if combined into a single cargo.toml, several different cargo.toml may be required if different targets require different dependency groups.
We need to improve the add_requires interface to support the description of all cargo deps in a single add_requires.
Use Cargo.toml
add_requires("cargo::test_actix_twitchirc", {configs = {tomlfile = path.join(os.scriptdir(), "Cargo.toml")}})
Cargo.toml
[package]
name = "test_actix_twitchirc"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = "4.0"
env_logger = "0.9"
log = "0.4"
twitch-irc = "4.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] }
Write cargo.toml configuarion in xmake.lua
add_requires("cargo::test_actix_twitchirc", {configs = {dependencies = [[
actix-web = "4.0"
env_logger = "0.9"
log = "0.4"
twitch-irc = "4.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] }
]]}})
Both solutions can also be supported and are compatible with the current single add_requires("cargo::actix-web 4.0")
configuration.
If we only use a single rust package, we can still continue to use add_requires("cargo::actix-web 4.0")
Both solutions are great but I think the first one is the best because Cargo.toml are part of the Rust ecosystem and may be needed by other tools such as Visual Studio Code for auto-completion.
I have supported the solution1, and tested it for your example. It works now. https://github.com/xmake-io/xmake/pull/2235
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")
https://github.com/xmake-io/xmake/blob/dev/tests/projects/rust/cargo_deps_with_toml/xmake.lua
Does it work?
Sorry I couldn't test until today.
Yes it works well, thank you. However it's not taking Cargo.toml updates into account, could it be possible to automatically handle this, or should I use version number for package?
Thanks a lot.
Sorry I couldn't test until today.
Yes it works well, thank you. However it's not taking Cargo.toml updates into account, could it be possible to automatically handle this, or should I use version number for package?
you need add version to add_requires("cargo::test 1.0")
Xmake Version
xmake v2.6.4+HEAD.9361ffcc1 (dev)
Operating System Version and Architecture
Windows 11
Describe Bug
When using xmake with the Rust language, there seem to be a problem with the way it handles Cargo packages.
I have the following requires:
and the following target:
(syslinks are required for Rust features but that's another issue)
xmake installs those packages without issue, but when I use them, they don't work quite right.
The issue is that xmake handle every cargo package separately, which means that actix-web, twitch-irc and tokio are three separate libs, and there is in fact 3 times tokio (as it's a dep of actix-web and twitch-irc).
Since tokio relies on global variables, it can lead to this famous Rust error:
which happens when you have multiple Tokio runtimes (which happens when you have different tokio versions).
I did try the very same Rust file with this Cargo.toml:
which worked.
I see two possibles fixes here: 1) That xmake collects all Cargo dependencies to build one single Cargo.toml to allow it to merge dependencies and collect the result, this is the easiest fix I think. 2) That xmake collects every cargo package dependency (actix-web => tokio and more), like it does for C++ packages, and install it separately (and allows it to reuse them). But it means to have a lot of dependencies in the list. XMake should also merge packages by features.
Expected Behavior
That xmake manages to reuse tokio and other rust dependencies to have a working program.
Project Configuration
Rust source for reference:
With cargo, it works:
With xmake, it fails:
Additional Information and Error Logs
Here's how Cargo linked my app:
Here's how xmake builds my lib: