]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/avr/driver-avr.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / avr / driver-avr.c
CommitLineData
4a2caf6c 1/* Subroutines for the gcc driver.
818ab71a 2 Copyright (C) 2009-2016 Free Software Foundation, Inc.
4a2caf6c
GJL
3 Contributed by Georg-Johann Lay <avr@gjlay.de>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "diagnostic.h"
25#include "tm.h"
26
076d86f3
GJL
27// Remove -nodevicelib from the command line if not needed
28#define X_NODEVLIB "%<nodevicelib"
29
4a2caf6c
GJL
30static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
31
32static const char specfiles_doc_url[] =
33 "http://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html";
34
35
36static const char*
37avr_diagnose_devicespecs_error (const char *mcu, const char *filename)
38{
39 error ("cannot access device-specs for %qs expected at %qs",
40 mcu, filename);
41
42 // Inform about natively supported devices and cores.
43
44 if (strncmp (mcu, "avr", strlen ("avr")))
45 avr_inform_devices ();
46
47 avr_inform_core_architectures ();
48
49 inform (input_location, "you can provide your own specs files, "
50 "see <%s> for details", specfiles_doc_url);
51
076d86f3 52 return X_NODEVLIB;
4a2caf6c
GJL
53}
54
55
56/* Implement spec function `device-specs-fileĀ“.
57
ed137300
GJL
58 Compose -specs=<specs-file-name>%s. If everything went well then argv[0]
59 is the inflated (absolute) specs directory and argv[1] is a device or
60 core name as supplied by -mmcu=*. When building GCC the path might
61 be relative. */
4a2caf6c
GJL
62
63const char*
64avr_devicespecs_file (int argc, const char **argv)
65{
66 char *specfile_name;
67 const char *mmcu = NULL;
68
69#ifdef DEBUG_SPECS
70 if (verbose_flag)
71 fnotice (stderr, "Running spec function '%s' with %d args\n\n",
72 __FUNCTION__, argc);
73#endif
74
75 switch (argc)
76 {
77 case 0:
78 fatal_error (input_location,
79 "bad usage of spec function %qs", "device-specs-file");
076d86f3 80 return X_NODEVLIB;
4a2caf6c
GJL
81
82 case 1:
3184f36f
GJL
83 if (0 == strcmp ("device-specs", argv[0]))
84 {
85 /* FIXME: This means "device-specs%s" from avr.h:DRIVER_SELF_SPECS
86 has not been resolved to a path. That case can occur when the
87 c++ testsuite is run from the build directory. DejaGNU's
88 libgloss.exp:get_multilibs runs $compiler without -B, i.e.runs
89 xgcc without specifying a prefix. Without any prefix, there is
90 no means to find out where the specs files might be located.
91 get_multilibs runs xgcc --print-multi-lib, hence we don't actually
92 need information form a specs file and may skip it here. */
93 return X_NODEVLIB;
94 }
95
4a2caf6c
GJL
96 mmcu = AVR_MMCU_DEFAULT;
97 break;
98
ed137300 99 default:
4a2caf6c 100 mmcu = argv[1];
4a2caf6c 101
ed137300
GJL
102 // Allow specifying the same MCU more than once.
103
104 for (int i = 2; i < argc; i++)
105 if (0 != strcmp (mmcu, argv[i]))
106 {
107 error ("specified option %qs more than once", "-mmcu");
108 return X_NODEVLIB;
109 }
110
111 break;
4a2caf6c
GJL
112 }
113
114 specfile_name = concat (argv[0], dir_separator_str, "specs-", mmcu, NULL);
115
116#ifdef DEBUG_SPECS
117 if (verbose_flag)
118 fnotice (stderr, "'%s': mmcu='%s'\n'%s': specfile='%s'\n\n",
119 __FUNCTION__, mmcu, __FUNCTION__, specfile_name);
120#endif
121
122 // Filter out silly -mmcu= arguments like "foo bar".
123
124 for (const char *s = mmcu; *s; s++)
125 if (!ISALNUM (*s)
126 && '-' != *s
127 && '_' != *s)
128 {
129 error ("strange device name %qs after %qs: bad character %qc",
130 mmcu, "-mmcu=", *s);
076d86f3 131 return X_NODEVLIB;
4a2caf6c
GJL
132 }
133
134 if (/* When building / configuring the compiler we might get a relative path
135 as supplied by "-B.". Assume that the specs file exists and MCU is
136 a core, not a proper device then, i.e. we have "-mmcu=avr*". */
137 (0 == strncmp (mmcu, "avr", strlen ("avr"))
138 && specfile_name[0] == '.')
139 /* vanilla */
140 || (IS_ABSOLUTE_PATH (specfile_name)
141 && !access (specfile_name, R_OK)))
142 {
076d86f3
GJL
143 return concat ("-specs=device-specs", dir_separator_str, "specs-", mmcu,
144 // Use '%s' instead of the expanded specfile_name. This
145 // is the easiest way to handle pathes containing spaces.
146 "%s",
147#if defined (WITH_AVRLIBC)
148 " %{mmcu=avr*:" X_NODEVLIB "} %{!mmcu=*:" X_NODEVLIB "}",
149#else
150 " " X_NODEVLIB,
151#endif
152 NULL);
4a2caf6c
GJL
153 }
154
155 return avr_diagnose_devicespecs_error (mmcu, specfile_name);
156}