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