Make gcc3 the default for non-i386 architectures, leave gcc2 the default
[dragonfly.git] / usr.bin / objformat / objformat.c
1 /*-
2  * Copyright (c) 1998, Peter Wemm <peter@netplex.com.au>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: src/usr.bin/objformat/objformat.c,v 1.6 1998/10/24 02:01:30 jdp Exp $
27  * $DragonFly: src/usr.bin/objformat/objformat.c,v 1.10 2004/01/31 09:14:24 dillon Exp $
28  */
29
30 #include <err.h>
31 #include <objformat.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36
37 /*
38  * System default compiler is still gcc2 for the IA32 architecture,
39  * unless overriden.  For other architectures we have to use gcc3.
40  */
41 #ifndef CCVER_DEFAULT
42 #ifdef __i386__
43 #define CCVER_DEFAULT "gcc2"
44 #else
45 #define CCVER_DEFAULT "gcc3"
46 #endif
47 #endif
48 #ifndef BINUTILSVER_DEFAULT
49 #define BINUTILSVER_DEFAULT "binutils212"
50 #endif
51
52 #define OBJFORMAT       0
53 #define COMPILER        1
54 #define BINUTILS1       2
55 #define BINUTILS2       3
56
57 #define arysize(ary)    (sizeof(ary)/sizeof((ary)[0]))
58
59 struct command {
60         const char *cmd;
61         int type;
62 };
63
64 static struct command commands[] = {
65         {"CC",          COMPILER},
66         {"c++",         COMPILER},
67         {"c++filt",     COMPILER},
68         {"cc",          COMPILER},
69         {"cpp",         COMPILER},
70         {"f77",         COMPILER},
71         {"g++",         COMPILER},
72         {"gcc",         COMPILER},
73         {"gcov",        COMPILER},
74         {"addr2line",   BINUTILS2},
75         {"ar",          BINUTILS2},
76         {"as",          BINUTILS2},
77         {"gasp",        BINUTILS2},
78         {"gdb",         BINUTILS2},
79         {"ld",          BINUTILS2},
80         {"nm",          BINUTILS2},
81         {"objcopy",     BINUTILS2},
82         {"objdump",     BINUTILS2},
83         {"ranlib",      BINUTILS2},
84         {"size",        BINUTILS2},
85         {"strings",     BINUTILS2},
86         {"strip",       BINUTILS2},
87         {"objformat",   OBJFORMAT}
88 };
89
90 int
91 main(int argc, char **argv)
92 {
93         struct command *cmds;
94         char objformat[32];
95         char *path, *chunk;
96         char *cmd, *newcmd = NULL;
97         char *objformat_path;
98         char *ccver;
99         char *buver;
100         const char *env_value = NULL;
101         const char *base_path = NULL;
102         int use_objformat = 0;
103
104         if (getobjformat(objformat, sizeof objformat, &argc, argv) == -1)
105                 errx(1, "Invalid object format");
106
107         /*
108          * Get the last path elemenet of the program name being executed
109          */
110         cmd = strrchr(argv[0], '/');
111         if (cmd != NULL)
112                 cmd++;
113         else
114                 cmd = argv[0];
115
116         for (cmds = commands; cmds < &commands[arysize(commands)]; ++cmds) {
117                 if (strcmp(cmd, cmds->cmd) == 0)
118                         break;
119         }
120
121         if ((ccver = getenv("CCVER")) == NULL)
122                 ccver = CCVER_DEFAULT;
123         if ((buver = getenv("BINUTILSVER")) == NULL) {
124                 buver = BINUTILSVER_DEFAULT;
125                 /*
126                  * XXX auto-select buver based on ccver if buver is
127                  * not otherwise specified
128                  */
129         }
130
131         if (cmds) {
132                 switch (cmds->type) {
133                 case COMPILER:
134                         base_path = "/usr/bin";
135                         use_objformat = 0;
136                         env_value = ccver;
137                         break;
138                 case BINUTILS2:
139                         use_objformat = 1;
140                         /* fall through */
141                 case BINUTILS1:
142                         env_value = buver;
143                         base_path = "/usr/libexec";
144                         break;
145                 case OBJFORMAT:
146                         break;
147                 default:
148                         err(1, "unknown command type");
149                         break;
150                 }
151         }
152
153         /*
154          * The objformat command itself doesn't need another exec
155          */
156         if (cmds->type == OBJFORMAT) {
157                 if (argc != 1) {
158                         fprintf(stderr, "Usage: objformat\n");
159                         exit(1);
160                 }
161
162                 printf("%s\n", objformat);
163                 exit(0);
164         }
165
166         /*
167          * make buildworld glue and CCVER overrides.
168          */
169         objformat_path = getenv("OBJFORMAT_PATH");
170         if (objformat_path == NULL)
171                 objformat_path = "";
172
173         path = strdup(objformat_path);
174
175         setenv("OBJFORMAT", objformat, 1);
176
177         /*
178          * objformat_path could be sequence of colon-separated paths.
179          */
180         while ((chunk = strsep(&path, ":")) != NULL) {
181                 if (newcmd != NULL) {
182                         free(newcmd);
183                         newcmd = NULL;
184                 }
185                 if (use_objformat) {
186                         asprintf(&newcmd, "%s%s/%s/%s/%s",
187                                 chunk, base_path, env_value, objformat, cmd);
188                 } else {
189                         asprintf(&newcmd, "%s%s/%s/%s",
190                                 chunk, base_path, env_value, cmd);
191                 }
192                 if (newcmd == NULL)
193                         err(1, "cannot allocate memory");
194
195                 argv[0] = newcmd;
196                 execv(newcmd, argv);
197         }
198         if (use_objformat) {
199                 err(1, "in path [%s]%s/%s/%s/%s",
200                         objformat_path, base_path, env_value, objformat, cmd);
201         } else {
202                 err(1, "in path [%s]%s/%s/%s",
203                         objformat_path, base_path, env_value, cmd);
204         }
205 }
206