Skip to content

Commit f626a35

Browse files
[libc] Codify header inclusion policy (#87017)
When supporting "overlay" vs "fullbuild" modes, "what ABI are you using?" becomes a fundamental question to have concrete answers for. Overlay mode MUST match the ABI of the system being overlayed onto; fullbuild more flexible (the only system ABI relevant is the OS kernel). When implementing llvm-libc we generally prefer the include-what-you use style of avoiding transitive dependencies (since that makes refactoring headers more painful, and slows down build times). So what header do you include for any given type or function declaration? For any given userspace program, the answer is straightforward. But for llvm-libc which is trying to support multiple ABIs (at least one per configuration), the answer is perhaps less clear. This proposal seeks to add one layer of indirection relative to what's being done today. It then converts users of sigset_t and struct epoll_event and the epoll implemenations over to this convention as an example.
1 parent 5122a2c commit f626a35

29 files changed

+200
-73
lines changed

libc/docs/dev/code_style.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,36 @@ We expect contributions to be free of warnings from the `minimum supported
186186
compiler versions`__ (and newer).
187187

188188
.. __: https://libc.llvm.org/compiler_support.html#minimum-supported-versions
189+
190+
Header Inclusion Policy
191+
=======================
192+
193+
Because llvm-libc supports
194+
`Overlay Mode <https://libc.llvm.org/overlay_mode.html>`__ and
195+
`Fullbuild Mode <https://libc.llvm.org/fullbuild_mode.html>`__ care must be
196+
taken when ``#include``'ing certain headers.
197+
198+
The ``include/`` directory contains public facing headers that users must
199+
consume for fullbuild mode. As such, types defined here will have ABI
200+
implications as these definitions may differ from the underlying system for
201+
overlay mode and are NEVER appropriate to include in ``libc/src/`` without
202+
preprocessor guards for ``LLVM_LIBC_FULL_BUILD``.
203+
204+
Consider the case where an implementation in ``libc/src/`` may wish to refer to
205+
a ``sigset_t``, what header should be included? ``<signal.h>``, ``<spawn.h>``,
206+
``<sys/select.h>``?
207+
208+
None of the above. Instead, code under ``src/`` should ``#include
209+
"hdr/types/sigset_t.h"`` which contains preprocessor guards on
210+
``LLVM_LIBC_FULL_BUILD`` to either include the public type (fullbuild mode) or
211+
the underlying system header (overlay mode).
212+
213+
Implementations in ``libc/src/`` should NOT be ``#include``'ing using ``<>`` or
214+
``"include/*``, except for these "proxy" headers that first check for
215+
``LLVM_LIBC_FULL_BUILD``.
216+
217+
These "proxy" headers are similarly used when referring to preprocessor
218+
defines. Code under ``libc/src/`` should ``#include`` a proxy header from
219+
``hdr/``, which contains a guard on ``LLVM_LIBC_FULL_BUILD`` to either include
220+
our header from ``libc/include/`` (fullbuild) or the corresponding underlying
221+
system header (overlay).

libc/docs/usage_modes.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The libc can used in two different modes:
66

77
#. The **overlay** mode: In this mode, the link order semantics are exploited
88
to overlay implementations from LLVM's libc over the system libc. See
9-
:ref:`overlay_mode` for more information about this mode.
9+
:ref:`overlay_mode` for more information about this mode. In this mode, libc
10+
uses the ABI of the system it's being overlayed onto. Headers are NOT
11+
generated. libllvmlibc.a is the only build artifact.
1012
#. The **fullbuild** mode: In this mode, LLVM's libc is used as the only libc
1113
for the binary. See :ref:`fullbuild_mode` for information about this mode.
14+
In this mode, libc uses its own ABI. Headers are generated along with a
15+
libc.a.

libc/hdr/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@ add_proxy_header_library(
4040
libc.include.llvm-libc-macros.fenv_macros
4141
libc.include.fenv
4242
)
43+
44+
add_subdirectory(types)

libc/hdr/types/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
add_proxy_header_library(
2+
sigset_t
3+
HDRS
4+
sigset_t.h
5+
FULL_BUILD_DEPENDS
6+
libc.include.llvm-libc-types.sigset_t
7+
)
8+
9+
add_proxy_header_library(
10+
struct_epoll_event
11+
HDRS
12+
struct_epoll_event.h
13+
FULL_BUILD_DEPENDS
14+
libc.include.llvm-libc-types.struct_epoll_event
15+
)
16+
17+
add_proxy_header_library(
18+
struct_timespec
19+
HDRS
20+
struct_timespec.h
21+
FULL_BUILD_DEPENDS
22+
libc.include.llvm-libc-types.struct_timespec
23+
)

libc/hdr/types/sigset_t.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Proxy for sigset_t ------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#ifndef LLVM_LIBC_HDR_TYPES_SIGSET_T_H
9+
#define LLVM_LIBC_HDR_TYPES_SIGSET_T_H
10+
11+
#ifdef LIBC_FULL_BUILD
12+
13+
#include "include/llvm-libc-types/sigset_t.h"
14+
15+
#else
16+
17+
#include <signal.h>
18+
19+
#endif // LIBC_FULL_BUILD
20+
21+
#endif // LLVM_LIBC_HDR_TYPES_SIGSET_T_H

libc/hdr/types/struct_epoll_event.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Proxy for struct epoll_event --------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_EPOLL_EVENT_H
9+
#define LLVM_LIBC_HDR_TYPES_STRUCT_EPOLL_EVENT_H
10+
11+
#ifdef LIBC_FULL_BUILD
12+
13+
#include "include/llvm-libc-types/struct_epoll_event.h"
14+
15+
#else
16+
17+
#include <sys/epoll.h>
18+
19+
#endif // LIBC_FULL_BUILD
20+
21+
#endif // LLVM_LIBC_HDR_TYPES_STRUCT_EPOLL_EVENT_H

libc/hdr/types/struct_timespec.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Proxy for struct timespec ----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_TIMESPEC_H
9+
#define LLVM_LIBC_HDR_TYPES_STRUCT_TIMESPEC_H
10+
11+
#ifdef LIBC_FULL_BUILD
12+
13+
#include "include/llvm-libc-types/struct_timespec.h"
14+
15+
#else
16+
17+
#include <time.h>
18+
19+
#endif // LIBC_FULL_BUILD
20+
21+
#endif // LLVM_LIBC_HDR_TYPES_STRUCT_TIMESPEC_H

libc/src/signal/linux/CMakeLists.txt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ add_header_library(
33
HDRS
44
signal_utils.h
55
DEPENDS
6+
libc.hdr.types.sigset_t
7+
libc.include.signal
68
libc.include.sys_syscall
79
libc.src.__support.OSUtil.osutil
810
)
@@ -28,7 +30,7 @@ add_entrypoint_object(
2830
../raise.h
2931
DEPENDS
3032
.signal_utils
31-
libc.include.signal
33+
libc.hdr.types.sigset_t
3234
libc.include.sys_syscall
3335
libc.src.__support.OSUtil.osutil
3436
)
@@ -57,7 +59,7 @@ add_entrypoint_object(
5759
../sigaction.h
5860
DEPENDS
5961
.__restore
60-
libc.include.signal
62+
libc.hdr.types.sigset_t
6163
libc.include.sys_syscall
6264
libc.src.__support.OSUtil.osutil
6365
libc.src.errno.errno
@@ -84,7 +86,7 @@ add_entrypoint_object(
8486
../sigprocmask.h
8587
DEPENDS
8688
.signal_utils
87-
libc.include.signal
89+
libc.hdr.types.sigset_t
8890
libc.include.sys_syscall
8991
libc.src.__support.OSUtil.osutil
9092
libc.src.errno.errno
@@ -98,7 +100,7 @@ add_entrypoint_object(
98100
../sigemptyset.h
99101
DEPENDS
100102
.signal_utils
101-
libc.include.signal
103+
libc.hdr.types.sigset_t
102104
libc.src.errno.errno
103105
)
104106

@@ -110,7 +112,7 @@ add_entrypoint_object(
110112
../sigaddset.h
111113
DEPENDS
112114
.signal_utils
113-
libc.include.signal
115+
libc.hdr.types.sigset_t
114116
libc.src.errno.errno
115117
)
116118

@@ -133,7 +135,7 @@ add_entrypoint_object(
133135
../sigfillset.h
134136
DEPENDS
135137
.signal_utils
136-
libc.include.signal
138+
libc.hdr.types.sigset_t
137139
libc.src.errno.errno
138140
)
139141

@@ -145,6 +147,6 @@ add_entrypoint_object(
145147
../sigdelset.h
146148
DEPENDS
147149
.signal_utils
148-
libc.include.signal
150+
libc.hdr.types.sigset_t
149151
libc.src.errno.errno
150152
)

libc/src/signal/linux/raise.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/signal/raise.h"
10-
#include "src/signal/linux/signal_utils.h"
1110

11+
#include "hdr/types/sigset_t.h"
1212
#include "src/__support/common.h"
13+
#include "src/signal/linux/signal_utils.h"
1314

1415
namespace LIBC_NAMESPACE {
1516

1617
LLVM_LIBC_FUNCTION(int, raise, (int sig)) {
17-
::sigset_t sigset;
18+
sigset_t sigset;
1819
block_all_signals(sigset);
1920
long pid = LIBC_NAMESPACE::syscall_impl<long>(SYS_getpid);
2021
long tid = LIBC_NAMESPACE::syscall_impl<long>(SYS_gettid);

libc/src/signal/linux/sigaction.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/signal/sigaction.h"
10-
#include "src/errno/libc_errno.h"
11-
#include "src/signal/linux/signal_utils.h"
1210

11+
#include "hdr/types/sigset_t.h"
1312
#include "src/__support/common.h"
14-
15-
#include <signal.h>
13+
#include "src/errno/libc_errno.h"
14+
#include "src/signal/linux/signal_utils.h"
1615

1716
namespace LIBC_NAMESPACE {
1817

libc/src/signal/linux/sigaddset.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/signal/sigaddset.h"
10+
11+
#include "hdr/types/sigset_t.h"
1012
#include "src/__support/common.h"
1113
#include "src/errno/libc_errno.h"
1214
#include "src/signal/linux/signal_utils.h"
1315

14-
#include <signal.h>
15-
1616
namespace LIBC_NAMESPACE {
1717

1818
LLVM_LIBC_FUNCTION(int, sigaddset, (sigset_t * set, int signum)) {

libc/src/signal/linux/sigdelset.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/signal/sigdelset.h"
10+
11+
#include "hdr/types/sigset_t.h"
1012
#include "src/__support/common.h"
1113
#include "src/errno/libc_errno.h"
1214
#include "src/signal/linux/signal_utils.h"
1315

14-
#include <signal.h>
15-
1616
namespace LIBC_NAMESPACE {
1717

1818
LLVM_LIBC_FUNCTION(int, sigdelset, (sigset_t * set, int signum)) {

libc/src/signal/linux/sigfillset.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/signal/sigfillset.h"
10+
11+
#include "hdr/types/sigset_t.h"
1012
#include "src/__support/common.h"
1113
#include "src/errno/libc_errno.h"
1214
#include "src/signal/linux/signal_utils.h"
1315

14-
#include <signal.h>
15-
1616
namespace LIBC_NAMESPACE {
1717

1818
LLVM_LIBC_FUNCTION(int, sigfillset, (sigset_t * set)) {

libc/src/signal/linux/signal_utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
#ifndef LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
1010
#define LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
1111

12+
#include "hdr/types/sigset_t.h"
1213
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
1314
#include "src/__support/common.h"
1415

15-
#include <signal.h>
16+
#include <signal.h> // sigaction
1617
#include <stddef.h>
1718
#include <sys/syscall.h> // For syscall numbers.
1819

libc/src/signal/linux/sigprocmask.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/signal/sigprocmask.h"
10+
11+
#include "hdr/types/sigset_t.h"
1012
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
13+
#include "src/__support/common.h"
1114
#include "src/errno/libc_errno.h"
1215
#include "src/signal/linux/signal_utils.h"
1316

14-
#include "src/__support/common.h"
15-
16-
#include <signal.h>
1717
#include <sys/syscall.h> // For syscall numbers.
1818

1919
namespace LIBC_NAMESPACE {

libc/src/signal/sigaddset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef LLVM_LIBC_SRC_SIGNAL_SIGADDSET_H
1010
#define LLVM_LIBC_SRC_SIGNAL_SIGADDSET_H
1111

12-
#include <signal.h>
12+
#include "hdr/types/sigset_t.h"
1313

1414
namespace LIBC_NAMESPACE {
1515

libc/src/signal/sigdelset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef LLVM_LIBC_SRC_SIGNAL_SIGDELSET_H
1010
#define LLVM_LIBC_SRC_SIGNAL_SIGDELSET_H
1111

12-
#include <signal.h>
12+
#include "hdr/types/sigset_t.h"
1313

1414
namespace LIBC_NAMESPACE {
1515

libc/src/signal/sigemptyset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef LLVM_LIBC_SRC_SIGNAL_SIGEMPTYSET_H
1010
#define LLVM_LIBC_SRC_SIGNAL_SIGEMPTYSET_H
1111

12-
#include <signal.h>
12+
#include "hdr/types/sigset_t.h"
1313

1414
namespace LIBC_NAMESPACE {
1515

libc/src/signal/sigfillset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef LLVM_LIBC_SRC_SIGNAL_SIGFILLSET_H
1010
#define LLVM_LIBC_SRC_SIGNAL_SIGFILLSET_H
1111

12-
#include <signal.h>
12+
#include "hdr/types/sigset_t.h"
1313

1414
namespace LIBC_NAMESPACE {
1515

libc/src/signal/sigprocmask.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef LLVM_LIBC_SRC_SIGNAL_SIGPROCMASK_H
1010
#define LLVM_LIBC_SRC_SIGNAL_SIGPROCMASK_H
1111

12-
#include <signal.h>
12+
#include "hdr/types/sigset_t.h"
1313

1414
namespace LIBC_NAMESPACE {
1515

libc/src/sys/epoll/epoll_pwait.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@
99
#ifndef LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT_H
1010
#define LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT_H
1111

12-
// TODO: Use this include once the include headers are also using quotes.
13-
// #include "include/llvm-libc-types/sigset_t.h"
14-
// #include "include/llvm-libc-types/struct_epoll_event.h"
15-
16-
#include <sys/epoll.h>
12+
#include "hdr/types/sigset_t.h"
13+
#include "hdr/types/struct_epoll_event.h"
1714

1815
namespace LIBC_NAMESPACE {
1916

libc/src/sys/epoll/epoll_pwait2.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@
99
#ifndef LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT2_H
1010
#define LLVM_LIBC_SRC_SYS_EPOLL_EPOLL_PWAIT2_H
1111

12-
// TODO: Use this include once the include headers are also using quotes.
13-
// #include "include/llvm-libc-types/sigset_t.h"
14-
// #include "include/llvm-libc-types/struct_epoll_event.h"
15-
// #include "include/llvm-libc-types/struct_timespec.h"
16-
17-
#include <sys/epoll.h>
12+
#include "hdr/types/sigset_t.h"
13+
#include "hdr/types/struct_epoll_event.h"
14+
#include "hdr/types/struct_timespec.h"
1815

1916
namespace LIBC_NAMESPACE {
2017

0 commit comments

Comments
 (0)