7个版本 (1个稳定版)

1.0.6 2020年6月27日
1.0.6-alpha52020年9月21日
1.0.6-alpha32020年9月20日
1.0.6-alpha22020年7月1日

#96 in 模拟

Apache-2.0

5.5MB
42K SLoC

Rust 36K SLoC // 0.0% comments C++ 5.5K SLoC // 0.0% comments JavaScript 1K SLoC // 0.1% comments Assembly 376 SLoC // 0.1% comments Vue 75 SLoC // 0.0% comments Python 51 SLoC // 0.3% comments

lc3tools-sys

Build Status License: Apache 2.0 crates.io API Docs

LC3Tools的Rust绑定。

用法

将此添加到您的 Cargo.toml

[dependencies]
lc3tools-sys = "1.0.6"

由于这个crate公开的绑定与LC3Tools API完全一一对应,因此LC3Tools的源代码和文档是了解如何使用此crate的最佳位置,特别是API文档

头文件

头文件在DEP_LC3CORE_LINKS环境变量指定的路径下公开。

注意事项

然而,请注意,LC3Tools公开了一个C++ API。虽然这个crate提供了绑定,但它与您的操作系统/平台/编译器/编译器标志一起工作的可能性非常小。不同的平台似乎有不同的名称混淆约定,并且布局(据我所知)在不同配置之间不稳定(例如,从-O3切换到-O0会破坏我的配置中的C++接口示例)。

所有这些(名称混淆符号、布局信息)都编码在生成的绑定中。请注意,因为链接器通常是懒惰的,即使生成的绑定中的符号与您平台实际产生的符号不匹配,除非您实际在最终二进制文件中使用(间接)这些符号,否则您可能不会收到编译错误。这就是为什么C++接口示例功能屏蔽的原因。

我们提供了一个generate-fresh功能,这样您可以在构建时在本地生成此文件,但C++接口仍然不太可能工作/有用。诸如vtable之类的对象通过不透明类型表示,即使您设法获取一个C++生成的vtable以传递,有时事情仍然不起作用。

例如,由于原因尚不明确,在运行C++接口示例时,传递给模拟器的printer神秘地变成了NULL,但在传递给state实例的日志器副本中;在logger中的副本保持不变。我只能在修改了以下LC3Tools之后才能让示例工作

点击显示差异。
diff --git a/backend/logger.h b/backend/logger.h
index b7146ac..c172acb 100644
--- a/backend/logger.h
+++ b/backend/logger.h
@@ -28,10 +28,17 @@ namespace utils
       template<typename ... Args>
       void printf(PrintType level, bool bold, std::string const & format, Args ... args) const;
       void newline(PrintType level = PrintType::P_ERROR) const {
-            if(static_cast<uint32_t>(level) <= print_level) { printer.newline(); }
       }
       void print(std::string const & str) {
-            if(print_level > static_cast<uint32_t>(PrintType::P_NONE)) { printer.print(str); }
       }
       uint32_t getPrintLevel(void) const { return print_level; }
       void setPrintLevel(uint32_t print_level) { this->print_level = print_level; }
diff --git a/backend/simulator.cpp b/backend/simulator.cpp
index c8004e8..bd7f1db 100644
--- a/backend/simulator.cpp
+++ b/backend/simulator.cpp
@@ -112,7 +112,7 @@ void Simulator::simulate(void)
       collecting_input = true;
-        inputter.beginInput();
       if(threaded_input) {
           input_thread = std::thread(&core::Simulator::inputThread, this);
       }
@@ -125,7 +125,7 @@ void Simulator::simulate(void)
           executeEventChain(events);
           updateDevices();
           if(! threaded_input) {
-                collectInput();
           }
           checkAndSetupInterrupts();
       }
@@ -139,7 +139,7 @@ void Simulator::simulate(void)
   if(threaded_input && input_thread.joinable()) {
       input_thread.join();
   }
-    inputter.endInput();

解决方案

为了让这个crate至少在一定程度上可用,我们提供了一组有限的C绑定,它仅适用于运行整个程序。

这非常麻烦,但对我们来说足够好™。如果您需要真正的Rust绑定cxx,那么这可能值得一看。由于这个crate导出了LC3Tools头文件,您可以依赖这个crate并使用它的cc设置(忽略它具有的绑定)。

或者,如果您需要特定于C绑定的添加,欢迎提交PR!

特性

LC3Tools功能特性

LC3Tools后端部分始终包含在内。frontend特性包括frontend中的文件,而grader特性(需要frontend特性)包括frontend/grader中的文件,但移除了main函数在framework.cpp中的实现。

这些特性默认都是启用的。

其他特性

generate-fresh

默认情况下,构建此crate时不会重新生成LC3Tools的Rust绑定。生成。相反,我们捆绑了预生成的绑定并默认使用它们。我们这样做是因为生成绑定需要一些时间(大约一分钟——除非您非常关心清洁构建所需的时间,否则这不是一个问题),但更重要的是因为生成绑定是系统特定的。bindgen在执行过程中会遍历系统libc和C++标准库头文件,并且我们维护了一个要跳过的类型和内容的列表,它非常特定于libc/system/OS。

你可能永远不需要这样做,但如果你自己想要生成这些绑定(例如,因为你修改了LC3Tools中的某些头文件),则可以使用generate-fresh功能来构建(build.rs会传递正确的指令给cargo,这样你就可以启用该功能——只有当构建图中的某个头文件/文件发生变化时,它才会实际执行工作)。

lto

不幸的是,我们无法默认启用LTO,因为它需要一些设置,并且需要使用一些特定的工具(参见此提交此提交以获取一些背景信息,以及此页面以获取所需设置的详细信息)。

因此,我们提供了一个lto功能,它将编译器调用的cc传递必要的标志。当使用此功能时,你还需要确保传递给rustc的LTO链接器插件标志,并指示它使用合适的链接器,如此处所述。对于此特定crate,必要的标志已存在于此处,但已注释。

当使用lto功能时,你需要确保cc最终使用的编译器能够与LTO链接器插件一起工作。此表此处提供了一些关于应使用哪个版本的信息,但它有些过时;如果使用相同版本的clang来构建LC3Tools,并且使用相同版本的rustc来进行链接,则应该可以正常工作(假设它是相对较新的clang版本——本repo的CI使用版本9,成功运行)。

确定并更改cc使用的编译器实际上更复杂;在基于Linux的系统上,确保c别名指向所需的版本似乎就可以了(update-alternatives可能有助于你完成此操作)。

示例

目前我们有一个示例,该示例运行一个LC-3程序,用于计算两个无符号数的乘积。如前所述,它有一个C++接口部分和一个C接口部分。默认情况下,C++部分被禁用,因为它不太可能在你的机器上工作。

cargo run --example mul 应该运行C接口部分。

最低支持的Rust版本(MSRV)

此crate目前保证可以在稳定的Rust 1.43及更高版本上编译。我们无法保证这一点在未来版本中依然成立,但承诺将始终支持(至少)最新的稳定Rust版本,并在变更日志中记录MSRV的更改。

贡献

PR(Pull Requests,拉取请求)(非常)欢迎!有关详细信息,请参阅CONTRIBUTING.md

依赖