Skip to main content

Module include

Module include 

Source
Expand description

#include resolution: where a header is looked for, and what is bundled.

§Search order

#include "name" looks in

  1. the directory of the file the directive is written in — for the macro’s own text that is the directory of the invoking .rs file, and for a header it is the directory that header was found in;
  2. the configured include directories, in the order SearchPaths describes;
  3. 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::name is 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 for some/dir/thing.h from a directive written in some/dir, which neither of the first two steps will find. A bare name is deliberately left out of this step, so that a stdio.h sitting in the working directory never shadows the bundled one;
  4. the bundled headers;
  5. the platform’s own directories — /usr/include and 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 #embed found.
Resolved
A header that was found.
SearchPaths
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_path is resolved against.
SYSTEM_ENV_VAR
The environment variable that turns the platform’s directories on for a whole crate: 1 for System::Last, first for System::First.
SYSTEM_PATH_ENV_VAR
The environment variable that replaces system_directories’s per-target default, split the way the platform splits PATH.

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 #embed resource 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.