Back to blog

Cheerp 3.0: The most advanced C++ compiler for the Web, now permissively licensed

Today we are very proud to announce Cheerp 3.0, the latest major release of our C++ compiler for the Web.

More than a year has passed since the previous release of Cheerp (Cheerp 2.7), and this new version is packed with new features and optimizations that, once more, move the state of the art of using C++ as a programming language for Web applications and games.

Most importantly, with this release we are making a significant change to the licensing model of Cheerp. Starting from Cheerp 3.0, all the compiler core components and libraries are now licensed permissively under the Apache 2.0 / LLVM license. This marks a radical departure from our previous GPLv2 / dual commercial licensing model, allowing for Cheerp 3.0 to be used for any purpose, with no restrictions.

Why are we changing the license of Cheerp?

Since its release in 2014 Cheerp has been licensed under a dual licensing scheme: GPLv2 for non-commercial users, and a proprietary license for anybody not willing to comply with GPLv2 terms.

For us at Leaning Technologies, this has always represented a less than ideal,but necessary choice. As a bootstrapped company with no external capital, we felt that dual licensing was the only way to monetize the tool, even if that came at the expense of a wider community adoption.

A lot has happened since 2014: we have grown significantly and released multiple products ( CheerpJ, CheerpX for Flash and WebVM). We are in a very different place financially and in terms of maturity. During this time, Cheerp remained the cornerstone of all our technologies. Everything that we make at Leaning Technologies is written in C++ and compiled with Cheerp, and it would not have been possible otherwise.

Having reflected on what role we want to play in the WebAssembly ecosystem, we realized that now is the right time to change gears, and prioritize a wider adoption of this tool. By relicensing it to a permissive liberal license we hope to remove any barrier to the adoption of Cheerp, which can now be used by anybody with ‘no strings attached’.

What makes Cheerp unique?

Cheerp is a compiler designed to make C++ a first class language for Web programming.

The purpose of Cheerp is not just to generate optimized WebAssembly from C++. Rather, it is to provide a tool that allows C++ to be seamlessly integrated with any external HTML5/JavaScript.

To achieve this, it has several unique features and optimizations:

  • A state-of-the-art WebAssembly backend: This is expected by a modern C++ compiler that can target the Web. Cheerp generates extremely high quality WebAssembly code in one step, with no post-processing required (e.g. Binaryen wasm-opt). Cheerp supports post-MVP features of WebAssembly including tail calls, SIMD and externrefs. All these features can be selectively enabled using the -cheerp-wasm-enable= command line flag to make sure you can target as many browsers as possible depending on your requirements.
  • A performant JavaScript backend: Cheerp is the only tool in the market that can generate pure JavaScript code from C++. In particular, it is possible to compile selected portions of code to JavaScript by tagging specific functions or classes with the [[cheerp::genericjs]] attribute. It is also possible to compile a whole codebase to pure JavaScript, by using the -target cheerp command line option. The JavaScript output of Cheerp is highly optimized. We have studied in depth how engines such as V8 and SpiderMonkey work internally to make sure the generated JavaScript can be compiled as efficiently as possible.
  • Transparent access to DOM APIs and JavaScript libraries: By taking advantage of the JavaScript backend, Cheerp allows one to manipulate the DOM and invoke any JavaScript API directly in C++. In Cheerp this is done by using the APIs declared in the client namespace. The <cheerp/clientlib.h> header declares all the standard DOM APIs at this time, but there is nothing magic about it and you are free to add your own declarations to the client namespace if you need to use experimental DOM APIs or any third party JavaScript libraries. As a quick example of what is possible with Cheerp, this is valid C++ code:
