Expand description
#include resolution: where a header is looked for, and what is bundled.
§Search order
#include "name" looks in
- the directory of the file the directive is written in — for the macro’s
own text that is the directory of the invoking
.rsfile, and for a header it is the directory that header was found in; - the configured include directories, in the order
SearchPathsdescribes; - the working directory, but only when the name is a path — when it
holds a directory separator. That is what makes
#include __FILE__work:Resolved::nameis written relative to the working directory wherever it can be (a diagnostic naming an absolute path is a diagnostic that differs between two machines), so a header that includes itself by__FILE__is asking forsome/dir/thing.hfrom a directive written insome/dir, which neither of the first two steps will find. A bare name is deliberately left out of this step, so that astdio.hsitting in the working directory never shadows the bundled one; - the bundled headers;
- the platform’s own directories —
/usr/includeand friends — but only when the switch is on.
#include <name> skips steps 1 and 3. A name that is absolute is used as
it stands.
§The platform’s own directories
Step 5 is off by default, and everything above it is enough for a
self-contained, target-model-portable unit. A real <stdio.h> is not
plain C: glibc’s is a thicket of __attribute__, __extension__,
__asm__ renaming and compiler builtins, and its layouts are the host’s
rather than the target model’s. So cinrs ships its own
small, plain-C99 declarations of the standard library: they declare exactly
what the platform’s real library exports, the linker binds the calls to the
real implementation, and the C that uses them is ordinary C.
What the bundled set cannot give is the things whose layout only the
platform knows — struct stat, DIR, pthread_mutex_t, the real
FILE — so a program that needs those turns the switch on with
#pragma cinrs system_include (or CINRS_SYSTEM_INCLUDE=1 in the
environment, which is the crate-wide default the pragma overrides). With
System::Last the bundled headers still win, and only a name they do not
carry reaches the platform; with System::First the platform’s copy of
every header wins, which is what makes FILE the real struct _IO_FILE.
The directories searched are SYSTEM_PATH_ENV_VAR when it is set, and
otherwise system_directories’s per-target default. The compiler’s own
private directories are never among them: GCC’s and Clang’s
.../include/{limits,stdint,stddef,stdarg}.h chain to the next header of
the same name with #include_next and expect their own compiler’s
builtins, and every one of those headers is bundled here anyway.
Nothing found under step 5 is tracked for rebuilds: a system header is part
of the machine rather than of the crate, and include_str!-ing
/usr/include/stdio.h into the build would make every unit rebuild when the
libc package is upgraded, which is not what the file identifies.
Structs§
- Embedded
- A resource
#embedfound. - Resolved
- A header that was found.
- Search
Paths - The include directories a unit searches, in the order it searches them.
Enums§
- Entry
- One place a search looks, in the order it looks.
- Error
- Why a header could not be included.
- Form
- How the header name was spelled.
- Origin
- The directory a file’s own
#include "…"searches first. - System
- Whether the platform’s own include directories are searched, and where in the order they go.
Constants§
- BUNDLED
- The bundled standard headers, as
(name, text)pairs. - BUNDLED_
DIR - The directory the bundled headers appear to live in.
- ENV_VAR
- The environment variable holding a global list of include directories.
- MANIFEST_
DIR_ VAR - The environment variable Cargo sets to the package’s own directory, which
is what a relative
#pragma cinrs include_pathis resolved against. - SYSTEM_
ENV_ VAR - The environment variable that turns the platform’s directories on for a
whole crate:
1forSystem::Last,firstforSystem::First. - SYSTEM_
PATH_ ENV_ VAR - The environment variable that replaces
system_directories’s per-target default, split the way the platform splitsPATH.
Functions§
- bundled
- The text of a bundled header, by name.
- bundled_
name - The display name a bundled header is known by:
<cinrs>/stdio.h. - display_
path - How a path is written in a diagnostic.
- read_
source - Reads the file an
include_c99!("…")names. - resolve
- Looks a header name up.
- resolve_
embed - Looks an
#embedresource up (C23 6.10.3). - resolve_
next #include_next <name>: the same search, taken up again at the entry after the one the file writing the directive was found under.- system_
directories - The platform’s own include directories for
target, when nothing named them.