driver-avr.c revision 1.6
1/* Subroutines for the gcc driver. 2 Copyright (C) 2009-2016 Free Software Foundation, Inc. 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 27// Remove -nodevicelib from the command line if not needed 28#define X_NODEVLIB "%<nodevicelib" 29 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 52 return X_NODEVLIB; 53} 54 55 56/* Implement spec function `device-specs-file��. 57 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. */ 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"); 80 return X_NODEVLIB; 81 82 case 1: 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 96 mmcu = AVR_MMCU_DEFAULT; 97 break; 98 99 default: 100 mmcu = argv[1]; 101 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; 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); 131 return X_NODEVLIB; 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 { 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); 153 } 154 155 return avr_diagnose_devicespecs_error (mmcu, specfile_name); 156} 157