client::HTMLElement* newElem =  client::document.createElement(“div”);
  • The [[cheerp::jsexport]] attribute: With this feature it is possible to use C++ functions and complete classes directly from manually written JavaScript. The compiler will enforce a set of rules on the exposed interfaces to guarantee that it’s safe to do so. We have written at length about this feature previously.
  • Advanced optimizations to reduce code size: Cheerp heavily takes advantage of whole program optimization techniques. We have developed advanced optimization such as PreExecuter  (convert global C++ constructors to constants), PartialExecuter (remove code that can be proven to never be run based on partial knowledge of function parameters), and a sophisticated devirtualizer. All of these contribute to a significant reduction in code size.

How does Cheerp compare to Emscripten?

Both Cheerp and Emscripten are based on the industry standard LLVM/Clang infrastructure, and, fundamentally, do the same thing: compiling C++ code into something that can run in the browser.

At a high level, the main difference between the two tools is a matter of philosophy. Emscripten has a strong focus towards converting whole C++ applications to WebAssembly so they can run on the browser. Conversely, Cheerp focuses on allowing existing C++ code to be used as part of a new, Web-native user experience. This is what almost all of our customers actually required for their use cases.

To achieve this, Cheerp provides a collection of features to allow seamless interoperability between C++ and any external JavaScript/DOM. In particular, the [[cheerp::jsexport]] tag signals that the generated code is exposed with no overhead to external JavaScript. This unique feature requires Cheerp to be able to generate a combination of WebAssembly and JavaScript from a single C++ source, while enforcing a set of rules on the exposed interfaces to ensure their behavior is predictable and without surprises.

On the technical side, the main differences are about how intermediate outputs are represented and how linking happens. Emscripten uses by default WebAssembly as the object format, the various files are then linked and optimized in post-processing by wasm-opt (part of binaryen).

From the get go, we followed a different approach, motivated by the desire to have an integrated tool for C++ on the Web. Cheerp directly uses the LLVM bytecode format as the intermediate representation, for both object files and libraries. This makes it possible to fully embrace whole program optimization by taking advantage of all the metadata available at the LLVM level. Cheerp will “internalize” all definitions during LTO, allowing a wide range of standard and custom optimizations to take place at the LLVM level. After this process, high quality WebAssembly and JavaScript is generated without any need for post-processing steps.

We routinely benchmark Cheerp against the Emscripten test suite. The results reflect the aforementioned differences in approach. In terms of output size, thanks to LLVM level whole program optimization and our custom passes, Cheerp normally achieves  better results across the board, with an average 7% smaller build size.

Output size benchmarks, lower is better. Data available here.

The reduced output size does not have a negative impact on execution performance, which is comparable with Emscripten across a wide range of benchmarks and execution engines. As an example here we have the execution times on the v8 engine, lower is better. Full dataset available for v8, SpiderMonkey and JavaScriptCore.

In other words, Cheerp provides a unique degree of integration between compiled C++ and external JavaScript, with a smaller output footprint, without sacrificing any performance compared to Emscripten.

The only significant missing feature in Cheerp 3.0 is support WebAssembly atomics and multithreading, but we are currently working on this feature and we expect this last gap to be filled over the next few months with the release of Cheerp 3.1.

It should be noted that the use of multithreading in browsers currently requires jumping through more than a few hoops to enable SharedArrayBuffer (i.e. COEP/COOP/CORP headers for cross-origin isolations). These hoops can become real limitations to load third-party resources, which is not uncommon in Web applications. This means that, in practice, it might be wise not to depend on multithreading unless you really need the feature.

Give Cheerp a try!

Cheerp has been used to build a lot of amazing products, including all of Leaning Technologies’ tools (e.g. WebVM, a x86 virtual machine running in the browser at high performance).

The question is, what will you build with Cheerp?

You can download Cheerp here. For Debian/Ubuntu, consider using our PPA

If you are unsure where to start, check out the Cheerp documentation.

For further support make sure to join our Discord: https://discord.leaningtech.com, where you will find Leaning Technologies core developers, including myself. We are always happy to help!

We hope you will enjoy using Cheerp, see you soon!

The author

Related posts