1.. index:: modularize 2 3================================== 4Modularize User's Manual 5================================== 6 7.. toctree:: 8 :hidden: 9 10 ModularizeUsage 11 12:program:`modularize` is a standalone tool that checks whether a set of headers 13provides the consistent definitions required to use modules. For example, it 14detects whether the same entity (say, a NULL macro or size_t typedef) is 15defined in multiple headers or whether a header produces different definitions 16under different circumstances. These conditions cause modules built from the 17headers to behave poorly, and should be fixed before introducing a module 18map. 19 20:program:`modularize` also has an assistant mode option for generating 21a module map file based on the provided header list. The generated file 22is a functional module map that can be used as a starting point for a 23module.map file. 24 25Getting Started 26=============== 27 28To build from source: 29 301. 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. 33 342. `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. 38 39 * If using CMake, you can also use the ``modularize`` target to build 40 just the modularize tool and its dependencies. 41 42Before continuing, take a look at :doc:`ModularizeUsage` to see how to invoke 43modularize. 44 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 48 49What Modularize Checks 50====================== 51 52Modularize will check for the following: 53 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) 61 62Modularize will do normal C/C++ parsing, reporting normal errors and warnings, 63but will also report special error messages like the following:: 64 65 error: '(symbol)' defined at multiple locations: 66 (file):(row):(column) 67 (file):(row):(column) 68 69 error: header '(file)' has different contents depending on how it was included 70 71The latter might be followed by messages like the following:: 72 73 note: '(symbol)' in (file) at (row):(column) not always provided 74 75Checks will also be performed for macro expansions, defined(macro) 76expressions, and preprocessor conditional directives that evaluate 77inconsistently, and can produce error messages like the following:: 78 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. 98 99Checks will also be performed for '#include' directives that are 100nested inside 'extern "C/C++" {}' or 'namespace (name) {}' blocks, 101and can produce error message like the following:: 102 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. 111 112.. _module-map-coverage: 113 114Module Map Coverage Check 115========================= 116 117The coverage check uses the Clang library to read and parse the 118module map file. Starting at the module map file directory, or just the 119include paths, if specified, it will collect the names of all the files it 120considers headers (no extension, .h, or .inc--if you need more, modify the 121isHeader function). It then compares the headers against those referenced 122in the module map, either explicitly named, or implicitly named via an 123umbrella directory or umbrella file, as parsed by the ModuleMap object. 124If headers are found which are not referenced or covered by an umbrella 125directory or file, warning messages will be produced, and this program 126will return an error code of 1. If no problems are found, an error code of 1270 is returned. 128 129Note that in the case of umbrella headers, this tool invokes the compiler 130to preprocess the file, and uses a callback to collect the header files 131included by the umbrella header or any of its nested includes. If any 132front end options are needed for these compiler invocations, these 133can be included on the command line after the module map file argument. 134 135Warning message have the form: 136 137 warning: module.modulemap does not account for file: Level3A.h 138 139Note that for the case of the module map referencing a file that does 140not exist, the module map parser in Clang will (at the time of this 141writing) display an error message. 142 143To limit the checks :program:`modularize` does to just the module 144map coverage check, use the ``-coverage-check-only option``. 145 146For example:: 147 148 modularize -coverage-check-only module.modulemap 149 150.. _module-map-generation: 151 152Module Map Generation 153===================== 154 155If you specify the ``-module-map-path=<module map file>``, 156:program:`modularize` will output a module map based on the input header list. 157A module will be created for each header. Also, if the header in the header 158list is a partial path, a nested module hierarchy will be created in which a 159module will be created for each subdirectory component in the header path, 160with the header itself represented by the innermost module. If other headers 161use the same subdirectories, they will be enclosed in these same modules also. 162 163For example, for the header list:: 164 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 172 173The following module map will be generated:: 174 175 // Output/NoProblemsAssistant.txt 176 // Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \ 177 -root-module=Root NoProblemsAssistant.modularize 178 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 } 209 210An optional ``-root-module=<root-name>`` option can be used to cause a root module 211to be created which encloses all the modules. 212 213An optional ``-problem-files-list=<problem-file-name>`` can be used to input 214a list of files to be excluded, perhaps as a temporary stop-gap measure until 215problem headers can be fixed. 216 217For example, with the same header list from above:: 218 219 // Output/NoProblemsAssistant.txt 220 // Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \ 221 -root-module=Root NoProblemsAssistant.modularize 222 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 } 255 256Note that headers with dependents will be ignored with a warning, as the 257Clang module mechanism doesn't support headers the rely on other headers 258to be included first. 259 260The module map format defines some keywords which can't be used in module 261names. If a header has one of these names, an underscore ('_') will be 262prepended to the name. For example, if the header name is ``header.h``, 263because ``header`` is a keyword, the module name will be ``_header``. 264For a list of the module map keywords, please see: 265`Lexical structure <https://clang.llvm.org/docs/Modules.html#lexical-structure>`_ 266