diff options
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 82 |
1 files changed, 70 insertions, 12 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c index 210277130f5..e584319369e 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -1163,6 +1163,11 @@ static const char *multilib_dir; set_multilib_dir based on the compilation options. */ static const char *multilib_os_dir; + +/* Subdirectory to use for locating libraries in multiarch conventions. Set by + set_multilib_dir based on the compilation options. */ + +static const char *multiarch_dir; /* Structure to keep track of the specs that have been defined so far. These are accessed using %(specname) in a compiler or link @@ -2094,6 +2099,7 @@ for_each_path (const struct path_prefix *paths, struct prefix_list *pl; const char *multi_dir = NULL; const char *multi_os_dir = NULL; + const char *multiarch_suffix = NULL; const char *multi_suffix; const char *just_multi_suffix; char *path = NULL; @@ -2111,11 +2117,14 @@ for_each_path (const struct path_prefix *paths, } if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0) multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL); + if (multiarch_dir) + multiarch_suffix = concat (multiarch_dir, dir_separator_str, NULL); while (1) { size_t multi_dir_len = 0; size_t multi_os_dir_len = 0; + size_t multiarch_len = 0; size_t suffix_len; size_t just_suffix_len; size_t len; @@ -2124,16 +2133,15 @@ for_each_path (const struct path_prefix *paths, multi_dir_len = strlen (multi_dir); if (multi_os_dir) multi_os_dir_len = strlen (multi_os_dir); + if (multiarch_suffix) + multiarch_len = strlen (multiarch_suffix); suffix_len = strlen (multi_suffix); just_suffix_len = strlen (just_multi_suffix); if (path == NULL) { len = paths->max_len + extra_space + 1; - if (suffix_len > multi_os_dir_len) - len += suffix_len; - else - len += multi_os_dir_len; + len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len); path = XNEWVEC (char, len); } @@ -2162,6 +2170,16 @@ for_each_path (const struct path_prefix *paths, break; } + /* Now try the multiarch path. */ + if (!skip_multi_dir + && !pl->require_machine_suffix && multiarch_dir) + { + memcpy (path + len, multiarch_suffix, multiarch_len + 1); + ret = callback (path, callback_info); + if (ret) + break; + } + /* Now try the base path. */ if (!pl->require_machine_suffix && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir)) @@ -2990,6 +3008,9 @@ display_help (void) fputs (_(" -print-libgcc-file-name Display the name of the compiler's companion library\n"), stdout); fputs (_(" -print-file-name=<lib> Display the full path to library <lib>\n"), stdout); fputs (_(" -print-prog-name=<prog> Display the full path to compiler component <prog>\n"), stdout); + fputs (_("\ + -print-multiarch Display the target's normalized GNU triplet, used as\n\ + a component in the library path\n"), stdout); fputs (_(" -print-multi-directory Display the root directory for versions of libgcc\n"), stdout); fputs (_("\ -print-multi-lib Display the mapping between command line options and\n\ @@ -3274,6 +3295,7 @@ driver_handle_option (struct gcc_options *opts, case OPT_print_multi_directory: case OPT_print_sysroot: case OPT_print_multi_os_directory: + case OPT_print_multiarch: case OPT_print_sysroot_headers_suffix: case OPT_time: case OPT_wrapper: @@ -4924,6 +4946,15 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) do_spec_1 (" ", 0, NULL); } + if (multiarch_dir) + { + do_spec_1 ("-imultiarch", 1, NULL); + /* Make this a separate argument. */ + do_spec_1 (" ", 0, NULL); + do_spec_1 (multiarch_dir, 1, NULL); + do_spec_1 (" ", 0, NULL); + } + if (gcc_exec_prefix) { do_spec_1 ("-iprefix", 1, NULL); @@ -6593,6 +6624,15 @@ main (int argc, char **argv) return (0); } + if (print_multiarch) + { + if (multiarch_dir == NULL) + printf ("\n"); + else + printf ("%s\n", multiarch_dir); + return (0); + } + if (print_sysroot) { if (target_system_root) @@ -7364,7 +7404,9 @@ default_arg (const char *p, int len) options are present, then we will ignore this completely. Passing that, gcc will consider each multilib_select in turn using the same rules for matching the options. If a match is found, that subdirectory - will be used. */ + will be used. + A subdirectory name is optionally followed by a colon and the corresponding + multiarch name. */ static void set_multilib_dir (void) @@ -7576,10 +7618,25 @@ set_multilib_dir (void) q++; if (q < end) { - char *new_multilib_os_dir = XNEWVEC (char, end - q); - memcpy (new_multilib_os_dir, q + 1, end - q - 1); - new_multilib_os_dir[end - q - 1] = '\0'; - multilib_os_dir = new_multilib_os_dir; + const char *q2 = q + 1, *ml_end = end; + char *new_multilib_os_dir; + + while (q2 < end && *q2 != ':') + q2++; + if (*q2 == ':') + ml_end = q2; + new_multilib_os_dir = XNEWVEC (char, ml_end - q); + memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1); + new_multilib_os_dir[ml_end - q - 1] = '\0'; + multilib_os_dir = *new_multilib_os_dir ? new_multilib_os_dir : "."; + + if (q2 < end && *q2 == ':') + { + char *new_multiarch_dir = XNEWVEC (char, end - q2); + memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1); + new_multiarch_dir[end - q2 - 1] = '\0'; + multiarch_dir = new_multiarch_dir; + } break; } } @@ -7639,9 +7696,10 @@ print_multilib_info (void) } /* When --disable-multilib was used but target defines - MULTILIB_OSDIRNAMES, entries starting with .: are there just - to find multilib_os_dir, so skip them from output. */ - if (this_path[0] == '.' && this_path[1] == ':') + MULTILIB_OSDIRNAMES, entries starting with .: (and not starting + with .:: for multiarch configurations) are there just to find + multilib_os_dir, so skip them from output. */ + if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':') skip = 1; /* Check for matches with the multilib_exclusions. We don't bother |