0
0
mirror of https://github.com/llvm/llvm-project.git synced 2025-04-23 05:26:05 +00:00
llvm-project/libcxx/utils/generate_libcxx_cppm_in.py
Louis Dionne d6e714b10e
[libc++] Rewrite the transitive header checking machinery ()
Since we don't generate a full dependency graph of headers, we can
greatly simplify the script that parses the result of --trace-includes.

At the same time, we also unify the mechanism for detecting whether a
header is a public/C compat/internal/etc header with the existing
mechanism in header_information.py.

As a drive-by this fixes the headers_in_modulemap.sh.py test which had
been disabled by mistake because it used its own way of determining
the list of libc++ headers. By consistently using header_information.py
to get that information, problems like this shouldn't happen anymore.

This should also unblock , which was blocked because of
a brittle implementation of the transitive includes check which broke
when the repository was cloned at a path like /path/__something/more.
2024-10-22 09:18:58 -04:00

96 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ===----------------------------------------------------------------------===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===----------------------------------------------------------------------===##
import os.path
import sys
from libcxx.header_information import module_c_headers, module_headers, header_restrictions, headers_not_available, libcxx_root
def write_file(module):
with open(libcxx_root / "modules" / f"{module}.cppm.in", "w") as module_cpp_in:
module_cpp_in.write(
"""\
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// WARNING, this entire header is generated by
// utils/generate_libcxx_cppm_in.py
// DO NOT MODIFY!
module;
#include <__config>
// The headers of Table 24: C++ library headers[tab:headers.cpp]
// and the headers of Table 25: C++ headers for C library facilities[tab:headers.cpp.c]
"""
)
for header in sorted(module_headers if module == "std" else module_c_headers):
if header in header_restrictions:
module_cpp_in.write(
f"""\
#if {header_restrictions[header]}
# include <{header}>
#endif
"""
)
else:
module_cpp_in.write(f"#include <{header}>\n")
module_cpp_in.write(
"""
// *** Headers not yet available ***
//
// This validation is mainly to catch when a new header is added but adding the
// corresponding .inc file is forgotten. However, the check based on __has_include
// alone doesn't work on Windows because the Windows SDK is on the include path,
// and that means the MSVC STL headers can be found as well, tricking __has_include
// into thinking that libc++ provides the header.
//
#ifndef _WIN32
"""
)
for header in sorted(headers_not_available):
module_cpp_in.write(
f"""\
# if __has_include(<{header}>)
# error "please update the header information for <{header}> in headers_not_available in utils/libcxx/header_information.py"
# endif // __has_include(<{header}>)
"""
)
module_cpp_in.write(
f"""#endif // _WIN32
export module {module};
{'export import std;' if module == 'std.compat' else ''}
{'@LIBCXX_MODULE_STD_INCLUDE_SOURCES@' if module == 'std' else ''}
{'@LIBCXX_MODULE_STD_COMPAT_INCLUDE_SOURCES@' if module == 'std.compat' else ''}"""
)
if __name__ == "__main__":
if len(sys.argv) != 2 or (sys.argv[1] != "std" and sys.argv[1] != "std.compat"):
sys.stderr.write(
f"""\
Usage:
{os.path.basename(__file__)} (std|std.compat)
"""
)
sys.exit(1)
write_file(sys.argv[1])