annotate clang-tools-extra/docs/modularize.rst @ 237:c80f45b162ad llvm-original

add some fix
author kono
date Wed, 09 Nov 2022 17:47:54 +0900
parents c4bab56944e8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 .. index:: modularize
anatofuz
parents:
diff changeset
2
anatofuz
parents:
diff changeset
3 ==================================
anatofuz
parents:
diff changeset
4 Modularize User's Manual
anatofuz
parents:
diff changeset
5 ==================================
anatofuz
parents:
diff changeset
6
anatofuz
parents:
diff changeset
7 .. toctree::
anatofuz
parents:
diff changeset
8 :hidden:
anatofuz
parents:
diff changeset
9
anatofuz
parents:
diff changeset
10 ModularizeUsage
anatofuz
parents:
diff changeset
11
anatofuz
parents:
diff changeset
12 :program:`modularize` is a standalone tool that checks whether a set of headers
anatofuz
parents:
diff changeset
13 provides the consistent definitions required to use modules. For example, it
anatofuz
parents:
diff changeset
14 detects whether the same entity (say, a NULL macro or size_t typedef) is
anatofuz
parents:
diff changeset
15 defined in multiple headers or whether a header produces different definitions
anatofuz
parents:
diff changeset
16 under different circumstances. These conditions cause modules built from the
anatofuz
parents:
diff changeset
17 headers to behave poorly, and should be fixed before introducing a module
anatofuz
parents:
diff changeset
18 map.
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 :program:`modularize` also has an assistant mode option for generating
anatofuz
parents:
diff changeset
21 a module map file based on the provided header list. The generated file
anatofuz
parents:
diff changeset
22 is a functional module map that can be used as a starting point for a
anatofuz
parents:
diff changeset
23 module.map file.
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 Getting Started
anatofuz
parents:
diff changeset
26 ===============
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 To build from source:
anatofuz
parents:
diff changeset
29
anatofuz
parents:
diff changeset
30 1. Read `Getting Started with the LLVM System`_ and `Clang Tools
anatofuz
parents:
diff changeset
31 Documentation`_ for information on getting sources for LLVM, Clang, and
anatofuz
parents:
diff changeset
32 Clang Extra Tools.
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 2. `Getting Started with the LLVM System`_ and `Building LLVM with CMake`_ give
anatofuz
parents:
diff changeset
35 directions for how to build. With sources all checked out into the
anatofuz
parents:
diff changeset
36 right place the LLVM build will build Clang Extra Tools and their
anatofuz
parents:
diff changeset
37 dependencies automatically.
anatofuz
parents:
diff changeset
38
anatofuz
parents:
diff changeset
39 * If using CMake, you can also use the ``modularize`` target to build
anatofuz
parents:
diff changeset
40 just the modularize tool and its dependencies.
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 Before continuing, take a look at :doc:`ModularizeUsage` to see how to invoke
anatofuz
parents:
diff changeset
43 modularize.
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45 .. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html
anatofuz
parents:
diff changeset
46 .. _Building LLVM with CMake: https://llvm.org/docs/CMake.html
anatofuz
parents:
diff changeset
47 .. _Clang Tools Documentation: https://clang.llvm.org/docs/ClangTools.html
anatofuz
parents:
diff changeset
48
anatofuz
parents:
diff changeset
49 What Modularize Checks
anatofuz
parents:
diff changeset
50 ======================
anatofuz
parents:
diff changeset
51
anatofuz
parents:
diff changeset
52 Modularize will check for the following:
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 * Duplicate global type and variable definitions
anatofuz
parents:
diff changeset
55 * Duplicate macro definitions
anatofuz
parents:
diff changeset
56 * Macro instances, 'defined(macro)', or #if, #elif, #ifdef, #ifndef conditions
anatofuz
parents:
diff changeset
57 that evaluate differently in a header
anatofuz
parents:
diff changeset
58 * #include directives inside 'extern "C/C++" {}' or 'namespace (name) {}' blocks
anatofuz
parents:
diff changeset
59 * Module map header coverage completeness (in the case of a module map input
anatofuz
parents:
diff changeset
60 only)
anatofuz
parents:
diff changeset
61
anatofuz
parents:
diff changeset
62 Modularize will do normal C/C++ parsing, reporting normal errors and warnings,
anatofuz
parents:
diff changeset
63 but will also report special error messages like the following::
anatofuz
parents:
diff changeset
64
anatofuz
parents:
diff changeset
65 error: '(symbol)' defined at multiple locations:
anatofuz
parents:
diff changeset
66 (file):(row):(column)
anatofuz
parents:
diff changeset
67 (file):(row):(column)
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 error: header '(file)' has different contents depending on how it was included
anatofuz
parents:
diff changeset
70
anatofuz
parents:
diff changeset
71 The latter might be followed by messages like the following::
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 note: '(symbol)' in (file) at (row):(column) not always provided
anatofuz
parents:
diff changeset
74
anatofuz
parents:
diff changeset
75 Checks will also be performed for macro expansions, defined(macro)
anatofuz
parents:
diff changeset
76 expressions, and preprocessor conditional directives that evaluate
anatofuz
parents:
diff changeset
77 inconsistently, and can produce error messages like the following::
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 (...)/SubHeader.h:11:5:
anatofuz
parents:
diff changeset
80 #if SYMBOL == 1
anatofuz
parents:
diff changeset
81 ^
anatofuz
parents:
diff changeset
82 error: Macro instance 'SYMBOL' has different values in this header,
anatofuz
parents:
diff changeset
83 depending on how it was included.
anatofuz
parents:
diff changeset
84 'SYMBOL' expanded to: '1' with respect to these inclusion paths:
anatofuz
parents:
diff changeset
85 (...)/Header1.h
anatofuz
parents:
diff changeset
86 (...)/SubHeader.h
anatofuz
parents:
diff changeset
87 (...)/SubHeader.h:3:9:
anatofuz
parents:
diff changeset
88 #define SYMBOL 1
anatofuz
parents:
diff changeset
89 ^
anatofuz
parents:
diff changeset
90 Macro defined here.
anatofuz
parents:
diff changeset
91 'SYMBOL' expanded to: '2' with respect to these inclusion paths:
anatofuz
parents:
diff changeset
92 (...)/Header2.h
anatofuz
parents:
diff changeset
93 (...)/SubHeader.h
anatofuz
parents:
diff changeset
94 (...)/SubHeader.h:7:9:
anatofuz
parents:
diff changeset
95 #define SYMBOL 2
anatofuz
parents:
diff changeset
96 ^
anatofuz
parents:
diff changeset
97 Macro defined here.
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
99 Checks will also be performed for '#include' directives that are
anatofuz
parents:
diff changeset
100 nested inside 'extern "C/C++" {}' or 'namespace (name) {}' blocks,
anatofuz
parents:
diff changeset
101 and can produce error message like the following::
anatofuz
parents:
diff changeset
102
anatofuz
parents:
diff changeset
103 IncludeInExtern.h:2:3:
anatofuz
parents:
diff changeset
104 #include "Empty.h"
anatofuz
parents:
diff changeset
105 ^
anatofuz
parents:
diff changeset
106 error: Include directive within extern "C" {}.
anatofuz
parents:
diff changeset
107 IncludeInExtern.h:1:1:
anatofuz
parents:
diff changeset
108 extern "C" {
anatofuz
parents:
diff changeset
109 ^
anatofuz
parents:
diff changeset
110 The "extern "C" {}" block is here.
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 .. _module-map-coverage:
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 Module Map Coverage Check
anatofuz
parents:
diff changeset
115 =========================
anatofuz
parents:
diff changeset
116
anatofuz
parents:
diff changeset
117 The coverage check uses the Clang library to read and parse the
anatofuz
parents:
diff changeset
118 module map file. Starting at the module map file directory, or just the
anatofuz
parents:
diff changeset
119 include paths, if specified, it will collect the names of all the files it
anatofuz
parents:
diff changeset
120 considers headers (no extension, .h, or .inc--if you need more, modify the
anatofuz
parents:
diff changeset
121 isHeader function). It then compares the headers against those referenced
anatofuz
parents:
diff changeset
122 in the module map, either explicitly named, or implicitly named via an
anatofuz
parents:
diff changeset
123 umbrella directory or umbrella file, as parsed by the ModuleMap object.
anatofuz
parents:
diff changeset
124 If headers are found which are not referenced or covered by an umbrella
anatofuz
parents:
diff changeset
125 directory or file, warning messages will be produced, and this program
anatofuz
parents:
diff changeset
126 will return an error code of 1. If no problems are found, an error code of
anatofuz
parents:
diff changeset
127 0 is returned.
anatofuz
parents:
diff changeset
128
anatofuz
parents:
diff changeset
129 Note that in the case of umbrella headers, this tool invokes the compiler
anatofuz
parents:
diff changeset
130 to preprocess the file, and uses a callback to collect the header files
anatofuz
parents:
diff changeset
131 included by the umbrella header or any of its nested includes. If any
anatofuz
parents:
diff changeset
132 front end options are needed for these compiler invocations, these
anatofuz
parents:
diff changeset
133 can be included on the command line after the module map file argument.
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 Warning message have the form:
anatofuz
parents:
diff changeset
136
anatofuz
parents:
diff changeset
137 warning: module.modulemap does not account for file: Level3A.h
anatofuz
parents:
diff changeset
138
anatofuz
parents:
diff changeset
139 Note that for the case of the module map referencing a file that does
anatofuz
parents:
diff changeset
140 not exist, the module map parser in Clang will (at the time of this
anatofuz
parents:
diff changeset
141 writing) display an error message.
anatofuz
parents:
diff changeset
142
anatofuz
parents:
diff changeset
143 To limit the checks :program:`modularize` does to just the module
anatofuz
parents:
diff changeset
144 map coverage check, use the ``-coverage-check-only option``.
anatofuz
parents:
diff changeset
145
anatofuz
parents:
diff changeset
146 For example::
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148 modularize -coverage-check-only module.modulemap
anatofuz
parents:
diff changeset
149
anatofuz
parents:
diff changeset
150 .. _module-map-generation:
anatofuz
parents:
diff changeset
151
anatofuz
parents:
diff changeset
152 Module Map Generation
anatofuz
parents:
diff changeset
153 =====================
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 If you specify the ``-module-map-path=<module map file>``,
anatofuz
parents:
diff changeset
156 :program:`modularize` will output a module map based on the input header list.
anatofuz
parents:
diff changeset
157 A module will be created for each header. Also, if the header in the header
anatofuz
parents:
diff changeset
158 list is a partial path, a nested module hierarchy will be created in which a
anatofuz
parents:
diff changeset
159 module will be created for each subdirectory component in the header path,
anatofuz
parents:
diff changeset
160 with the header itself represented by the innermost module. If other headers
anatofuz
parents:
diff changeset
161 use the same subdirectories, they will be enclosed in these same modules also.
anatofuz
parents:
diff changeset
162
anatofuz
parents:
diff changeset
163 For example, for the header list::
anatofuz
parents:
diff changeset
164
anatofuz
parents:
diff changeset
165 SomeTypes.h
anatofuz
parents:
diff changeset
166 SomeDecls.h
anatofuz
parents:
diff changeset
167 SubModule1/Header1.h
anatofuz
parents:
diff changeset
168 SubModule1/Header2.h
anatofuz
parents:
diff changeset
169 SubModule2/Header3.h
anatofuz
parents:
diff changeset
170 SubModule2/Header4.h
anatofuz
parents:
diff changeset
171 SubModule2.h
anatofuz
parents:
diff changeset
172
anatofuz
parents:
diff changeset
173 The following module map will be generated::
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 // Output/NoProblemsAssistant.txt
anatofuz
parents:
diff changeset
176 // Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \
anatofuz
parents:
diff changeset
177 -root-module=Root NoProblemsAssistant.modularize
236
c4bab56944e8 LLVM 16
kono
parents: 150
diff changeset
178
150
anatofuz
parents:
diff changeset
179 module SomeTypes {
anatofuz
parents:
diff changeset
180 header "SomeTypes.h"
anatofuz
parents:
diff changeset
181 export *
anatofuz
parents:
diff changeset
182 }
anatofuz
parents:
diff changeset
183 module SomeDecls {
anatofuz
parents:
diff changeset
184 header "SomeDecls.h"
anatofuz
parents:
diff changeset
185 export *
anatofuz
parents:
diff changeset
186 }
anatofuz
parents:
diff changeset
187 module SubModule1 {
anatofuz
parents:
diff changeset
188 module Header1 {
anatofuz
parents:
diff changeset
189 header "SubModule1/Header1.h"
anatofuz
parents:
diff changeset
190 export *
anatofuz
parents:
diff changeset
191 }
anatofuz
parents:
diff changeset
192 module Header2 {
anatofuz
parents:
diff changeset
193 header "SubModule1/Header2.h"
anatofuz
parents:
diff changeset
194 export *
anatofuz
parents:
diff changeset
195 }
anatofuz
parents:
diff changeset
196 }
anatofuz
parents:
diff changeset
197 module SubModule2 {
anatofuz
parents:
diff changeset
198 module Header3 {
anatofuz
parents:
diff changeset
199 header "SubModule2/Header3.h"
anatofuz
parents:
diff changeset
200 export *
anatofuz
parents:
diff changeset
201 }
anatofuz
parents:
diff changeset
202 module Header4 {
anatofuz
parents:
diff changeset
203 header "SubModule2/Header4.h"
anatofuz
parents:
diff changeset
204 export *
anatofuz
parents:
diff changeset
205 }
anatofuz
parents:
diff changeset
206 header "SubModule2.h"
anatofuz
parents:
diff changeset
207 export *
anatofuz
parents:
diff changeset
208 }
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 An optional ``-root-module=<root-name>`` option can be used to cause a root module
anatofuz
parents:
diff changeset
211 to be created which encloses all the modules.
anatofuz
parents:
diff changeset
212
anatofuz
parents:
diff changeset
213 An optional ``-problem-files-list=<problem-file-name>`` can be used to input
anatofuz
parents:
diff changeset
214 a list of files to be excluded, perhaps as a temporary stop-gap measure until
anatofuz
parents:
diff changeset
215 problem headers can be fixed.
anatofuz
parents:
diff changeset
216
anatofuz
parents:
diff changeset
217 For example, with the same header list from above::
anatofuz
parents:
diff changeset
218
anatofuz
parents:
diff changeset
219 // Output/NoProblemsAssistant.txt
anatofuz
parents:
diff changeset
220 // Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \
anatofuz
parents:
diff changeset
221 -root-module=Root NoProblemsAssistant.modularize
236
c4bab56944e8 LLVM 16
kono
parents: 150
diff changeset
222
150
anatofuz
parents:
diff changeset
223 module Root {
anatofuz
parents:
diff changeset
224 module SomeTypes {
anatofuz
parents:
diff changeset
225 header "SomeTypes.h"
anatofuz
parents:
diff changeset
226 export *
anatofuz
parents:
diff changeset
227 }
anatofuz
parents:
diff changeset
228 module SomeDecls {
anatofuz
parents:
diff changeset
229 header "SomeDecls.h"
anatofuz
parents:
diff changeset
230 export *
anatofuz
parents:
diff changeset
231 }
anatofuz
parents:
diff changeset
232 module SubModule1 {
anatofuz
parents:
diff changeset
233 module Header1 {
anatofuz
parents:
diff changeset
234 header "SubModule1/Header1.h"
anatofuz
parents:
diff changeset
235 export *
anatofuz
parents:
diff changeset
236 }
anatofuz
parents:
diff changeset
237 module Header2 {
anatofuz
parents:
diff changeset
238 header "SubModule1/Header2.h"
anatofuz
parents:
diff changeset
239 export *
anatofuz
parents:
diff changeset
240 }
anatofuz
parents:
diff changeset
241 }
anatofuz
parents:
diff changeset
242 module SubModule2 {
anatofuz
parents:
diff changeset
243 module Header3 {
anatofuz
parents:
diff changeset
244 header "SubModule2/Header3.h"
anatofuz
parents:
diff changeset
245 export *
anatofuz
parents:
diff changeset
246 }
anatofuz
parents:
diff changeset
247 module Header4 {
anatofuz
parents:
diff changeset
248 header "SubModule2/Header4.h"
anatofuz
parents:
diff changeset
249 export *
anatofuz
parents:
diff changeset
250 }
anatofuz
parents:
diff changeset
251 header "SubModule2.h"
anatofuz
parents:
diff changeset
252 export *
anatofuz
parents:
diff changeset
253 }
anatofuz
parents:
diff changeset
254 }
anatofuz
parents:
diff changeset
255
anatofuz
parents:
diff changeset
256 Note that headers with dependents will be ignored with a warning, as the
anatofuz
parents:
diff changeset
257 Clang module mechanism doesn't support headers the rely on other headers
anatofuz
parents:
diff changeset
258 to be included first.
anatofuz
parents:
diff changeset
259
anatofuz
parents:
diff changeset
260 The module map format defines some keywords which can't be used in module
anatofuz
parents:
diff changeset
261 names. If a header has one of these names, an underscore ('_') will be
anatofuz
parents:
diff changeset
262 prepended to the name. For example, if the header name is ``header.h``,
anatofuz
parents:
diff changeset
263 because ``header`` is a keyword, the module name will be ``_header``.
anatofuz
parents:
diff changeset
264 For a list of the module map keywords, please see:
anatofuz
parents:
diff changeset
265 `Lexical structure <https://clang.llvm.org/docs/Modules.html#lexical-structure>`_