[libc++][Android] Allow testing libc++ with clang-r536225 (#116149)
[llvm-project.git] / libc / docs / dev / header_generation.rst
blobec4206217ca777995c2d840191761a7c7c986ce0
1 .. _header_generation:
3 Generating Public and Internal headers
4 ======================================
6 This is a new implementation of the previous libc header generator. The old
7 header generator (libc-hdrgen aka "Headergen") was based on TableGen, which
8 created an awkward dependency on the rest of LLVM for our build system. By
9 creating a new standalone Headergen we can eliminate these dependencies for
10 easier cross compatibility.
12 There are 3 main components of the new Headergen. The first component are the
13 YAML files that contain all the function header information and are separated by
14 header specification and standard. The second component are the classes that are
15 created for each component of the function header: macros, enumerations, types,
16 function, arguments, and objects. The third component is the Python script that
17 uses the class representation to deserialize YAML files into its specific
18 components and then reserializes the components into the function header. The
19 Python script also combines the generated header content with header definitions
20 and extra macro and type inclusions from the .h.def file.
23 Instructions
24 ------------
26 Required Versions:
27   - Python Version: 3.8
28   - PyYAML Version: 5.1
30 1. Keep full-build mode on when building, otherwise headers will not be
31    generated.
32 2. Once the build is complete, enter in the command line within the build
33    directory ``ninja check-newhdrgen`` to ensure that the integration tests are
34    passing.
35 3. Then enter in the command line ``ninja libc`` to generate headers. Headers
36    will be in ``build/projects/libc/include`` or ``build/libc/include`` in a
37    runtime build. Sys spec headers will be located in
38    ``build/projects/libc/include/sys``.
41 New Headergen is turned on by default, but if you want to use old Headergen,
42 you can include this statement when building: ``-DLIBC_USE_NEW_HEADER_GEN=OFF``
44 To add a function to the YAML files, you can either manually enter it in the
45 YAML file corresponding to the header it belongs to or add it through the
46 command line.
48 To add through the command line:
50 1. Make sure you are in the llvm-project directory.
52 2. Enter in the command line:
54    .. code-block:: none
56      python3 libc/newhdrgen/yaml_to_classes.py
57      libc/newhdrgen/yaml/[yaml_file.yaml] --add_function "<return_type>" <function_name> "<function_arg1, function_arg2>" <standard> <guard> <attribute>
59    Example:
61    .. code-block:: none
63       python3 libc/newhdrgen/yaml_to_classes.py
64       libc/newhdrgen/yaml/ctype.yaml --add_function "char" example_function
65       "int, void, const void" stdc example_float example_attribute
67    Keep in mind only the return_type and arguments have quotes around them. If
68    you do not have any guards or attributes you may enter "null" for both.
70 3. Check the YAML file that the added function is present. You will also get a
71    generated header file with the new addition in the newhdrgen directory to
72    examine.
74 If you want to sort the functions alphabetically you can check out libc/newhdrgen/yaml_functions_sorted.py.
77 Testing
78 -------
80 New Headergen has an integration test that you may run once you have configured
81 your CMake within the build directory. In the command line, enter the following:
82 ``ninja check-newhdrgen``. The integration test is one test that ensures the
83 process of YAML to classes to generate headers works properly. If there are any
84 new additions on formatting headers, make sure the test is updated with the
85 specific addition.
87 Integration Test can be found in: ``libc/newhdrgen/tests/test_integration.py``
89 File to modify if adding something to formatting:
90 ``libc/newhdrgen/tests/expected_output/test_header.h``
93 Common Errors
94 -------------
95 1. Missing function specific component
97    Example:
99    .. code-block:: none
101       "/llvm-project/libc/newhdrgen/yaml_to_classes.py", line 67, in yaml_to_classes function_data["return_type"]
103    If you receive this error or any error pertaining to
104    ``function_data[function_specific_component]`` while building the headers
105    that means the function specific component is missing within the YAML files.
106    Through the call stack, you will be able to find the header file which has
107    the issue. Ensure there is no missing function specific component for that
108    YAML header file.
110 2. CMake Error: require argument to be specified
112    Example:
114    .. code-block:: none
116      CMake Error at:
117      /llvm-project/libc/cmake/modules/LLVMLibCHeaderRules.cmake:86 (message):
118      'add_gen_hdr2' rule requires GEN_HDR to be specified.
119      Call Stack (most recent call first):
120      /llvm-project/libc/include/CMakeLists.txt:22 (add_gen_header2)
121      /llvm-project/libc/include/CMakeLists.txt:62 (add_header_macro)
123    If you receive this error, there is a missing YAML file, h_def file, or
124    header name within the ``libc/include/CMakeLists.txt``. The last line in the
125    error call stack will point to the header where there is a specific component
126    missing. Ensure the correct style and required files are present:
128    | ``[header_name]``
129    | ``[../libc/newhdrgen/yaml/[yaml_file.yaml]``
130    | ``[header_name.h.def]``
131    | ``[header_name.h]``
132    | ``DEPENDS``
133    |   ``{Necessary Depend Files}``
135 3. Command line: expected arguments
137    Example:
139    .. code-block:: none
141      usage: yaml_to_classes.py [-h] [--output_dir OUTPUT_DIR] [--h_def_file H_DEF_FILE]
142      [--add_function RETURN_TYPE NAME ARGUMENTS STANDARDS GUARD ATTRIBUTES]
143      [--e ENTRY_POINTS] [--export-decls]
144      yaml_file
145      yaml_to_classes.py:
146      error: argument --add_function: expected 6 arguments
148    In the process of adding a function, you may run into an issue where the
149    command line is requiring more arguments than what you currently have. Ensure
150    that all components of the new function are filled. Even if you do not have a
151    guard or attribute, make sure to put null in those two areas.
153 4. Object has no attribute
155    Example:
157    .. code-block:: none
159      File "/llvm-project/libc/newhdrgen/header.py", line 60, in __str__ for
160      function in self.functions: AttributeError: 'HeaderFile' object has no
161      attribute 'functions'
163    When running ``ninja libc`` in the build directory to generate headers you
164    may receive the error above. Essentially this means that in
165    ``libc/newhdrgen/header.py`` there is a missing attribute named functions.
166    Make sure all function components are defined within this file and there are
167    no missing functions to add these components.
169 5. Unknown type name
171    Example:
173    .. code-block:: none
175      /llvm-project/build/projects/libc/include/sched.h:20:25: error: unknown type
176      name 'size_t'; did you mean 'time_t'?
177      20 | int_sched_getcpucount(size_t, const cpu_set_t*) __NOEXCEPT
178       |           ^
179      /llvm-project/build/projects/libc/include/llvm-libc-types/time_t.h:15:24:
180      note: 'time_t' declared here
181      15 | typedef __INT64_TYPE__ time_t;
182      |                    ^
184    During the header generation process errors like the one above may occur
185    because there are missing types for a specific header file. Check the YAML
186    file corresponding to the header file and make sure all the necessary types
187    that are being used are input into the types as well. Delete the specific
188    header file from the build folder and re-run ``ninja libc`` to ensure the
189    types are being recognized.
191 6. Test Integration Errors
193    Sometimes the integration test will fail but that
194    still means the process is working unless the comparison between the output
195    and expected_output is not showing. If that is the case make sure in
196    ``libc/newhdrgen/tests/test_integration.py`` there are no missing arguments
197    that run through the script.
199    If the integration tests are failing due to mismatching of lines or small
200    errors in spacing that is nothing to worry about. If this is happening while
201    you are making a new change to the formatting of the headers, then
202    ensure the expected output file
203    ``libc/newhdrgen/tests/expected_output/test_header.h`` has the changes you
204    are applying.