.. 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 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-generation: Module Map Generation ===================== If you specify the ``-module-map-path=``, :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=`` option can be used to cause a root module to be created which encloses all the modules. 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 `_