Summary: These were originally intended to represent the functions that are present on the GPU as to be provided by the LLVM libc implementation. The original plan was that LLVM libc would report which functions were supported and then the offload interface would mark those as supported. The problem is that these wrapper headers are very difficult to make work given the various libc extensions everyone does so they were extremely fragile. OpenMP already declares all functions used inside of a target region as implicitly host / device, while these headers weren't even used for CUDA / HIP yet anyway. The only things we need to define right now are the stdio FILE types. If we want to make this work for CUDA we'd need to define these manually, but we're a ways off and that's way easier because they do proper overloading.
196 lines
7.4 KiB
ReStructuredText
196 lines
7.4 KiB
ReStructuredText
.. _header_generation:
|
|
|
|
Generating Public and Internal headers
|
|
======================================
|
|
|
|
There are 3 main components of the Headergen. The first component are the YAML
|
|
files that contain all the function header information and are separated by
|
|
header specification and standard. The second component are the classes that
|
|
are created for each component of the function header: macros, enumerations,
|
|
types, function, arguments, and objects. The third component is the Python
|
|
script that uses the class representation to deserialize YAML files into its
|
|
specific components and then reserializes the components into the function
|
|
header. The Python script also combines the generated header content with
|
|
header definitions and extra macro and type inclusions from the .h.def file.
|
|
|
|
|
|
Instructions
|
|
------------
|
|
|
|
Required Versions:
|
|
- Python Version: 3.8
|
|
- PyYAML Version: 5.1
|
|
|
|
1. Keep full-build mode on when building, otherwise headers will not be
|
|
generated.
|
|
2. Once the build is complete, enter in the command line within the build
|
|
directory ``ninja check-hdrgen`` to ensure that the integration tests are
|
|
passing.
|
|
3. Then enter in the command line ``ninja libc`` to generate headers. Headers
|
|
will be in ``build/projects/libc/include`` or ``build/libc/include`` in a
|
|
runtime build. Sys spec headers will be located in
|
|
``build/projects/libc/include/sys``.
|
|
|
|
|
|
To add a function to the YAML files, you can either manually enter it in the
|
|
YAML file corresponding to the header it belongs to or add it through the
|
|
command line.
|
|
|
|
To add through the command line:
|
|
|
|
1. Make sure you are in the llvm-project directory.
|
|
|
|
2. Enter in the command line:
|
|
|
|
.. code-block:: none
|
|
|
|
python3 libc/utils/hdrgen/yaml_to_classes.py
|
|
libc/include/[yaml_file.yaml] --add_function "<return_type>" <function_name> "<function_arg1, function_arg2>" <standard> <guard> <attribute>
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
python3 libc/utils/hdrgen/yaml_to_classes.py
|
|
libc/include/ctype.yaml --add_function "char" example_function
|
|
"int, void, const void" stdc example_float example_attribute
|
|
|
|
Keep in mind only the return_type and arguments have quotes around them. If
|
|
you do not have any guards or attributes you may enter "null" for both.
|
|
|
|
3. Check the YAML file that the added function is present. You will also get a
|
|
generated header file with the new addition in the hdrgen directory to
|
|
examine.
|
|
|
|
If you want to sort the functions alphabetically you can check out
|
|
``libc/utils/hdrgen/hdrgen/yaml_functions_sorted.py``.
|
|
|
|
|
|
Testing
|
|
-------
|
|
|
|
Headergen has an integration test that you may run once you have configured
|
|
your CMake within the build directory. In the command line, enter the
|
|
following: ``ninja check-hdrgen``. The integration test is one test that
|
|
ensures the process of YAML to classes to generate headers works properly. If
|
|
there are any new additions on formatting headers, make sure the test is
|
|
updated with the specific addition.
|
|
|
|
Integration Test can be found in: ``libc/utils/hdrgen/tests/test_integration.py``
|
|
|
|
File to modify if adding something to formatting:
|
|
``libc/utils/hdrgen/tests/expected_output/test_header.h``
|
|
|
|
|
|
Common Errors
|
|
-------------
|
|
1. Missing function specific component
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
"/llvm-project/libc/utils/hdrgen/hdrgen/yaml_to_classes.py", line 67, in yaml_to_classes function_data["return_type"]
|
|
|
|
If you receive this error or any error pertaining to
|
|
``function_data[function_specific_component]`` while building the headers
|
|
that means the function specific component is missing within the YAML files.
|
|
Through the call stack, you will be able to find the header file which has
|
|
the issue. Ensure there is no missing function specific component for that
|
|
YAML header file.
|
|
|
|
2. CMake Error: require argument to be specified
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
CMake Error at:
|
|
/llvm-project/libc/cmake/modules/LLVMLibCHeaderRules.cmake:86 (message):
|
|
'add_gen_hdr' rule requires GEN_HDR to be specified.
|
|
Call Stack (most recent call first):
|
|
/llvm-project/libc/include/CMakeLists.txt:22 (add_gen_header)
|
|
/llvm-project/libc/include/CMakeLists.txt:62 (add_header_macro)
|
|
|
|
If you receive this error, there is a missing YAML file, h_def file, or
|
|
header name within the ``libc/include/CMakeLists.txt``. The last line in the
|
|
error call stack will point to the header where there is a specific component
|
|
missing. Ensure the correct style and required files are present:
|
|
|
|
| ``[header_name]``
|
|
| ``[../libc/include/[yaml_file.yaml]``
|
|
| ``[header_name.h]``
|
|
| ``DEPENDS``
|
|
| ``{Necessary Depend Files}``
|
|
|
|
3. Command line: expected arguments
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
usage: yaml_to_classes.py [-h] [--output_dir OUTPUT_DIR] [--h_def_file H_DEF_FILE]
|
|
[--add_function RETURN_TYPE NAME ARGUMENTS STANDARDS GUARD ATTRIBUTES]
|
|
[--e ENTRY_POINTS]
|
|
yaml_file
|
|
yaml_to_classes.py:
|
|
error: argument --add_function: expected 6 arguments
|
|
|
|
In the process of adding a function, you may run into an issue where the
|
|
command line is requiring more arguments than what you currently have. Ensure
|
|
that all components of the new function are filled. Even if you do not have a
|
|
guard or attribute, make sure to put null in those two areas.
|
|
|
|
4. Object has no attribute
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
File "/llvm-project/libc/utils/hdrgen/hdrgen/header.py", line 60, in __str__ for
|
|
function in self.functions: AttributeError: 'HeaderFile' object has no
|
|
attribute 'functions'
|
|
|
|
When running ``ninja libc`` in the build directory to generate headers you
|
|
may receive the error above. Essentially this means that in
|
|
``libc/utils/hdrgen/hdrgen/header.py`` there is a missing attribute named functions.
|
|
Make sure all function components are defined within this file and there are
|
|
no missing functions to add these components.
|
|
|
|
5. Unknown type name
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
/llvm-project/build/projects/libc/include/sched.h:20:25: error: unknown type
|
|
name 'size_t'; did you mean 'time_t'?
|
|
20 | int_sched_getcpucount(size_t, const cpu_set_t*) __NOEXCEPT
|
|
| ^
|
|
/llvm-project/build/projects/libc/include/llvm-libc-types/time_t.h:15:24:
|
|
note: 'time_t' declared here
|
|
15 | typedef __INT64_TYPE__ time_t;
|
|
| ^
|
|
|
|
During the header generation process errors like the one above may occur
|
|
because there are missing types for a specific header file. Check the YAML
|
|
file corresponding to the header file and make sure all the necessary types
|
|
that are being used are input into the types as well. Delete the specific
|
|
header file from the build folder and re-run ``ninja libc`` to ensure the
|
|
types are being recognized.
|
|
|
|
6. Test Integration Errors
|
|
|
|
Sometimes the integration test will fail but that
|
|
still means the process is working unless the comparison between the output
|
|
and expected_output is not showing. If that is the case make sure in
|
|
``libc/utils/hdrgen/tests/test_integration.py`` there are no missing arguments
|
|
that run through the script.
|
|
|
|
If the integration tests are failing due to mismatching of lines or small
|
|
errors in spacing that is nothing to worry about. If this is happening while
|
|
you are making a new change to the formatting of the headers, then
|
|
ensure the expected output file
|
|
``libc/utils/hdrgen/tests/expected_output/test_header.h`` has the changes you
|
|
are applying.
|