36 ms·
Rust and C++ Interoperability in Chrome
- brian_herman__ 6y agoI wonder how this compares to Mozilla's approach when they did something similar with Rust, Firefox and servo.
- muizelaar 6y agoMozilla's uses a combination of https://github.com/eqrion/cbindgen https://github.com/eqrion/cbindgen and https://github.com/rust-lang/rust-bindgen https://github.com/rust-lang/rust-bindgen depending on the direction of interop. These tools don't provide the safety guarantees of https://github.com/dtolnay/cxx https://github.com/dtolnay/cxx but the also both predate cxx and C++ doesn't have much in terms of safety guarantees to begin with so the bar is pretty low.
- jcranmer 6y agoIt's also worth mentioning that Mozilla tends not to use a lot of standard C++ types, using nsTArray instead of std::vector or nsA?C?String instead of std::string. This makes the porting of APIs using arrays or structs easier, since Mozilla owns the ABI rather than needing to worry about different standard libraries having different ABIs.
- ChrisSD 6y agoC++ interop with C++ can be a pain. E.g. even with the same version of the same compiler, GCC can have different options enabled that affect the layout of some types.
- ncmncm 6y agoThat is the same in all languages mature enough to have variant options. Rust included. Therefore, a tendentious distraction from the topic. Chris, I shall expect better from you in the future.
- fgdfgddfg 6y agoLooks like the Chromium team could also snag a few of them, since servo team is axed https://twitter.com/ddprrt/status/1293570734271406080 https://twitter.com/ddprrt/status/1293570734271406080
- adamnemecek 6y agoThey should probably look at how mozilla does it. From experience doing something similar, things get simpler when you write your code using handles rather than pointers but that's not how chrome is written. https://floooh.github.io/2018/06/17/handles-vs-pointers.html https://floooh.github.io/2018/06/17/handles-vs-pointers.html
- bluejekyll 6y ago> This seems to present some C++/Rust interoperability challenges which nobody else has faced. Is this different from the Firefox integration with Rust in some meaningful way? It looks like the cxx library is going to be critical for this. I’m curious how helpful others have found cxx for interop with C++? > For a Rustacean, this is controversial - all C++ is unsafe! But “unsafe” should be a really bad code smell. If “unsafe” is needed for all C++ calls, there will be thousands of them, and the “unsafe” keyword will lose its meaning. I don’t think the attitude about unsafe usage differs from the general Rust community. If there’s a lot of it, then it definitely is a code smell.
- rightbyte 6y agoCan't you just do a: #define CPP_CALL unsafe in the Rust equivalent to annotate "unsafe" cpp calls from Rust? "No boilerplate or redeclarations. No C++ annotations. Ideally, no allowlist." This seems like an unpractical approach. How do you even call C++ code from Rust without extern "C" linkage.
- deleted 6y ago[deleted]
- steveklabnik 6y agoRust does not have a textual substitution pre-processor, so like, you can do this sorta kinda but it would be way more involved.
- roblabla 6y agomacro_rules! cpp_call { ($($tt:tt)*) => { unsafe { $($tt)* } } } Yeah, not pretty, but it works :P
- rightbyte 6y agoNature finds its ways. Seriously though, maybe comment annotation would be better than abusing the macros like that. I though there was a more direct cpp way. (Edit: As in the c preprocessor, not C++.)
- Rochus 6y agoSo building Chromium becomes even more complex. Understanding the build system alone is a major achievement; I even had to build a tool for that: https://github.com/rochus-keller/gntools/ https://github.com/rochus-keller/gntools/. Unfortunately that's only half of the rent; it also needs hundereds of Python scripts; and now also crates will be added.
- malkia 6y agoFuchsia, uses also "gn" (then ninja) and has rust support too
- deleted 6y ago[deleted]
- bitwize 6y ago> So building Chromium becomes even more complex. Suck it up and get used to it. Rust is absolutely the future of systems development; every major C or C++ project -- including the kernel -- is going to have a Rust interoperability story, and eventually, major components that implement desirable features written entirely in Rust, so in the interim, until the desirable but currently unrealistic goal of migrating all extant C and C++ code to Rust is achieved, you will need to have both C(++) and Rust tooling (and whatever else) to build the project.
- staticassertion 6y agoThe post is how they are not using rust, how could you possibly have come to the conclusion that the builds are going to get more complicated?
- ComputerGuru 6y agoBecause they’re clearly interested in possibly doing so in the future?
- hamaluik 6y agoI integrated some basic CEF stuff (enough get to get a basic browser working) into a Rust codebase (https://github.com/hamaluik/cef-simple https://github.com/hamaluik/cef-simple). It was a massive pain at first, but much easier once you give up on the safety and "idiomacy" of Rust and accept that you have to write in more of C/C++ style. For the parts that can't be written purely in Rust, it ends up being not really any more painful than writing it in C++ anyway.
- eggsnbacon1 6y agoDo they really need to access thousands of C++ API calls from Rust? Doesn't this defeat the purpose of writing safe code in Rust? This smells of "not invented here" which applies to Google projects pretty often. They should focus on integrating Rust in portions of the API instead of exposing a gigantic unsafe API surface, essentially making all their code unsafe. Unless the Chrome codebase is really such a mess that they can't do anything without exposing this giant API surface. In that case they should rewrite it to... not do that. "We can't use Rust unless it allows us to write all our code in C++ without showing unsafe warnings"
- nitsky 6y ago> Doesn't this defeat the purpose of writing safe code in Rust? While the Chrome authors will not be protected from memory unsafety in the wrapped C++ APIs, the usage of those APIs in the new code they write on top will be safe, which is better than nothing. Similarly, much of the Rust standard library and many popular crates are "safe" wrappers around unsafe code, like calls to libc, winapi, openssl, etc. If there is a memory unsafety issue in one of those libraries, Rust won't save you.
- outworlder 6y ago> Do they really need to access thousands of C++ API calls from Rust? Yes. It's turtles all the way down. Applying this line of thought to its logical conclusion, it wouldn't be worth it until we have written the OS itself and all firmware in Rust.
- Ericson2314 6y agoJust within the process. Between processes or process and kernel, there are already runtime checks, so Rust isn't contributing safety so much quality.
- Const-me 6y agoLooks way too complicated. I think the reason is rust is not good at OOP. Compare with my C# to C++ interop library, it can easily pass arbitrary complicated types both ways: https://github.com/Const-me/ComLightInterop https://github.com/Const-me/ComLightInterop
- kazagistar 6y agoThe problems listed aren't the oop, they are the memory and thread safety rules of rust, that prevent all the null pointer dereferencing and leaky memory that a "dumb" C++ wrapper allows.
- Const-me 6y agoHere's a quote from the article: > We think the hardest part of this is imagining a safe way to pass types between Rust and C++. That requires auto-generated shim code on both the Rust and C++ side. I'll be very surprised if they'll be able to make a production-quality solution. The languages are just too different, and Rust's OOP support is one of these issues.
- Paul-ish 6y agoBack when I was an intern at Mozilla it was a real pain (in my opinion) to call between C++ and Rust. This was before bindgen and cbindgen, and certainly CXX. Eg if you have a heap allocated thing that is passed between Rust and C++, who frees it? I ended up hacking something together, but it didn't feel right.
- xxpor 6y ago>if you have a heap allocated thing that is passed between Rust and C++, who frees it? Isn't this an issue regardless? Forget crossing the rust/c++ boundary, lets say you pass something to another class in c++, you need to have a contract of who frees what when, right? Maybe I'm not understanding the issue.
- webkike 6y agoThere are some things that make this better, such as returning pointer types and not returning raw pointers. Returning raw pointers usually means that another function will delete them. I very rarely see pointers handed back from functions being freed caller side
- Matthias247 6y agoDo you mean references instead of pointers? I'm not familiar of a difference between pointers and raw pointers in C or C++. C++ allows to be more clear: unique_ptrs allow to move ownership, references mean this is definitely not owned, and the remaining questions are around normal pointers. With pure C there is however zero distinction. A pointer can mean ownership is transferred, it is meant to be a reference, it could be a static reference to something in constant memory, etc.
- webkike 6y agoI meant pointers versus types such unique_ptr and shared_ptr
- 6y ago
- oscargrouch 6y agoAs someone that deals with a chromium-based codebase everyday, i dont think this is a good idea at all. Unnecessary overcomplication on the codebase, making it more difficult to understand. (Rust and C++ are complex beasts) The only thing i could think of, is to replace the tools that are mostly in Python.. But this will be a lot of work. I guess maybe Google wants to employ good Rust enginneers and need to have some "playground" for them. Swift on the other way, will have native C++ interop, and soon will give the ability to manage the memory ownership the same way C++ and Rust does (not just defaulting to ref-count).. Once Swift have those properties we will have one more good contender in the same arena as C++, Rust and Zig.
- deleted 6y ago[deleted]
- nilkn 6y agoI doubt the point is to offer people a playground but rather to find a way to write new code in a language that is memory safe by default. Browsers are notoriously plagued by bugs related to memory safety so there’s quite a lot of motivation for at least considering this path.
- oscargrouch 6y agoThat is the problem with default narratives, they dont adapt well to every case. Chromium codebase is a massive codebase. It works, its efficient and fast, its sophisticated and complex, its well tested, had all sort of bugs that was taken out of them. Its really well written C++ code with modern ownership semantics. So a lot of mistakes that are used as boogeyman to convince people to use Rust are barely problems you really face. And no matter what wonders Rust promisses, a lot of bugs would get back there in case of rewriting things. Rust can make a very good point when the thing to be rewritten is in C (if is not a billion dollar codebase like Linux). But with big codebases, well written and modern C++ it doesnt make sense at all. I get it why someone would start a new project in Rust though.. but the things dont add up when we talk about big codebases already coded with good C++ practices.
- onebot 6y agoI hope someday maybe we have a browser completely written in Rust. What's the point of using Rust in a C++ code base if C++ is the 800lb gorilla as the article implies. If C++ is so important, then just stick to that?!
- bsder 6y ago> If C++ is so important, then just stick to that?! A journey of a thousand miles begins with a single step ... Legacy is a thing. Replacing it piecemeal is the only way to get it replaced. In addition, you can prioritize pieces. If a particular piece is very likely to be a security problem or has lots of bugs, you can rewrite just that piece into Rust.
- SquareWheel 6y agoSome areas of code are more sensitive than others. Eliminating bugs in areas dealing with encryption, sandboxing, etc may be very beneficial.
- erik_seaberg 6y agoThe strangler pattern (gradually replacing C++ with Rust) is pretty much the only alternative to a https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/ https://www.joelonsoftware.com/2000/04/06/things-you-should-... complete rewrite.
- est31 6y agoYou have to start somewhere. Every C++ component that's replaced by a safe Rust component is a reduction in attack surface.
- Skunkleton 6y agoMost of the fun stuff your computer is doing right now is the direct result of C and C++ code (browser, kernel, web server, games, etc.). Replacing all that code in one go isn't going to happen. Still, Rust solves some real problems with C++, so we shouldn't ignore it. If we can't replace the world all at once, why not do it piecemeal while targeting the highest value components?
- 6y ago
- kbenson 6y ago> No need for the “unsafe” keyword unless something is known to be less safe than normal C++. > For a Rustacean, this is controversial - all C++ is unsafe! Isn't this just a fundamental misunderstanding of what unsafe really means, and as such a nonsense goal that doesn't gain anything? Unsafe is a Rust language definition, and defines whether the rust compiler can vouch for the safety of some code. As such, calling to a library in some other language will always be unsafe, by definition, because the Rust language cannot vouch for it. If it makes you feel better, replace "unsafe" in your head (or with a macro) with "rustc_cannot_vouch_for" and carry on with your day. It means the same thing, and isn't really telling you that your C++ code sucks even if it looks like it at first glance, so who cares? If you really want to reduce the unsafe keyword from being seen in most regular code, you create and interface that maps the C++ function and exposes it as a rust function, and you've hidden away your unsafe usage to one spot per function. If you have enough confidence in your C++ code, there's no downside to this (and if you don't, then maybe you shouldn't be complaining that unsafe is unneeded).
- arcticbull 6y ago> ... known to be less safe than normal C++. Oh... no, no, that's... very unsafe lol. Jokes aside, making that their #1 goal was very strange. Agreed it appears to be a fundamental misunderstanding of what "unsafe" means. It doesn't mean that it's literally not safe to call that function, just that it's unchecked. "unchecked" might be a better annotation come to think of it.
- kbenson 6y ago> "unchecked" might be a better annotation come to think of it. Yeah, it's come up before in discussions here. Depending on the context you're coming from/working in, unchecked either makes more sense, or less sense than unsafe. When working within Rust, unsafe makes sense, it maps to how people think about what they are doing, because rustc is checking everything. When working between Rust and other languages/libraries, it's a bit less accurate, and "unchecked" makes more sense.
- nicoburns 6y ago
- da39a3ee 6y agoQuestion about the organizational context here. My understanding is that Chromium is an open source project. In practice though, when the document says "we" is it talking about mostly Google engineers? I read the document as indicating that there's a serious possibility of more widespread Rust usage, especially that last sentence If we become convinced this sort of interoperability is possible, we’ll revisit widespread use of Rust in Chrome, and at that point we plan to work hard to achieve this with robust production-quality solutions. Would it be wrong to take away from this that in some teams within Google, using Rust in places where C++ would have been used, is something that is being considered seriously?
- deleted 6y ago[deleted]
- tolbish 6y agoThere are Googlers in this thread considering it.
- cmrdporcupine 6y agoHm, I'm a Googler working on the chromecast platform and a Chromium committer who thinks Rust Is Pretty Neat. I'll look internally as well, but who can I talk to about helping out with Rust adoption in the context of the chromium codebase?
- ncmncm 6y agoThis is all very clever, but it has certain really, really fundamental problems. 1. The main program will remain C++ (or anyway Google's hobbled subset). New code you choose to get done in Rust will be lower-level code, implementing specific new features, or re-implementing low-level stuff too toxic to fix. So, the main task is not Rust calling into C++ code, but C++ calling Rust. That doesn't mean the Rust code won't ever need to call out to utility code, but: You are coding in Rust for an actual, you know, reason, right? Maybe that utility stuff should be RIIR, first? Otherwise what was the point, again? 2. It is all very well to talk about Rust calling C-like functions and virtual functions, but that only takes us up to 1985. We all know (I hope) that the overwhelming majority of useful power in C++ code is in features wholly inaccessible to Rust, even in principle. How will Rust do overload resolution? Inlines? (Also 1985.) Template instantiation? Exception handling? (That takes us to 1992.) Template function overloading and partial specialization? (1998). I could go on, right up to 2020. There are other fundamental problems, but this seems like enough for now. No sense piling on. At least point 1 makes point 2 less a problem.
- historyremade 6y agoShort Google Stock. Chrome gonna to face death. I guarantee this.
- historyremade 6y agoThe Law Enforcement not gonna to allow Rust to live. Rust must Die. We need Zerodays to protect our citizens. Fuck you all Rust and Bitcoin Retards.
- hoseja 6y agoTIL Rust doesn't have function overloading. But actually not sure whether this is a good or bad thing.
- ComputerGuru 6y agoI’ve been using it since pre 1.0 and I couldn’t tell you either. (Traits get you most of the way there but you’d see them exist for no other purpose which is just boilerplate imho.)
- mlindner 6y agoWhat's so good about function overloading in C++? I've never used it in any C++ I've written.