What should a good build system provide?
Super easy to set up
[package]
name = "my-binary"
version = "0.1.0"
[dependencies]
uuid = "1.0"
my-library = { git = 'https://github.com/mortimer/my-library.git' }
my-renderer = { path = '../..//my-renderer' }
Super easy to build & run
Multiple platform compilations for free
#Desktop
cargo build
#Android
cargo build --target=armv7-linux-androideabi
#iOS
cargo build --target=aarch64-apple-ios
#WebAssembly
cargo build --target=wasm32-unknown-unknown
Development workflow
[replace]
# Compile project with a SpiderMonkey fork
mozjs_sys = {path = '/home/mortimer/Projects/mozjs_fork'}
Easy & elegant set up
[features]
default = ["openvr", "mock"]
openvr = ["libloading"]
mock = []
googlevr = ["gvr-sys"]
oculusvr = ["ovr-mobile-sys"]
Easy & elegant optional code
#[cfg(feature = "oculusvr")]
mod oculusvr;
Ease & safe to use
[dependencies]
rust-webvr = {features = ["openvr", "googlevr", "oculusvr"], version = "0.9"}
#[cfg(target_os = "linux")]
fn platform_hello() {
println!("You are running Linux!");
}
#[cfg(target_os = "android")]
fn platform_hello() {
println!("You are running Android!");
}
#[cfg(target_os = "ios")]
fn platform_hello() {
println!("You are running iOS!");
}
#[cfg(target_os = "macos")]
fn platform_hello() {
println!("You are running MacOS!");
}
#include <string>
int main() {
return 0;
}
Show preprocessor output
gcc -E test.cpp > result.text
22,020 lines!
template
struct __attribute__ ((__type_visibility__("default"))) owner_less >
: binary_function, weak_ptr<_Tp>, bool>
{
typedef bool result_type;
__attribute__ ((__visibility__("hidden"), __always_inline__))
bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const
{return __x.owner_before(__y);}
__attribute__ ((__visibility__("hidden"), __always_inline__))
bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const
{return __x.owner_before(__y);}
__attribute__ ((__visibility__("hidden"), __always_inline__))
bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const
{return __x.owner_before(__y);}
};
Tim Sweeney about C++17 Modules working draft
“I'm trying to understand the rationale for the oddity of the C++ modules TS”
C++: Research & set up testing framework
#include <gtest/gtest.h>
TEST(MyTestSuitName, MyTestCaseName) {
int actual = 1;
EXPECT_GT(actual, 0);
EXPECT_EQ(1, actual) << "Should be equal to one";
}
Rust: Built-in Unit testing
#[test]
fn it_works() {
assert_eq!(4, adder::add_two(2));
}
Run all tests
$) cargo test
Compiling adder v0.0.1 (file:///home/you/projects/adder)
Running target/adder-91b3e234d4ed382a
running 1 test
test tests::it_works ... ok
vs
fn main() {
if let Ok(aar_out_dir) = env::var("AAR_OUT_DIR") {
fs::copy(&Path::new("src/api/googlevr/aar/GVRService.aar"),
&Path::new(&aar_out_dir).join("GVRService.aar")).unwrap();
fs::copy(&Path::new("src/api/oculusvr/aar/OVRService.aar"),
&Path::new(&aar_out_dir).join("OVRService.aar")).unwrap();
}
}
warning: variable `frameData` should have
a snake case name such as `frame_data`
Rust, C/C++, Javascript
e.g.: Concurrency without data races
e.g.: Concurrency without data races
“std::string is responsible for almost half of all allocations in the Chrome browser process; please be careful how you use it!”
Errors cost money
Errors can cost a company it's reputation
C++ macros: Simple text substitution
#define FIVE_TIMES(x) 5 * x
int main() {
printf("%d\n", FIVE_TIMES(2 + 3));
return 0;
}
Variable captures
#define LOG(msg) do { \
int state = get_log_state(); \
if (state > 0) { \
printf("log(%d): %s\n", state, msg); \
} \
} while (0)
const char *state = "It's over 9000!";
LOG(state);
macro expansion happens in a distinct syntax context
macro_rules! log {
($msg:expr) => {{
let state: i32 = get_log_state();
if state > 0 {
println!("log({}): {}", state, $msg);
}
}};
}
Procedural & built-in macros
#[derive(Debug, Clone)]
pub struct VRFrameData {
pub timestamp: f64,
pub left_projection_matrix: [f32; 16],
pub left_view_matrix: [f32; 16],
pub right_projection_matrix: [f32; 16],
pub right_view_matrix: [f32; 16],
pub pose: VRPose,
}
println!("{:?}", frame_data);
constexpr factorial (int n){
return n > 0 ? n * factorial( n - 1 ) : 1;
}
constexpr int value = factorial(10);
println!("factorial: %d", value);
Rust favors "composition over inheritanceā€¯