pub struct SearchPath { /* private fields */ }Expand description
The directories a header is looked for in, in order.
GCC’s order, because a different one produces header shadowing bugs that are miserable to
diagnose: -iquote first and only for a quoted include, then -I, then -isystem, then
the configured system directories, then -idirafter. The directory of the including file
comes before all of it for a quoted include, and it is not part of the numbered list
because #include_next must not be able to land back on it.
Implementations§
Source§impl SearchPath
impl SearchPath
Sourcepub fn new() -> SearchPath
pub fn new() -> SearchPath
An empty search path.
Sourcepub fn push_quote(&mut self, dir: impl Into<PathBuf>)
pub fn push_quote(&mut self, dir: impl Into<PathBuf>)
Adds a -iquote directory, searched only for a quoted include.
Sourcepub fn push_bracket(&mut self, dir: impl Into<PathBuf>)
pub fn push_bracket(&mut self, dir: impl Into<PathBuf>)
Adds a -I directory.
Sourcepub fn push_system(&mut self, dir: impl Into<PathBuf>)
pub fn push_system(&mut self, dir: impl Into<PathBuf>)
Adds a -isystem directory, or one of the target’s configured system directories.
Sourcepub fn push_after(&mut self, dir: impl Into<PathBuf>)
pub fn push_after(&mut self, dir: impl Into<PathBuf>)
Adds a -idirafter directory, which is searched after everything else.
Sourcepub fn split_quote_chain(&mut self)
pub fn split_quote_chain(&mut self)
Makes every directory added so far reachable only by a quoted include, which is -I-.
The flag GCC deprecated in favour of -iquote and still supports, because a build system
old enough to be worth compiling is old enough to pass it. It does two things at once. The
-I directories written before it move into the quoted chain, so #include <x.h> stops
seeing them, and the directory of the including file comes off the front of that chain, so
#include "x.h" stops looking next to the file that wrote it.
The second half is the reason the flag was worth having and the reason it was worth
dropping. It is the only way to say that a quoted include means a directory the command
line named rather than whatever happens to sit beside the source, which is what a project
with two headers of the same name in two directories needs. It is also a global answer to
a question every include asks separately, which is why -iquote replaced it.
A -iquote directory given before this stays in the quoted chain, and lands after the
-I directories that just joined it. That is GCC’s order and not an accident of the
implementation: GCC holds -iquote back until every -I and -I- has been dealt with,
so a -iquote is always later in the chain than an -I whatever order they were written.
Sourcepub fn searches_current_dir(&self) -> bool
pub fn searches_current_dir(&self) -> bool
Whether the directory of the including file is searched for a quoted include.
False once -I- has been given. A caller that has a directory to offer still passes it,
and this is where it is refused, so that the rule lives with the search path rather than at
every call site that knows where a file came from.
Sourcepub fn remove_duplicates(&mut self)
pub fn remove_duplicates(&mut self)
Drops the directories that are already on the path, the way GCC does.
A duplicate is not a harmless extra entry that costs one failed open. It changes what
#include_next means, which is defined as continuing past the directory the current
file came from: a header found in the first /usr/include writes #include_next <stdint.h> meaning “the one below me” and finds itself in the second, and a header set
that ends in a fixed point of its own is one that includes itself forever or answers
__has_include_next yes where the compiler it was written for said no. It shows up as
soon as somebody passes the system directories on the command line, which the compat
harness does deliberately and a build system does by accident.
A -I that names a system directory loses to the system entry rather than the other way
round, and that is GCC’s rule and is documented as one: keeping the earlier one would
move a system directory up the order and take the system treatment off the headers in
it, so the -I is the one that goes.
Two names for one directory are two directories here, where GCC compares the device and the inode and sees through a symlink. That wants a file system that can answer the question and this one deliberately only reads.
Sourcepub fn start(&self, form: IncludeForm) -> usize
pub fn start(&self, form: IncludeForm) -> usize
The first entry an include of this form looks at.
An angled include skips the -iquote directories, which is the only difference
between the two chains once the including file’s own directory is out of the way.
Sourcepub fn resolve(
&self,
fs: &dyn FileSystem,
name: &str,
form: IncludeForm,
relative_to: Option<&Path>,
from: usize,
) -> Option<Found>
pub fn resolve( &self, fs: &dyn FileSystem, name: &str, form: IncludeForm, relative_to: Option<&Path>, from: usize, ) -> Option<Found>
Finds name, starting at entry from of the search path.
relative_to is the directory of the file doing the including, tried first for a
quoted include and ignored otherwise. Pass None for an #include_next, which is
defined as continuing past the directory the current file was found in and so must not
look next to it again. It is also ignored after SearchPath::split_quote_chain, which
is what -I- asks for.
An absolute name is opened directly and the search path is not consulted, which is what every C compiler does and what a generated header with an absolute path needs.
Sourcepub fn tried(
&self,
name: &str,
form: IncludeForm,
relative_to: Option<&Path>,
from: usize,
) -> Vec<PathBuf>
pub fn tried( &self, name: &str, form: IncludeForm, relative_to: Option<&Path>, from: usize, ) -> Vec<PathBuf>
The directories a failed SearchPath::resolve with the same arguments looked in.
spec/05-preprocessor.md section 5.7 makes printing this the required behaviour for a
failed include, because “file not found” without the list of places that were tried is
the diagnostic that wastes the most time in this part of the compiler.
Trait Implementations§
Source§impl Clone for SearchPath
impl Clone for SearchPath
Source§fn clone(&self) -> SearchPath
fn clone(&self) -> SearchPath
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more