OLD | NEW |
1 # Caveats | 1 # Clang Tool Refactoring |
2 * The current workflow requires git. | |
3 * This doesn't work on Windows... yet. I'm hoping to have a proof-of-concept w
orking on Windows as well ~~in a month~~ several centuries from now. | |
4 | 2 |
5 # Prerequisites | 3 [TOC] |
6 Everything needed should be in a default Chromium checkout using gclient. third\
_party/llvm-build/Release+Asserts/bin should be in your `$PATH`. | |
7 | 4 |
8 # Writing the Tool | 5 ## Caveats |
9 An example clang tool is being implemented in https://codereview.chromium.org/12
746010/. Other useful resources might be the [basic tutorial for Clang's AST mat
chers](http://clang.llvm.org/docs/LibASTMatchersTutorial.html) or the [AST match
er reference](http://clang.llvm.org/docs/LibASTMatchersReference.html). | |
10 | 6 |
11 Build your tool by running the following command (requires cmake version 2.8.10
or later): | 7 * The current workflow requires git. |
12 ``` | 8 * This doesn't work on Windows... yet. I'm hoping to have a proof-of-concept |
13 tools/clang/scripts/update.sh --force-local-build --without-android --with-chrom
e-tools <tools> | 9 working on Windows as well ~~in a month~~ several centuries from now. |
14 ``` | 10 |
15 `<tools>` is a semicolon delimited list of subdirectories in `tools/clang` to bu
ild. The resulting binary will end up in `third_party/llvm-build/Release+Asserts
/bin`. For example, to build the Chrome plugin and the empty\_string tool, run t
he following: | 11 ## Prerequisites |
16 ``` | 12 |
17 tools/clang/scripts/update.sh --force-local-build --without-android --with-chrom
e-tools "plugins;empty_string" | 13 Everything needed should be in a default Chromium checkout using gclient. |
| 14 `third_party/llvm-build/Release+Asserts/bin` should be in your `$PATH`. |
| 15 |
| 16 ## Writing the Tool |
| 17 |
| 18 An example clang tool is being implemented in |
| 19 https://codereview.chromium.org/12746010/. Other useful resources might be the |
| 20 [basic tutorial for Clang's AST matchers](http://clang.llvm.org/docs/LibASTMatch
ersTutorial.html) |
| 21 or the |
| 22 [AST matcher reference](http://clang.llvm.org/docs/LibASTMatchersReference.html)
. |
| 23 |
| 24 Build your tool by running the following command (requires cmake version 2.8.10 |
| 25 or later): |
| 26 |
| 27 ```shell |
| 28 tools/clang/scripts/update.sh --force-local-build --without-android \ |
| 29 --with-chrome-tools <tools> |
18 ``` | 30 ``` |
19 | 31 |
20 When writing AST matchers, the following can be helpful to see what clang thinks
the AST is: | 32 `<tools>` is a semicolon delimited list of subdirectories in `tools/clang` to |
| 33 build. The resulting binary will end up in |
| 34 `third_party/llvm-build/Release+Asserts/bin`. For example, to build the Chrome |
| 35 plugin and the empty\_string tool, run the following: |
| 36 |
| 37 ```shell |
| 38 tools/clang/scripts/update.sh --force-local-build --without-android \ |
| 39 --with-chrome-tools "plugins;empty_string" |
21 ``` | 40 ``` |
| 41 |
| 42 When writing AST matchers, the following can be helpful to see what clang thinks |
| 43 the AST is: |
| 44 |
| 45 ```shell |
22 clang++ -cc1 -ast-dump foo.cc | 46 clang++ -cc1 -ast-dump foo.cc |
23 ``` | 47 ``` |
24 | 48 |
25 # Running the tool | 49 ## Running the tool |
26 First, you'll need to generate the compilation database with the following comma
nd: | 50 |
27 ``` | 51 First, you'll need to generate the compilation database with the following |
| 52 command: |
| 53 |
| 54 ```shell |
28 cd $HOME/src/chrome/src | 55 cd $HOME/src/chrome/src |
29 ninja -C out/Debug -t compdb cc cxx objc objcxx > out/Debug/compile_commands.jso
n | 56 ninja -C out/Debug -t compdb cc cxx objc objcxx > \ |
| 57 out/Debug/compile_commands.json |
30 ``` | 58 ``` |
31 | 59 |
32 This will dump the command lines used to build the C/C++ modules in all of Chrom
ium into the resulting file. Then run the following command to run your tool acr
oss all Chromium code: | 60 This will dump the command lines used to build the C/C++ modules in all of |
33 ``` | 61 Chromium into the resulting file. Then run the following command to run your |
34 # Make sure all chromium targets are built to avoid missing generated dependenci
es | 62 tool across all Chromium code: |
| 63 |
| 64 ```shell |
| 65 # Make sure all chromium targets are built to avoid missing generated |
| 66 # dependencies |
35 ninja -C out/Debug | 67 ninja -C out/Debug |
36 tools/clang/scripts/run_tool.py <toolname> <path/to/directory/with/compile_comma
nds.json> <path 1> <path 2> ... | 68 tools/clang/scripts/run_tool.py <toolname> \ |
| 69 <path/to/directory/with/compile_commands.json> <path 1> <path 2> ... |
37 ``` | 70 ``` |
38 | 71 |
39 `<path 1>`, `<path 2>`, etc are optional arguments you use to filter the files t
hat will be rewritten. For example, if you only want to run the `empty-string` t
ool on files in `chrome/browser/extensions` and `sync`, you'd do something like: | 72 `<path 1>`, `<path 2>`, etc are optional arguments you use to filter the files |
40 ``` | 73 that will be rewritten. For example, if you only want to run the `empty-string` |
41 tools/clang/scripts/run_tool.py empty_string out/Debug chrome/browser/extensions
sync | 74 tool on files in `chrome/browser/extensions` and `sync`, you'd do something like
: |
| 75 |
| 76 ```shell |
| 77 tools/clang/scripts/run_tool.py empty_string out/Debug \ |
| 78 chrome/browser/extensions sync |
42 ``` | 79 ``` |
43 | 80 |
44 # Limitations | 81 ## Limitations |
45 Since the compile database is generated by ninja, that means that files that are
n't compiled on that platform won't be processed. That means if you want to appl
y a change across all Chromium platforms, you'll have to run the tool once on ea
ch platform. | |
46 | 82 |
47 # Testing | 83 Since the compile database is generated by ninja, that means that files that |
| 84 aren't compiled on that platform won't be processed. That means if you want to |
| 85 apply a change across all Chromium platforms, you'll have to run the tool once |
| 86 on each platform. |
| 87 |
| 88 ## Testing |
| 89 |
48 `test_tool.py` is the test harness for running tests. To use it, simply run: | 90 `test_tool.py` is the test harness for running tests. To use it, simply run: |
49 ``` | 91 |
| 92 ```shell |
50 test_tool.py <tool name> | 93 test_tool.py <tool name> |
51 ``` | 94 ``` |
52 Note that name of the built tool and the subdirectory it lives in at `tools/clan
g` must match. What the test harness does is find all files that match the patte
rn `*-original.cc` in your tool's tests subdirectory. It then runs the tool acro
ss those files and compares it to the expected result, stored in `*-expected.cc` | 95 |
| 96 Note that name of the built tool and the subdirectory it lives in at |
| 97 `tools/clang` must match. What the test harness does is find all files that |
| 98 match the pattern `*-original.cc` in your tool's tests subdirectory. It then |
| 99 runs the tool across those files and compares it to the expected result, stored |
| 100 in `*-expected.cc` |
OLD | NEW |