< 返回版块

Mercury 发表于 2021-07-01 15:13

现在手头有个小项目,后端application用的是warp。

为了方便前端调用,所以工程里还包含了一个子wasm crate来复用application中的结构体。

起初能正常编译产生wasm文件,但是当结构体上通过derive实现了一些diesel的宏后,编译wasm失败,会出很多奇怪的错误。

设计的初衷,是为了前后端不用定义两遍结构体,wasm crate里面只是一些赋值语句,根本不会用到diesel的功能。而且编译成功了,还会使得生成的wasm文件变臃肿。

所以想问下,是否有方法可以在引用某个crate中的结构时,屏蔽部分trait的实现。 譬如 a.rs

#[derive(Debug,TraitA,TraitB)]
struct A;

但被b.rs引用时,struct A忽略TraitA,TraitB

评论区

写评论
作者 Mercury 2021-07-04 15:43

嗯,是的,又测了下,哪怕啥代码都没写,啥方法都没用,只要在dependency里面用到了某个crate,凡是没说明是否是optional的,都会无条件去编译,但编译后的文件大小,有无dependency都是一样的,说明编译器在最后编译时,的确是会剔除没使用到的crate的。

--
👇
johnmave126: 我理解了一下

uuid用到了OsRng,这个在wasm环境下默认是没有的

然后cargo编译时是先把整个dependency每个crate都编译了,最后链接的时候再去掉没有用到的部分。

然后在编译uuid的时候就失败了,即使其实没有用到。

--
👇
Freddie Mercury: 搞了个简单的示例,源码放网盘了 https://share.weiyun.com/nDgrVeOO

public_struct引用了uuidcrate,通过featurerand来启用结构体的implementation。

uuid本身有支持wasm的feature,这里不启用,好复现错误。

issue application启用了randwasm_lib 没启用;

cargo check --workspace 不报任何错误。 在wasm_lib下执行wasm-pack build --target web,提示报错,因为编译了uuid

个人理解是Cargo.toml里面引用到了某个crate,如果没有写明是optional的,就会全部编译,哪怕代码里没用到任何这个crate的方法。

解决的方法是修改public_struct的Cargo.toml。

[dependencies]
uuid = { version = "0.8", features = ["v4"] , optional = true}

[features]
rand = ["uuid"]

--
👇
johnmave126: 有点好奇原因,我理解的话rust在最后link的时候会把没有用到的代码去掉

有没有一个小一点的例子可以重现的?包括用的是什么wasm的工具链

--
👇
Freddie Mercury: 解决了。

目前通过在crate中设置feature,然后用cfg_attr宏来开关。

似乎没有更优雅的实现方法了 =,=

johnmave126 2021-07-03 02:23

我理解了一下

uuid用到了OsRng,这个在wasm环境下默认是没有的

然后cargo编译时是先把整个dependency每个crate都编译了,最后链接的时候再去掉没有用到的部分。

然后在编译uuid的时候就失败了,即使其实没有用到。

--
👇
Freddie Mercury: 搞了个简单的示例,源码放网盘了 https://share.weiyun.com/nDgrVeOO

public_struct引用了uuidcrate,通过featurerand来启用结构体的implementation。

uuid本身有支持wasm的feature,这里不启用,好复现错误。

issue application启用了randwasm_lib 没启用;

cargo check --workspace 不报任何错误。 在wasm_lib下执行wasm-pack build --target web,提示报错,因为编译了uuid

个人理解是Cargo.toml里面引用到了某个crate,如果没有写明是optional的,就会全部编译,哪怕代码里没用到任何这个crate的方法。

解决的方法是修改public_struct的Cargo.toml。

[dependencies]
uuid = { version = "0.8", features = ["v4"] , optional = true}

[features]
rand = ["uuid"]

--
👇
johnmave126: 有点好奇原因,我理解的话rust在最后link的时候会把没有用到的代码去掉

有没有一个小一点的例子可以重现的?包括用的是什么wasm的工具链

--
👇
Freddie Mercury: 解决了。

目前通过在crate中设置feature,然后用cfg_attr宏来开关。

似乎没有更优雅的实现方法了 =,=

作者 Mercury 2021-07-02 10:26

搞了个简单的示例,源码放网盘了 https://share.weiyun.com/nDgrVeOO

public_struct引用了uuidcrate,通过featurerand来启用结构体的implementation。

uuid本身有支持wasm的feature,这里不启用,好复现错误。

issue application启用了randwasm_lib 没启用;

cargo check --workspace 不报任何错误。 在wasm_lib下执行wasm-pack build --target web,提示报错,因为编译了uuid

个人理解是Cargo.toml里面引用到了某个crate,如果没有写明是optional的,就会全部编译,哪怕代码里没用到任何这个crate的方法。

解决的方法是修改public_struct的Cargo.toml。

[dependencies]
uuid = { version = "0.8", features = ["v4"] , optional = true}

[features]
rand = ["uuid"]

--
👇
johnmave126: 有点好奇原因,我理解的话rust在最后link的时候会把没有用到的代码去掉

有没有一个小一点的例子可以重现的?包括用的是什么wasm的工具链

--
👇
Freddie Mercury: 解决了。

目前通过在crate中设置feature,然后用cfg_attr宏来开关。

似乎没有更优雅的实现方法了 =,=

johnmave126 2021-07-02 01:05

有点好奇原因,我理解的话rust在最后link的时候会把没有用到的代码去掉

有没有一个小一点的例子可以重现的?包括用的是什么wasm的工具链

--
👇
Freddie Mercury: 解决了。

目前通过在crate中设置feature,然后用cfg_attr宏来开关。

似乎没有更优雅的实现方法了 =,=

作者 Mercury 2021-07-01 16:14

解决了。

目前通过在crate中设置feature,然后用cfg_attr宏来开关。

似乎没有更优雅的实现方法了 =,=

1 共 5 条评论, 1 页