forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			266 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
| .. 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: https://llvm.org/docs/GettingStarted.html
 | |
| .. _Building LLVM with CMake: https://llvm.org/docs/CMake.html
 | |
| .. _Clang Tools Documentation: https://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 <https://clang.llvm.org/docs/Modules.html#lexical-structure>`_
 |