|  | .. index:: modularize | 
|  |  | 
|  | ================================== | 
|  | Modularize User's Manual | 
|  | ================================== | 
|  |  | 
|  | .. toctree:: | 
|  | :hidden: | 
|  |  | 
|  | ModularizeUsage | 
|  |  | 
|  | :program:`modularize` is a standalone tool that checks whether a set of headers | 
|  | provides the consistent definitions required to use modules. For example, it | 
|  | detects whether the same entity (say, a NULL macro or size_t typedef) is | 
|  | defined in multiple headers or whether a header produces different definitions | 
|  | under different circumstances. These conditions cause modules built from the | 
|  | headers to behave poorly, and should be fixed before introducing a module | 
|  | map. | 
|  |  | 
|  | :program:`modularize` also has an assistant mode option for generating | 
|  | a module map file based on the provided header list. The generated file | 
|  | is a functional module map that can be used as a starting point for a | 
|  | module.map file. | 
|  |  | 
|  | Getting Started | 
|  | =============== | 
|  |  | 
|  | To build from source: | 
|  |  | 
|  | 1. Read `Getting Started with the LLVM System`_ and `Clang Tools | 
|  | Documentation`_ for information on getting sources for LLVM, Clang, and | 
|  | Clang Extra Tools. | 
|  |  | 
|  | 2. `Getting Started with the LLVM System`_ and `Building LLVM with CMake`_ give | 
|  | directions for how to build. With sources all checked out into the | 
|  | right place the LLVM build will build Clang Extra Tools and their | 
|  | dependencies automatically. | 
|  |  | 
|  | * If using CMake, you can also use the ``modularize`` target to build | 
|  | just the modularize tool and its dependencies. | 
|  |  | 
|  | Before continuing, take a look at :doc:`ModularizeUsage` to see how to invoke | 
|  | modularize. | 
|  |  | 
|  | .. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html | 
|  | .. _Building LLVM with CMake: http://llvm.org/docs/CMake.html | 
|  | .. _Clang Tools Documentation: http://clang.llvm.org/docs/ClangTools.html | 
|  |  | 
|  | What Modularize Checks | 
|  | ====================== | 
|  |  | 
|  | Modularize will check for the following: | 
|  |  | 
|  | * Duplicate global type and variable definitions | 
|  | * Duplicate macro definitions | 
|  | * Macro instances, 'defined(macro)', or #if, #elif, #ifdef, #ifndef conditions | 
|  | that evaluate differently in a header | 
|  | * #include directives inside 'extern "C/C++" {}' or 'namespace (name) {}' blocks | 
|  | * Module map header coverage completeness (in the case of a module map input | 
|  | only) | 
|  |  | 
|  | Modularize will do normal C/C++ parsing, reporting normal errors and warnings, | 
|  | but will also report special error messages like the following:: | 
|  |  | 
|  | error: '(symbol)' defined at multiple locations: | 
|  | (file):(row):(column) | 
|  | (file):(row):(column) | 
|  |  | 
|  | error: header '(file)' has different contents depending on how it was included | 
|  |  | 
|  | The latter might be followed by messages like the following:: | 
|  |  | 
|  | note: '(symbol)' in (file) at (row):(column) not always provided | 
|  |  | 
|  | Checks will also be performed for macro expansions, defined(macro) | 
|  | expressions, and preprocessor conditional directives that evaluate | 
|  | inconsistently, and can produce error messages like the following:: | 
|  |  | 
|  | (...)/SubHeader.h:11:5: | 
|  | #if SYMBOL == 1 | 
|  | ^ | 
|  | error: Macro instance 'SYMBOL' has different values in this header, | 
|  | depending on how it was included. | 
|  | 'SYMBOL' expanded to: '1' with respect to these inclusion paths: | 
|  | (...)/Header1.h | 
|  | (...)/SubHeader.h | 
|  | (...)/SubHeader.h:3:9: | 
|  | #define SYMBOL 1 | 
|  | ^ | 
|  | Macro defined here. | 
|  | 'SYMBOL' expanded to: '2' with respect to these inclusion paths: | 
|  | (...)/Header2.h | 
|  | (...)/SubHeader.h | 
|  | (...)/SubHeader.h:7:9: | 
|  | #define SYMBOL 2 | 
|  | ^ | 
|  | Macro defined here. | 
|  |  | 
|  | Checks will also be performed for '#include' directives that are | 
|  | nested inside 'extern "C/C++" {}' or 'namespace (name) {}' blocks, | 
|  | and can produce error message like the following:: | 
|  |  | 
|  | IncludeInExtern.h:2:3: | 
|  | #include "Empty.h" | 
|  | ^ | 
|  | error: Include directive within extern "C" {}. | 
|  | IncludeInExtern.h:1:1: | 
|  | extern "C" { | 
|  | ^ | 
|  | The "extern "C" {}" block is here. | 
|  |  | 
|  | .. _module-map-coverage: | 
|  |  | 
|  | Module Map Coverage Check | 
|  | ========================= | 
|  |  | 
|  | The coverage check uses the Clang library to read and parse the | 
|  | module map file. Starting at the module map file directory, or just the | 
|  | include paths, if specified, it will collect the names of all the files it | 
|  | considers headers (no extension, .h, or .inc--if you need more, modify the | 
|  | isHeader function). It then compares the headers against those referenced | 
|  | in the module map, either explicitly named, or implicitly named via an | 
|  | umbrella directory or umbrella file, as parsed by the ModuleMap object. | 
|  | If headers are found which are not referenced or covered by an umbrella | 
|  | directory or file, warning messages will be produced, and this program | 
|  | will return an error code of 1. If no problems are found, an error code of | 
|  | 0 is returned. | 
|  |  | 
|  | Note that in the case of umbrella headers, this tool invokes the compiler | 
|  | to preprocess the file, and uses a callback to collect the header files | 
|  | included by the umbrella header or any of its nested includes. If any | 
|  | front end options are needed for these compiler invocations, these | 
|  | can be included on the command line after the module map file argument. | 
|  |  | 
|  | Warning message have the form: | 
|  |  | 
|  | warning: module.modulemap does not account for file: Level3A.h | 
|  |  | 
|  | Note that for the case of the module map referencing a file that does | 
|  | not exist, the module map parser in Clang will (at the time of this | 
|  | writing) display an error message. | 
|  |  | 
|  | To limit the checks :program:`modularize` does to just the module | 
|  | map coverage check, use the ``-coverage-check-only option``. | 
|  |  | 
|  | For example:: | 
|  |  | 
|  | modularize -coverage-check-only module.modulemap | 
|  |  | 
|  | .. _module-map-generation: | 
|  |  | 
|  | Module Map Generation | 
|  | ===================== | 
|  |  | 
|  | If you specify the ``-module-map-path=<module map file>``, | 
|  | :program:`modularize` will output a module map based on the input header list. | 
|  | A module will be created for each header. Also, if the header in the header | 
|  | list is a partial path, a nested module hierarchy will be created in which a | 
|  | module will be created for each subdirectory component in the header path, | 
|  | with the header itself represented by the innermost module. If other headers | 
|  | use the same subdirectories, they will be enclosed in these same modules also. | 
|  |  | 
|  | For example, for the header list:: | 
|  |  | 
|  | SomeTypes.h | 
|  | SomeDecls.h | 
|  | SubModule1/Header1.h | 
|  | SubModule1/Header2.h | 
|  | SubModule2/Header3.h | 
|  | SubModule2/Header4.h | 
|  | SubModule2.h | 
|  |  | 
|  | The following module map will be generated:: | 
|  |  | 
|  | // Output/NoProblemsAssistant.txt | 
|  | // Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \ | 
|  | -root-module=Root NoProblemsAssistant.modularize | 
|  |  | 
|  | module SomeTypes { | 
|  | header "SomeTypes.h" | 
|  | export * | 
|  | } | 
|  | module SomeDecls { | 
|  | header "SomeDecls.h" | 
|  | export * | 
|  | } | 
|  | module SubModule1 { | 
|  | module Header1 { | 
|  | header "SubModule1/Header1.h" | 
|  | export * | 
|  | } | 
|  | module Header2 { | 
|  | header "SubModule1/Header2.h" | 
|  | export * | 
|  | } | 
|  | } | 
|  | module SubModule2 { | 
|  | module Header3 { | 
|  | header "SubModule2/Header3.h" | 
|  | export * | 
|  | } | 
|  | module Header4 { | 
|  | header "SubModule2/Header4.h" | 
|  | export * | 
|  | } | 
|  | header "SubModule2.h" | 
|  | export * | 
|  | } | 
|  |  | 
|  | An optional ``-root-module=<root-name>`` option can be used to cause a root module | 
|  | to be created which encloses all the modules. | 
|  |  | 
|  | An optional ``-problem-files-list=<problem-file-name>`` can be used to input | 
|  | a list of files to be excluded, perhaps as a temporary stop-gap measure until | 
|  | problem headers can be fixed. | 
|  |  | 
|  | For example, with the same header list from above:: | 
|  |  | 
|  | // Output/NoProblemsAssistant.txt | 
|  | // Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \ | 
|  | -root-module=Root NoProblemsAssistant.modularize | 
|  |  | 
|  | module Root { | 
|  | module SomeTypes { | 
|  | header "SomeTypes.h" | 
|  | export * | 
|  | } | 
|  | module SomeDecls { | 
|  | header "SomeDecls.h" | 
|  | export * | 
|  | } | 
|  | module SubModule1 { | 
|  | module Header1 { | 
|  | header "SubModule1/Header1.h" | 
|  | export * | 
|  | } | 
|  | module Header2 { | 
|  | header "SubModule1/Header2.h" | 
|  | export * | 
|  | } | 
|  | } | 
|  | module SubModule2 { | 
|  | module Header3 { | 
|  | header "SubModule2/Header3.h" | 
|  | export * | 
|  | } | 
|  | module Header4 { | 
|  | header "SubModule2/Header4.h" | 
|  | export * | 
|  | } | 
|  | header "SubModule2.h" | 
|  | export * | 
|  | } | 
|  | } | 
|  |  | 
|  | Note that headers with dependents will be ignored with a warning, as the | 
|  | Clang module mechanism doesn't support headers the rely on other headers | 
|  | to be included first. | 
|  |  | 
|  | The module map format defines some keywords which can't be used in module | 
|  | names. If a header has one of these names, an underscore ('_') will be | 
|  | prepended to the name. For example, if the header name is ``header.h``, | 
|  | because ``header`` is a keyword, the module name will be ``_header``. | 
|  | For a list of the module map keywords, please see: | 
|  | `Lexical structure <http://clang.llvm.org/docs/Modules.html#lexical-structure>`_ |