xmake icon indicating copy to clipboard operation
xmake copied to clipboard

交叉编译Rust项目时,cargo的编译期依赖没有被正确安装

Open Yangff opened this issue 1 month ago • 8 comments

Xmake 版本

xmake v2.9.2+master.d8818c5b0

操作系统版本和架构

all

描述问题

当前,xmake通过编译一个空的项目来复制cargo解析的rust项目依赖,并将产生的所有编译结果安装到目标路径。 https://github.com/xmake-io/xmake/issues/4049 解决了交叉编译时不能正确拷贝目标平台库文件的问题。 但是,在交叉编译时,rust会将需要在主机运行的编译期依赖,例如过程宏编译为可以在主机平台运行的文件,例如.dlls。这些目标文件不会被存放在 target/arch/release/deps , 而是 target/release/deps. Cargo会在产生rustc指令时同时将这两个目录放进-L中,从而产生正确的编译结果。 但是,通过add_files添加的rs文件只会在xmake复制后的安装路径中寻找依赖,这使得rustc无法在use对应包的时候提示找不到这个包,实际上,是找不到对应的在主机上运行的依赖。

产生类似如下的错误

PS C:\Users\yangf\Documents\Projects\RE-UE4SS> rustc 
-C debuginfo=2 -C opt-level=3 -C linker=C:\Users\yangf\Documents\Projects\RE-UE4SS/tools/zig/zig-c++ 
--target=x86_64-unknown-linux-gnu 
--edition=2021 
-L dependency=C:\Users\yangf\Documents\Projects\RE-UE4SS\Intermediates\.packages\c\cargo_patternsleuth_bind\latest\ca0d54df84b4464a9d56cf13e471daea\lib 
-C debuginfo=2 
--extern patternsleuth=C:\Users\yangf\Documents\Projects\RE-UE4SS\Intermediates\.packages\c\cargo_patternsleuth_bind\latest\cache\source\target\x86_64-unknown-linux-gnu\release\deps\libpatternsleuth-fe8a45f2bce330fe.rlib 
--crate-type=staticlib -o C:\Users\yangf\Documents\Projects\RE-UE4SS\Binaries\Game__Shipping__Linux\patternsleuth_bind\libpatternsleuth_bind.a deps\first\patternsleuth_bind\src\lib.rs
error[E0463]: can't find crate for `patternsleuth`
 --> deps\first\patternsleuth_bind\src\lib.rs:5:5
  |
5 | use patternsleuth::resolvers::{
  |     ^^^^^^^^^^^^^ can't find crate

error: cannot determine resolution for the macro `impl_collector`
  --> deps\first\patternsleuth_bind\src\lib.rs:19:1
   |
19 | impl_collector! {
   | ^^^^^^^^^^^^^^
   |
   = note: import resolution is stuck, try simplifying macro imports

error[E0463]: can't find crate for `patternsleuth`
   --> deps\first\patternsleuth_bind\src\lib.rs:101:15
    |
101 |     let exe = patternsleuth::process::internal::read_image()?;
    |               ^^^^^^^^^^^^^ can't find crate

error[E0433]: failed to resolve: use of undeclared type `UE4SSResolution`
   --> deps\first\patternsleuth_bind\src\lib.rs:105:34
    |
105 |     let resolution = exe.resolve(UE4SSResolution::resolver())?;
    |                                  ^^^^^^^^^^^^^^^ use of undeclared type `UE4SSResolution`

error: aborting due to 4 previous errors

期待的结果

项目应该正常编译,调用应该为

C:\Users\yangf\Documents\Projects\RE-UE4SS> rustc 
-C debuginfo=2 -C opt-level=3 
-C linker=C:\Users\yangf\Documents\Projects\RE-UE4SS/tools/zig/zig-c++ 
--target=x86_64-unknown-linux-gnu --edition=2021 
-L dependency=C:\Users\yangf\Documents\Projects\RE-UE4SS\Intermediates\.packages\c\cargo_patternsleuth_bind\latest\ca0d54df84b4464a9d56cf13e471daea\lib 
**-L dependency=C:\Users\yangf\Documents\Projects\RE-UE4SS\Intermediates\.packages\c\cargo_patternsleuth_bind\latest\cache\source\target\release\deps**  
-C debuginfo=2 
--extern patternsleuth=C:\Users\yangf\Documents\Projects\RE-UE4SS\Intermediates\.packages\c\cargo_patternsleuth_bind\latest\cache\source\target\x86_64-unknown-linux-gnu\release\deps\libpatternsleuth-fe8a45f2bce330fe.rlib 
--crate-type=staticlib 
-o C:\Users\yangf\Documents\Projects\RE-UE4SS\Binaries\Game__Shipping__Linux\patternsleuth_bind\libpatternsleuth_bind.a deps\first\patternsleuth_bind\src\lib.rs

工程配置

我手上没有合适的复现但是原理上来说

    if target then
        os.vcp(path.join(sourcedir, "target", target, opt.mode == "debug" and "debug" or "release", "deps"), path.join(installdir, "lib"))
        -- copy everything host target to lib
        os.vcp(path.join(sourcedir, "target", opt.mode == "debug" and "debug" or "release", "deps", "*"), path.join(installdir, "lib"))
    else
        os.vcp(path.join(sourcedir, "target", opt.mode == "debug" and "debug" or "release", "deps"), path.join(installdir, "lib"))
    end

加上第二行复制之后就可以正确编译了 (我测试也是可以的)。 但是,我不认为将主机依赖复制到安装路径下是正确的行为。。 我不大确定额xmake是怎么区分编译期依赖和项目依赖的安装路径的。

另外我也遇到了 https://github.com/xmake-io/xmake/issues/4049#issuecomment-1668808516 这里提到的不会自动添加

add_rcflags("--target=aarch64-unknown-none", {force = true})

的问题,这似乎与我之前编译no_std的时候遇到的问题是一样的,和这里的问题无关,只是如果修复上述代码之后交叉编译还是失败的话可能是这个导致的。

附加信息和错误日志

Yangff avatar May 28 '24 01:05 Yangff