Line data Source code
1 : /* Set up combined include path chain for the preprocessor.
2 : Copyright (C) 1986-2026 Free Software Foundation, Inc.
3 :
4 : Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
5 :
6 : This program is free software; you can redistribute it and/or modify it
7 : under the terms of the GNU General Public License as published by the
8 : Free Software Foundation; either version 3, or (at your option) any
9 : later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "config.h"
21 : #include "system.h"
22 : #include "coretypes.h"
23 : #include "target.h"
24 : #include "cpplib.h"
25 : #include "prefix.h"
26 : #include "intl.h"
27 : #include "incpath.h"
28 : #include "cppdefault.h"
29 :
30 : /* Microsoft Windows does not natively support inodes.
31 : VMS has non-numeric inodes. */
32 : #ifdef VMS
33 : # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
34 : # define INO_T_COPY(DEST, SRC) memcpy (&(DEST), &(SRC), sizeof (SRC))
35 : #elif !defined (HOST_LACKS_INODE_NUMBERS)
36 : # define INO_T_EQ(A, B) ((A) == (B))
37 : # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
38 : #endif
39 :
40 : #if defined INO_T_EQ
41 : #define DIRS_EQ(A, B) ((A)->dev == (B)->dev \
42 : && INO_T_EQ ((A)->ino, (B)->ino))
43 : #else
44 : #define DIRS_EQ(A, B) (!filename_cmp ((A)->canonical_name, (B)->canonical_name))
45 : #endif
46 :
47 : #ifndef HOST_STAT_FOR_64BIT_INODES
48 : #define HOST_STAT_FOR_64BIT_INODES stat
49 : #endif
50 :
51 : static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
52 :
53 : static void add_env_var_paths (const char *, incpath_kind);
54 : static void add_standard_paths (const char *, const char *, const char *, int);
55 : static void free_path (struct cpp_dir *, int);
56 : static void merge_include_chains (const char *, cpp_reader *, int);
57 : static void add_sysroot_to_chain (const char *, int);
58 : static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
59 : struct cpp_dir *, struct cpp_dir *,
60 : int);
61 :
62 : /* Include chains heads and tails. */
63 : static struct cpp_dir *heads[INC_MAX];
64 : static struct cpp_dir *tails[INC_MAX];
65 :
66 : static bool quote_ignores_source_dir;
67 : enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
68 :
69 : /* Free an element of the include chain, possibly giving a reason. */
70 : static void
71 1303127 : free_path (struct cpp_dir *path, int reason)
72 : {
73 1303127 : switch (reason)
74 : {
75 0 : case REASON_DUP:
76 0 : case REASON_DUP_SYS:
77 0 : fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
78 0 : if (reason == REASON_DUP_SYS)
79 0 : fprintf (stderr,
80 0 : _(" as it is a non-system directory that duplicates a system directory\n"));
81 : break;
82 :
83 662 : case REASON_NOENT:
84 662 : fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
85 : path->name);
86 662 : break;
87 :
88 : case REASON_QUIET:
89 : default:
90 : break;
91 : }
92 :
93 1303127 : free (path->name);
94 1303127 : free (path);
95 1303127 : }
96 :
97 : /* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
98 : append all the names to the search path CHAIN. */
99 : static void
100 418016 : add_env_var_paths (const char *env_var, incpath_kind chain)
101 : {
102 418016 : char *p, *q, *path;
103 :
104 418016 : q = getenv (env_var);
105 :
106 418016 : if (!q)
107 : return;
108 :
109 0 : for (p = q; *q; p = q + 1)
110 : {
111 : q = p;
112 0 : while (*q != 0 && *q != PATH_SEPARATOR)
113 0 : q++;
114 :
115 0 : if (p == q)
116 0 : path = xstrdup (".");
117 : else
118 : {
119 0 : path = XNEWVEC (char, q - p + 1);
120 0 : memcpy (path, p, q - p);
121 0 : path[q - p] = '\0';
122 : }
123 :
124 0 : add_path (path, chain, chain == INC_SYSTEM, false);
125 : }
126 : }
127 :
128 : /* Append the standard include chain defined in cppdefault.cc. */
129 : static void
130 208948 : add_standard_paths (const char *sysroot, const char *iprefix,
131 : const char *imultilib, int cxx_stdinc)
132 : {
133 208948 : const struct default_include *p;
134 208948 : int relocated = cpp_relocated ();
135 208948 : size_t len;
136 :
137 208948 : if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
138 : {
139 : /* Look for directories that start with the standard prefix.
140 : "Translate" them, i.e. replace /usr/local/lib/gcc... with
141 : IPREFIX and search them first. */
142 2679040 : for (p = cpp_include_defaults; p->fname; p++)
143 : {
144 2472960 : if (p->cplusplus == 0
145 824320 : || (cxx_stdinc && (p->cplusplus == flag_stdlib_kind)))
146 : {
147 : /* Should we be translating sysrooted dirs too? Assume
148 : that iprefix and sysroot are mutually exclusive, for
149 : now. */
150 1649378 : if (sysroot && p->add_sysroot)
151 0 : continue;
152 1649378 : if (!filename_ncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
153 : {
154 825058 : char *str = concat (iprefix, p->fname + len, NULL);
155 825058 : if (p->multilib == 1 && imultilib)
156 1 : str = reconcat (str, str, dir_separator_str,
157 : imultilib, NULL);
158 825057 : else if (p->multilib == 2)
159 : {
160 206080 : if (!imultiarch)
161 : {
162 206080 : free (str);
163 206080 : continue;
164 : }
165 0 : str = reconcat (str, str, dir_separator_str,
166 : imultiarch, NULL);
167 : }
168 618978 : add_path (str, INC_SYSTEM, p->cxx_aware, false);
169 : }
170 : }
171 : }
172 : }
173 :
174 2716324 : for (p = cpp_include_defaults; p->fname; p++)
175 : {
176 2507376 : if (p->cplusplus == 0
177 835792 : || (cxx_stdinc && (p->cplusplus == flag_stdlib_kind)))
178 : {
179 1672322 : char *str;
180 :
181 : /* Should this directory start with the sysroot? */
182 1672322 : if (sysroot && p->add_sysroot)
183 : {
184 0 : char *sysroot_no_trailing_dir_separator = xstrdup (sysroot);
185 0 : size_t sysroot_len = strlen (sysroot);
186 :
187 0 : if (sysroot_len > 0 && sysroot[sysroot_len - 1] == DIR_SEPARATOR)
188 0 : sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
189 0 : str = concat (sysroot_no_trailing_dir_separator, p->fname, NULL);
190 0 : free (sysroot_no_trailing_dir_separator);
191 0 : }
192 836530 : else if (!p->add_sysroot && relocated
193 2508852 : && !filename_ncmp (p->fname, cpp_PREFIX, cpp_PREFIX_len))
194 : {
195 836530 : static const char *relocated_prefix;
196 836530 : char *ostr;
197 : /* If this path starts with the configure-time prefix,
198 : but the compiler has been relocated, replace it
199 : with the run-time prefix. The run-time exec prefix
200 : is GCC_EXEC_PREFIX. Compute the path from there back
201 : to the toplevel prefix. */
202 836530 : if (!relocated_prefix)
203 : {
204 782413 : char *dummy;
205 : /* Make relative prefix expects the first argument
206 : to be a program, not a directory. */
207 782413 : dummy = concat (gcc_exec_prefix, "dummy", NULL);
208 782413 : relocated_prefix
209 782413 : = make_relative_prefix (dummy,
210 : cpp_EXEC_PREFIX,
211 : cpp_PREFIX);
212 782413 : free (dummy);
213 : }
214 1673060 : ostr = concat (relocated_prefix,
215 836530 : p->fname + cpp_PREFIX_len,
216 : NULL);
217 836530 : str = update_path (ostr, p->component);
218 836530 : free (ostr);
219 : }
220 : else
221 835792 : str = update_path (p->fname, p->component);
222 :
223 1672322 : if (p->multilib == 1 && imultilib)
224 1 : str = reconcat (str, str, dir_separator_str, imultilib, NULL);
225 1672321 : else if (p->multilib == 2)
226 : {
227 626844 : if (!imultiarch)
228 : {
229 626844 : free (str);
230 626844 : continue;
231 : }
232 0 : str = reconcat (str, str, dir_separator_str, imultiarch, NULL);
233 : }
234 :
235 1045478 : add_path (str, INC_SYSTEM, p->cxx_aware, false);
236 : }
237 : }
238 208948 : }
239 :
240 : /* For each duplicate path in chain HEAD, keep just the first one.
241 : Remove each path in chain HEAD that also exists in chain SYSTEM.
242 : Set the NEXT pointer of the last path in the resulting chain to
243 : JOIN, unless it duplicates JOIN in which case the last path is
244 : removed. Return the head of the resulting chain. Any of HEAD,
245 : JOIN and SYSTEM can be NULL. */
246 :
247 : static struct cpp_dir *
248 836032 : remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
249 : struct cpp_dir *system, struct cpp_dir *join,
250 : int verbose)
251 : {
252 836032 : struct cpp_dir **pcur, *tmp, *cur;
253 836032 : struct HOST_STAT_FOR_64BIT_INODES st;
254 :
255 3531260 : for (pcur = &head; *pcur; )
256 : {
257 2695228 : int reason = REASON_QUIET;
258 :
259 2695228 : cur = *pcur;
260 :
261 2695228 : if (HOST_STAT_FOR_64BIT_INODES (cur->name, &st))
262 : {
263 : /* Dirs that don't exist or have denied permissions are
264 : silently ignored, unless verbose. */
265 1297626 : if ((errno != ENOENT) && (errno != EPERM))
266 0 : cpp_errno (pfile, CPP_DL_ERROR, cur->name);
267 : else
268 : {
269 : /* If -Wmissing-include-dirs is given, warn. */
270 1297626 : cpp_options *opts = cpp_get_options (pfile);
271 1297626 : if (opts->warn_missing_include_dirs && cur->user_supplied_p)
272 9 : cpp_warning (pfile, CPP_W_MISSING_INCLUDE_DIRS, "%s: %s",
273 : cur->name, xstrerror (errno));
274 : reason = REASON_NOENT;
275 : }
276 : }
277 1397602 : else if (!S_ISDIR (st.st_mode))
278 0 : cpp_error_with_line (pfile, CPP_DL_WARNING, 0, 0,
279 : "%s: not a directory", cur->name);
280 : else
281 : {
282 : #if defined (INO_T_COPY)
283 1397602 : INO_T_COPY (cur->ino, st.st_ino);
284 1397602 : cur->dev = st.st_dev;
285 : #endif
286 :
287 : /* Remove this one if it is in the system chain. */
288 1397602 : reason = REASON_DUP_SYS;
289 3646087 : for (tmp = system; tmp; tmp = tmp->next)
290 2248665 : if (DIRS_EQ (tmp, cur) && cur->construct == tmp->construct)
291 : break;
292 :
293 1397602 : if (!tmp)
294 : {
295 : /* Duplicate of something earlier in the same chain? */
296 1397422 : reason = REASON_DUP;
297 3901742 : for (tmp = head; tmp != cur; tmp = tmp->next)
298 2509641 : if (DIRS_EQ (cur, tmp) && cur->construct == tmp->construct)
299 : break;
300 :
301 1397422 : if (tmp == cur
302 : /* Last in the chain and duplicate of JOIN? */
303 1392101 : && !(cur->next == NULL && join
304 109946 : && DIRS_EQ (cur, join)
305 0 : && cur->construct == join->construct))
306 : {
307 : /* Unique, so keep this directory. */
308 1392101 : pcur = &cur->next;
309 1392101 : continue;
310 : }
311 : }
312 : }
313 :
314 : /* Remove this entry from the chain. */
315 1303127 : *pcur = cur->next;
316 1303789 : free_path (cur, verbose ? reason : REASON_QUIET);
317 : }
318 :
319 836032 : *pcur = join;
320 836032 : return head;
321 : }
322 :
323 : /* Add SYSROOT to any user-supplied paths in CHAIN starting with
324 : "=" or "$SYSROOT". */
325 :
326 : static void
327 0 : add_sysroot_to_chain (const char *sysroot, int chain)
328 : {
329 0 : struct cpp_dir *p;
330 :
331 0 : for (p = heads[chain]; p != NULL; p = p->next)
332 : {
333 0 : if (p->user_supplied_p)
334 : {
335 0 : if (p->name[0] == '=')
336 0 : p->name = concat (sysroot, p->name + 1, NULL);
337 0 : if (startswith (p->name, "$SYSROOT"))
338 0 : p->name = concat (sysroot, p->name + strlen ("$SYSROOT"), NULL);
339 : }
340 : }
341 0 : }
342 :
343 : /* Merge the four include chains together in the order quote, bracket,
344 : system, after. Remove duplicate dirs (determined in
345 : system-specific manner).
346 :
347 : We can't just merge the lists and then uniquify them because then
348 : we may lose directories from the <> search path that should be
349 : there; consider -iquote foo -iquote bar -Ifoo -Iquux. It is
350 : however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if
351 : written -iquote bar -Ifoo -Iquux. */
352 :
353 : static void
354 209008 : merge_include_chains (const char *sysroot, cpp_reader *pfile, int verbose)
355 : {
356 : /* Add the sysroot to user-supplied paths starting with "=". */
357 209008 : if (sysroot)
358 : {
359 0 : add_sysroot_to_chain (sysroot, INC_QUOTE);
360 0 : add_sysroot_to_chain (sysroot, INC_BRACKET);
361 0 : add_sysroot_to_chain (sysroot, INC_SYSTEM);
362 0 : add_sysroot_to_chain (sysroot, INC_AFTER);
363 0 : add_sysroot_to_chain (sysroot, INC_EMBED);
364 : }
365 :
366 : /* Join the SYSTEM and AFTER chains. Remove duplicates in the
367 : resulting SYSTEM chain. */
368 209008 : if (heads[INC_SYSTEM])
369 209007 : tails[INC_SYSTEM]->next = heads[INC_AFTER];
370 : else
371 1 : heads[INC_SYSTEM] = heads[INC_AFTER];
372 209008 : heads[INC_SYSTEM]
373 209008 : = remove_duplicates (pfile, heads[INC_SYSTEM], 0, 0, verbose);
374 :
375 : /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
376 : join it to SYSTEM. */
377 209008 : heads[INC_BRACKET]
378 209008 : = remove_duplicates (pfile, heads[INC_BRACKET], heads[INC_SYSTEM],
379 : heads[INC_SYSTEM], verbose);
380 :
381 : /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
382 : join it to BRACKET. */
383 209008 : heads[INC_QUOTE]
384 209008 : = remove_duplicates (pfile, heads[INC_QUOTE], heads[INC_SYSTEM],
385 : heads[INC_BRACKET], verbose);
386 :
387 : /* Remove duplicates from EMBED that are in itself. */
388 209008 : heads[INC_EMBED]
389 209008 : = remove_duplicates (pfile, heads[INC_EMBED], 0, 0, verbose);
390 :
391 : /* If verbose, print the list of dirs to search. */
392 209008 : if (verbose)
393 : {
394 110 : struct cpp_dir *p;
395 :
396 110 : fprintf (stderr, _("#include \"...\" search starts here:\n"));
397 550 : for (p = heads[INC_QUOTE];; p = p->next)
398 : {
399 550 : if (p == heads[INC_BRACKET])
400 110 : fprintf (stderr, _("#include <...> search starts here:\n"));
401 550 : if (!p)
402 : break;
403 440 : fprintf (stderr, " %s\n", p->name);
404 : }
405 110 : fprintf (stderr, _("End of search list.\n"));
406 110 : if (heads[INC_EMBED])
407 : {
408 0 : fprintf (stderr, _("#embed <...> search starts here:\n"));
409 0 : for (p = heads[INC_EMBED]; p; p = p->next)
410 0 : fprintf (stderr, " %s\n", p->name);
411 0 : fprintf (stderr, _("End of #embed search list.\n"));
412 : }
413 : }
414 209008 : }
415 :
416 : /* Use given -I paths for #include "..." but not #include <...>, and
417 : don't search the directory of the present file for #include "...".
418 : (Note that -I. -I- is not the same as the default setup; -I. uses
419 : the compiler's working dir.) */
420 : void
421 0 : split_quote_chain (void)
422 : {
423 0 : if (heads[INC_QUOTE])
424 0 : free_path (heads[INC_QUOTE], REASON_QUIET);
425 0 : if (tails[INC_QUOTE])
426 0 : free_path (tails[INC_QUOTE], REASON_QUIET);
427 0 : heads[INC_QUOTE] = heads[INC_BRACKET];
428 0 : tails[INC_QUOTE] = tails[INC_BRACKET];
429 0 : heads[INC_BRACKET] = NULL;
430 0 : tails[INC_BRACKET] = NULL;
431 : /* This is NOT redundant. */
432 0 : quote_ignores_source_dir = true;
433 0 : }
434 :
435 : /* Add P to the chain specified by CHAIN. */
436 :
437 : void
438 2739750 : add_cpp_dir_path (cpp_dir *p, incpath_kind chain)
439 : {
440 2739750 : if (tails[chain])
441 2387301 : tails[chain]->next = p;
442 : else
443 352449 : heads[chain] = p;
444 2739750 : tails[chain] = p;
445 2739750 : }
446 :
447 : /* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
448 : NUL-terminated. */
449 : void
450 2739750 : add_path (char *path, incpath_kind chain, int cxx_aware, bool user_supplied_p)
451 : {
452 2739750 : cpp_dir *p;
453 2739750 : size_t pathlen = strlen (path);
454 :
455 : #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
456 : /* Remove unnecessary trailing slashes. On some versions of MS
457 : Windows, trailing _forward_ slashes cause no problems for stat().
458 : On newer versions, stat() does not recognize a directory that ends
459 : in a '\\' or '/', unless it is a drive root dir, such as "c:/",
460 : where it is obligatory. */
461 : char* end = path + pathlen - 1;
462 : /* Preserve the lead '/' or lead "c:/". */
463 : char* start = path + (pathlen > 2 && path[1] == ':' ? 3 : 1);
464 :
465 : for (; end > start && IS_DIR_SEPARATOR (*end); end--)
466 : *end = 0;
467 : pathlen = end - path;
468 : #endif
469 :
470 2739750 : p = XNEW (cpp_dir);
471 2739750 : p->next = NULL;
472 2739750 : p->name = path;
473 2739750 : p->len = pathlen;
474 : #ifndef INO_T_EQ
475 : p->canonical_name = lrealpath (path);
476 : #endif
477 2739750 : if (chain == INC_SYSTEM || chain == INC_AFTER)
478 2750829 : p->sysp = 1 + !cxx_aware;
479 : else
480 614373 : p->sysp = 0;
481 2739750 : p->construct = 0;
482 2739750 : p->user_supplied_p = user_supplied_p;
483 :
484 2739750 : add_cpp_dir_path (p, chain);
485 2739750 : }
486 :
487 : /* Exported function to handle include chain merging, duplicate
488 : removal, and registration with cpplib. */
489 : void
490 209008 : register_include_chains (cpp_reader *pfile, const char *sysroot,
491 : const char *iprefix, const char *imultilib,
492 : int stdinc, int cxx_stdinc, int verbose)
493 : {
494 209008 : static const char *const lang_env_vars[] =
495 : { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
496 : "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
497 209008 : cpp_options *cpp_opts = cpp_get_options (pfile);
498 209008 : size_t idx = (cpp_opts->objc ? 2 : 0);
499 :
500 209008 : if (cpp_opts->cplusplus)
501 97313 : idx++;
502 : else
503 : cxx_stdinc = false;
504 :
505 : /* CPATH and language-dependent environment variables may add to the
506 : include chain. */
507 209008 : add_env_var_paths ("CPATH", INC_BRACKET);
508 209008 : add_env_var_paths (lang_env_vars[idx], INC_SYSTEM);
509 :
510 209008 : target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
511 :
512 : /* Finally chain on the standard directories. */
513 209008 : if (stdinc)
514 208948 : add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc);
515 :
516 209008 : target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
517 :
518 209008 : merge_include_chains (sysroot, pfile, verbose);
519 :
520 209008 : cpp_set_include_chains (pfile, heads[INC_QUOTE], heads[INC_BRACKET],
521 209008 : heads[INC_EMBED], quote_ignores_source_dir);
522 209008 : }
523 :
524 : /* Return the current chain of cpp dirs. */
525 :
526 : struct cpp_dir *
527 0 : get_added_cpp_dirs (incpath_kind chain)
528 : {
529 0 : return heads[chain];
530 : }
531 :
532 : #if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES)
533 418016 : static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED,
534 : const char *iprefix ATTRIBUTE_UNUSED,
535 : int stdinc ATTRIBUTE_UNUSED)
536 : {
537 418016 : }
538 : #endif
539 :
540 : #ifndef TARGET_EXTRA_INCLUDES
541 : #define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int
542 : #endif
543 : #ifndef TARGET_EXTRA_PRE_INCLUDES
544 : #define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int
545 : #endif
546 :
547 : struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES };
548 :
|