库能否以二进制形式分发,这样最终用户就看不到源代码?
Can libraries be distributed as a binary, so the end user cannot see the source code?
是否可以编译一个 Rust 库 crate,以便用户看不到源代码但仍然可以使用该库?
如果是,是否所有泛型都作为 "Source code" 或某些 IR 提供,或者 Rust 是否以不同于 C++ 模板的方式实现泛型?
每个库 crate 都包含大量元数据,无论是静态链接 (.rlib
) 还是动态链接 (.so
/.dylib
/.dll
):
- 模块结构
- 已导出
macro_rules
个宏
- 类型和特征定义
- 常量及其初始化表达式
- 所有函数的签名
- 标记为
#[inline]
或通用的每个函数的整个主体(默认特征方法在 Self
上被认为是通用的)
尽管没有注释或其他空格,但所有这些足以复制一些原始来源(多少取决于泛型的使用)。
函数体在编译器的内部 AST 结构中被序列化——你可以通过 rustc -Z ast-json lib.rs
.
看到它的漂亮形式
虽然元数据是二进制的,而不是 JSON,但使用 librustc
从已编译的 crate 中提取所有导出的函数定义,并且漂亮地打印 AST 相当容易。
在未来,可能没有任何 AST 过去的类型检查,因此元数据将编码某种 IR——一种可能性是 CFG,即 "control flow graph",它已经在几个内部使用地点。
然而,这仍然会暴露比 Java 字节码更多的信息,这将是一种优化,您仍然可以近似原始代码(并轻松获得可以编译的东西)。
因此,我只能推荐两个选项:
- 暴露一个CAPI;它的优点是作为一个稳定的 ABI,但它非常有限且脆弱;
- 仅使用 trait 对象而不是泛型公开 Rust API;这样你就可以保持内存安全并且所有单态函数仍然可以正常工作,但是特征对象(动态调度)不能表达泛型可能的所有模式:特别是,泛型特征方法不能在特征对象上调用(C++ 应该有一个混合
template
和 virtual
的类似限制,可能根据具体情况提供解决方法)。
是否可以编译一个 Rust 库 crate,以便用户看不到源代码但仍然可以使用该库?
如果是,是否所有泛型都作为 "Source code" 或某些 IR 提供,或者 Rust 是否以不同于 C++ 模板的方式实现泛型?
每个库 crate 都包含大量元数据,无论是静态链接 (.rlib
) 还是动态链接 (.so
/.dylib
/.dll
):
- 模块结构
- 已导出
macro_rules
个宏 - 类型和特征定义
- 常量及其初始化表达式
- 所有函数的签名
- 标记为
#[inline]
或通用的每个函数的整个主体(默认特征方法在Self
上被认为是通用的)
尽管没有注释或其他空格,但所有这些足以复制一些原始来源(多少取决于泛型的使用)。
函数体在编译器的内部 AST 结构中被序列化——你可以通过 rustc -Z ast-json lib.rs
.
虽然元数据是二进制的,而不是 JSON,但使用 librustc
从已编译的 crate 中提取所有导出的函数定义,并且漂亮地打印 AST 相当容易。
在未来,可能没有任何 AST 过去的类型检查,因此元数据将编码某种 IR——一种可能性是 CFG,即 "control flow graph",它已经在几个内部使用地点。
然而,这仍然会暴露比 Java 字节码更多的信息,这将是一种优化,您仍然可以近似原始代码(并轻松获得可以编译的东西)。
因此,我只能推荐两个选项:
- 暴露一个CAPI;它的优点是作为一个稳定的 ABI,但它非常有限且脆弱;
- 仅使用 trait 对象而不是泛型公开 Rust API;这样你就可以保持内存安全并且所有单态函数仍然可以正常工作,但是特征对象(动态调度)不能表达泛型可能的所有模式:特别是,泛型特征方法不能在特征对象上调用(C++ 应该有一个混合
template
和virtual
的类似限制,可能根据具体情况提供解决方法)。