库可以作为二进制文件分发,因此最终用户无法看到源代码吗?

时间:2015-01-17 12:41:03

标签: rust

是否可以编译Rust库包以便用户无法查看源代码但仍可以使用该库?

如果是,所有的仿制药都提供为"源代码"或者某些IR,或者Rust实现泛型与C ++模板有什么不同?

1 个答案:

答案 0 :(得分:35)

每个库包中都包含大量元数据,无论是静态链接(.rlib)还是动态链接(.so / .dylib / .dll):

  • 模块结构
  • 导出macro_rules
  • 类型和特征定义
  • 具有初始化表达式的常量
  • 所有功能的签名
  • 标记为#[inline]或通用的每个函数的整个主体(默认特征方法被认为是Self上的泛型)

所有这些都足以重现一些原始来源(多少取决于泛型的用法),尽管没有评论或其他空格。
函数体在编译器的内部AST结构中被序列化 - 你可以用rustc -Z ast-json lib.rs看到它的漂亮形式。

虽然元数据是二进制的,而不是JSON,但是使用librustc从已编译的包中提取所有导出的函数定义,并且相当容易地打印AST。

将来可能没有任何AST过去的类型检查,因此元数据会对IR进行编码 - 一种可能性是CFG,即"控制流图",已在内部使用在几个地方。

然而,这仍然会比Java字节码暴露更多的信息,这将是一个优化,你仍然可以近似原始代码(并轻松得到编译的东西)。

因此,我只推荐两种选择:

  1. 公开C API;它具有稳定的ABI的优点,但它非常有限和脆弱;
  2. 仅使用trait对象而不是泛型来公开Rust API;这样你就可以保持内存安全,并且所有单态函数仍然可以正常工作,但特征对象(动态调度)不能用泛型表达所有可能的模式:特别是,通用特征方法不能在特征对象上调用(C ++应该有一个混合templatevirtual的类似限制,可能会根据具体情况提供变通方法。