OLD | NEW |
1 Adblock Plus core | 1 Adblock Plus core |
2 ================= | 2 ================= |
3 | 3 |
4 This repository contains the generic Adblock Plus code that's shared between | 4 This repository contains the generic Adblock Plus code that's shared between |
5 platforms. This repository is not designed to be used directly, but instead to | 5 platforms. This repository is not designed to be used directly, but instead to |
6 serve as a dependency for `adblockplus`, `adblockpluschrome` and | 6 serve as a dependency for `adblockplus`, `adblockpluschrome` and |
7 `libadblockplus`. | 7 `libadblockplus`. |
8 | 8 |
9 Compiling C++ code | 9 Compiling C++ code |
10 ------------------ | 10 ------------------ |
11 | 11 |
12 ### Purpose | 12 ### Purpose |
13 | 13 |
14 In order to improve performance and memory usage, some of the code (located | 14 In order to improve performance and memory usage, some of the code (located |
15 inside the `compiled` directory) is written in C++ and compiled to JavaScript | 15 inside the `compiled` directory) is written in C++ and compiled to JavaScript |
16 via Empscripten. | 16 via Empscripten. |
17 | 17 |
18 ### Requirements | 18 ### Requirements |
19 | 19 |
20 * [Emscripten 1.37.3](https://github.com/kripken/emscripten) | 20 * [Emscripten 1.37.3](https://github.com/kripken/emscripten) |
21 * [Python 2.7](https://www.python.org) | 21 * [Python 2.7](https://www.python.org) |
22 * [Node.js 6 or higher](https://nodejs.org/en/) | |
23 | 22 |
24 ### Running Emscripten | 23 ### Running Emscripten |
25 | 24 |
26 *Note*: The `compile` script will likely be replaced by a more elaborate | 25 After installing and configuring Emscripten you can run the following command: |
27 solution later. | |
28 | |
29 Before you start make sure to edit the `compile` script and make sure that | |
30 `EMSCRIPTEN_PATH` constant at the top of it points to your Emscripten install. | |
31 After that run the following command: | |
32 | 26 |
33 python compile | 27 python compile |
34 | 28 |
35 This will produce a `lib/compiled.js` exporting the classes defined in C++ code. | 29 This will produce a `lib/compiled.js` exporting the classes defined in C++ code. |
36 | 30 |
37 ### Technical details | 31 ### Technical details |
38 | 32 |
39 Compilation is currently a two-step process. In the first step, | 33 Compilation is currently a two-step process. In the bindings generation step, |
40 `compiled/bindings.cpp` (definitions of classes to be exported) is compiled into | 34 the source files are compiled into `compiled/bindings.cpp.js` with the |
41 `compiled/bindings.cpp.js` with `PRINT_BINDINGS` symbol defined. This | 35 `PRINT_BINDINGS` symbol defined. This application is then executed via Node.js |
42 application is then executed via Node.js and will print JavaScript wrappers for | 36 and will print JavaScript wrappers for the C++ classes to |
43 the C++ classes to `compiled/bindings.js`. | 37 `compiled/bindings.js` according to definitions within the `EMSCRIPTEN_BINDINGS` |
| 38 macro in `compiled/bindings.cpp`. |
44 | 39 |
45 In the next step all the C++ files in `compiled` directory are compiled, | 40 In the actual compilation step the source files are compiled into |
46 including `compiled/bindings.cpp` - without `PRINT_BINDINGS` symbol the | 41 `lib/compiled.js` without the `PRINT_BINDINGS` symbol, so that the |
47 `EMSCRIPTEN_BINDINGS` macro in this file will ignore its contents but rather | 42 `EMSCRIPTEN_BINDINGS` macro ignores its contents and merely emits some generic |
48 emit some functions necessary for the JavaScript bindings to work. The | 43 functions necessary for the JavaScript bindings to work. The previously |
49 `compiled/bindings.js` file is added to the end of Emscripten output. | 44 generated `compiled/bindings.js` file is added to the end of Emscripten output. |
50 | 45 |
51 The binding generation approach is heavily inspired by | 46 The binding generation approach is heavily inspired by |
52 [embind](http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_an
d_javascript/embind.html). | 47 [embind](http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_an
d_javascript/embind.html). |
53 However, embind doesn't use a separate build step to produce the bindings, the | 48 However, embind doesn't use a separate build step to produce the bindings, the |
54 bindings are rather generated dynamically at run time. As a side-effect, it | 49 bindings are rather generated dynamically at run time. As a side-effect, it |
55 increases the build size considerably and also imposes a significant performance | 50 increases the build size considerably and also imposes a significant performance |
56 penalty. Also, generating JavaScript code dynamically is discouraged for browser | 51 penalty. Also, generating JavaScript code dynamically is discouraged for browser |
57 extensions. | 52 extensions. |
58 | 53 |
59 *Note*: The tricky part when generating JavaScript bindings is determining the | 54 *Note*: The tricky part when generating JavaScript bindings is determining the |
60 mangled names of C++ methods. In order to do that, `compiled/bindings.cpp.js` | 55 mangled names of C++ methods. In order to do that, `compiled/bindings.cpp.js` |
61 will call these methods with invalid parameters and make them crash. The | 56 will call these methods with invalid parameters and make them crash. The |
62 resulting `abort()` call is then caught by JavaScript code that reads out the | 57 resulting `abort()` call is then caught by JavaScript code that reads out the |
63 method name from the stack. With this approach relying on some Emscripten | 58 method name from the stack. With this approach relying on some Emscripten |
64 internals, we have to require a specific Emscripten version. | 59 internals, we have to require a specific Emscripten version. |
65 | 60 |
66 Running the unit tests | 61 Running the unit tests |
67 ---------------------- | 62 ---------------------- |
68 | 63 |
69 You first need to run `npm install` in the repository directory in order to | 64 You first need to run `npm install` in the repository directory in order to |
70 install the required dependencies. After that you can run `npm test` which will | 65 install the required dependencies. After that you can run `npm test` which will |
71 execute all tests in the `test` directory of the repository. You can also | 66 execute all tests in the `test` directory of the repository. You can also |
72 specify specific test files on the command line, e.g. | 67 specify specific test files on the command line, e.g. |
73 `npm test test/synchronizer.js`. | 68 `npm test test/synchronizer.js`. |
OLD | NEW |