Mercurial > projects > ddmd
annotate dmd/Util.d @ 22:fd4acc376c45
Implemented object file output and linking on linux.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Thu, 08 Apr 2010 04:21:03 +0100 |
parents | 5c9b78899f5d |
children | cfa3747ebe4c |
rev | line source |
---|---|
0 | 1 module dmd.Util; |
2 | |
3 import dmd.Loc; | |
4 import dmd.Library; | |
5 import dmd.File; | |
6 import dmd.String; | |
7 import dmd.OutBuffer; | |
8 import dmd.FileName; | |
9 import dmd.Global; | |
10 import dmd.PREC; | |
11 import dmd.TOK; | |
12 | |
13 import std.process : getenv; | |
14 import std.c.string; | |
15 import std.stdio : writef, writefln, write; | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
16 version (Windows) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
17 { |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
18 import std.c.process : spawnl, spawnlp; |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
19 } |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
20 version (POSIX) |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
21 { |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
22 import core.sys.posix.unistd; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
23 } |
0 | 24 import core.stdc.stdlib; |
25 import core.stdc.ctype; | |
26 import core.stdc.stdarg; | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
27 public import core.stdc.stdio; |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
28 version (Bug4054) import core.memory; |
0 | 29 |
30 extern(C) int putenv(char*); | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
31 /+version (LOG) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
32 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
33 static if( !is(typeof(printf)) ) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
34 extern (C) int printf(const char*,...); |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
35 }+/ |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
36 //version = LOG; |
0 | 37 |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
38 version (TARGET_OSX) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
39 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
40 version = TARGET_FOS; // FreeBSD, OS X, Solaris |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
41 } |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
42 version (TARGET_FREEBSD) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
43 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
44 version = TARGET_FOS; // FreeBSD, OS X, Solaris |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
45 } |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
46 version (TARGET_SOLARIS) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
47 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
48 version = TARGET_FOS; // FreeBSD, OS X, Solaris |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
49 } |
0 | 50 |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
51 version (POSIX) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
52 { |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
53 import dmd.Array; |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
54 import dmd.Gnuc; |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
55 import core.sys.posix.stdlib; |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
56 version (TARGET_FOS) import core.stdc.limits; |
0 | 57 } |
58 | |
59 enum MAX_PATH = 256; /// | |
60 | |
61 version (Windows) { | |
62 import core.sys.windows.windows : GetModuleFileNameA; | |
63 } | |
64 | |
65 string fromStringz(const(char)* s) | |
66 { | |
67 return s[0..strlen(s)].idup; | |
68 } | |
69 | |
70 void warning(T...)(string format, T t) | |
71 { | |
72 assert(false); | |
73 } | |
74 | |
75 void warning(T...)(Loc loc, string format, T t) | |
76 { | |
77 assert(false); | |
78 } | |
79 | |
80 void error(T...)(Loc loc, string format, T t) | |
81 { | |
82 if (!global.gag) | |
83 { | |
84 string p = loc.toChars(); | |
85 | |
86 if (p.length != 0) | |
87 writef("%s: ", p); | |
88 | |
89 write("Error: "); | |
90 writefln(format, t); | |
91 | |
92 //halt(); | |
93 } | |
94 global.errors++; | |
95 } | |
96 | |
97 char* strupr(char* s) | |
98 { | |
99 char* t = s; | |
100 | |
101 while (*s) | |
102 { | |
103 *s = cast(char)toupper(*s); | |
104 s++; | |
105 } | |
106 | |
107 return t; | |
108 } | |
109 | |
110 char[] skipspace(char[] p) | |
111 { | |
112 foreach (i, c; p) { | |
113 if (!isspace(c)) { | |
114 return p[i..$]; | |
115 } | |
116 } | |
117 | |
118 return null; | |
119 } | |
120 | |
121 char* skipspace(char* p) | |
122 { | |
123 while (isspace(*p)) | |
124 p++; | |
125 | |
126 return p; | |
127 } | |
128 | |
129 void inifile(string argv0, string inifile) | |
130 { | |
131 char *path; // need path for @P macro | |
132 string filename; | |
133 int i; | |
134 int k; | |
135 int envsection = 0; | |
136 | |
137 version (LOG) { | |
138 writef("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); | |
139 } | |
140 if (FileName.absolute(inifile)) { | |
141 filename = inifile; | |
142 } else { | |
143 /* Look for inifile in the following sequence of places: | |
144 * o current directory | |
145 * o home directory | |
146 * o directory off of argv0 | |
147 * o /etc/ | |
148 */ | |
149 if (FileName.exists(inifile)) { | |
150 filename = inifile; | |
151 } else { | |
152 filename = FileName.combine(getenv("HOME"), inifile); | |
153 if (!FileName.exists(filename)) { | |
154 version (_WIN32) { // This fix by Tim Matthews | |
155 char resolved_name_b[MAX_PATH + 1]; | |
156 auto resolved_name = resolved_name_b[].idup; | |
157 if (GetModuleFileNameA(null, resolved_name_b.ptr, MAX_PATH + 1) && FileName.exists(resolved_name)) | |
158 { | |
159 filename = FileName.replaceName(resolved_name, inifile); | |
160 if (FileName.exists(filename)) { | |
161 goto Ldone; | |
162 } | |
163 } | |
164 } | |
165 filename = FileName.replaceName(argv0, inifile); | |
166 if (!FileName.exists(filename)) { | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
167 version (POSIX) { /// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
168 version (POSIX) { /// __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne |
0 | 169 /* argv0 might be a symbolic link, |
170 * so try again looking past it to the real path | |
171 */ | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
172 version (TARGET_FOS) {/// #if __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
0 | 173 char resolved_name[PATH_MAX + 1]; |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
174 char* real_argv0 = realpath(toStringz(argv0), resolved_name); |
0 | 175 } else { |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
176 char* real_argv0 = realpath(toStringz(argv0), null); |
0 | 177 } |
178 //printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0); | |
179 if (real_argv0) { | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
180 filename = FileName.replaceName(fromStringz(real_argv0), inifile); |
0 | 181 version (linux) { |
2 | 182 ///free(real_argv0); |
0 | 183 } |
184 if (FileName.exists(filename)) { | |
185 goto Ldone; | |
186 } | |
187 } | |
188 } else { | |
189 static assert (false, "use of glibc non-standard extension realpath(char*, null)"); | |
190 } | |
191 if (true) { | |
192 // Search PATH for argv0 | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
193 const(char)* p = toStringz(getenv("PATH")); |
0 | 194 version (LOG) { |
195 writef("\tPATH='%s'\n", p); | |
196 } | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
197 auto paths = FileName.splitPath(fromStringz(p)); |
0 | 198 filename = FileName.searchPath(paths, argv0, 0); |
199 if (!filename) { | |
200 goto Letc; // argv0 not found on path | |
201 } | |
202 | |
203 filename = FileName.replaceName(filename, inifile); | |
204 if (FileName.exists(filename)) { | |
205 goto Ldone; | |
206 } | |
207 } | |
208 } | |
209 // Search /etc/ for inifile | |
210 Letc: | |
211 filename = FileName.combine("/etc/", inifile); | |
212 | |
213 Ldone: | |
214 ; | |
215 } | |
216 } | |
217 } | |
218 } | |
219 | |
220 path = cast(char*)toStringz(FileName.path(filename)); | |
221 | |
222 version (LOG) { | |
223 writef("\tpath = '%s', filename = '%s'\n", fromStringz(path), filename); | |
224 } | |
225 | |
226 scope File file = new File(filename); | |
227 | |
228 if (file.read()) { | |
229 return; // error reading file | |
230 } | |
231 | |
232 scope OutBuffer buf = new OutBuffer(); | |
233 | |
234 // Parse into lines | |
235 int eof = 0; | |
236 for (i = 0; i < file.len && !eof; i++) | |
237 { | |
238 int linestart = i; | |
239 | |
240 for (; i < file.len; i++) | |
241 { | |
242 switch (file.buffer[i]) | |
243 { | |
244 case '\r': | |
245 break; | |
246 | |
247 case '\n': | |
248 // Skip if it was preceded by '\r' | |
249 if (i && file.buffer[i - 1] == '\r') | |
250 goto Lskip; | |
251 break; | |
252 | |
253 case 0: | |
254 case 0x1A: | |
255 eof = 1; | |
256 break; | |
257 | |
258 default: | |
259 continue; | |
260 } | |
261 break; | |
262 } | |
263 | |
264 // The line is file.buffer[linestart..i] | |
265 char *line; | |
266 int len; | |
267 char *p; | |
268 char* pn; | |
269 | |
270 line = cast(char*)&file.buffer[linestart]; | |
271 len = i - linestart; | |
272 | |
273 buf.reset(); | |
274 | |
275 // First, expand the macros. | |
276 // Macros are bracketed by % characters. | |
277 | |
278 for (k = 0; k < len; k++) | |
279 { | |
280 if (line[k] == '%') | |
281 { | |
282 int j; | |
283 | |
284 for (j = k + 1; j < len; j++) | |
285 { | |
286 if (line[j] == '%') | |
287 { | |
288 if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) | |
289 { | |
290 // %@P% is special meaning the path to the .ini file | |
291 p = path; | |
292 if (!*p) | |
293 p = cast(char*)"."; | |
294 } | |
295 else | |
296 { | |
297 int l = j - k; | |
298 char tmp[10]; // big enough most of the time | |
299 | |
300 if (l <= tmp.sizeof) | |
301 p = tmp.ptr; | |
302 else | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
303 { |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
304 version (Bug4054) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
305 p = cast(char*)GC.malloc(l); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
306 else |
0 | 307 p = cast(char*)alloca(l); |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
308 } |
0 | 309 l--; |
310 memcpy(p, &line[k + 1], l); | |
311 p[l] = 0; | |
312 strupr(p); | |
313 p = core.stdc.stdlib.getenv(p); | |
314 if (!p) | |
315 p = cast(char*)""; | |
316 } | |
317 buf.writestring(p[0..strlen(p)]); /// | |
318 k = j; | |
319 goto L1; | |
320 } | |
321 } | |
322 } | |
323 buf.writeByte(line[k]); | |
324 L1: | |
325 ; | |
326 } | |
327 | |
328 // Remove trailing spaces | |
329 while (buf.offset && isspace(buf.data[buf.offset - 1])) | |
330 buf.offset--; | |
331 | |
332 char[] pp = buf.getString(); | |
333 | |
334 // The expanded line is in p. | |
335 // Now parse it for meaning. | |
336 | |
337 pp = skipspace(pp); | |
338 if (pp.length != 0) { | |
339 switch (pp[0]) | |
340 { | |
341 case ';': // comment | |
342 break; | |
343 | |
344 case '[': // look for [Environment] | |
345 pp = skipspace(pp[1..$]); | |
346 for (pn = pp.ptr; isalnum(*pn); pn++) { | |
347 ; | |
348 } | |
349 | |
350 if (pn - pp.ptr == 11 && | |
351 memicmp(pp.ptr, "Environment", 11) == 0 && | |
352 *skipspace(pn) == ']' | |
353 ) | |
354 envsection = 1; | |
355 else | |
356 envsection = 0; | |
357 break; | |
358 | |
359 default: | |
360 if (envsection) | |
361 { | |
362 pn = pp.ptr; | |
363 | |
364 // Convert name to upper case; | |
365 // remove spaces bracketing = | |
366 auto p2 = pn; | |
367 for ( ; *p2; p2++) | |
368 { if (islower(*p2)) | |
369 *p2 &= ~0x20; | |
370 else if (isspace(*p)) | |
371 memmove(p2, p2 + 1, strlen(p2)); | |
372 else if (*p2 == '=') | |
373 { | |
374 p2++; | |
375 while (isspace(*p2)) | |
376 memmove(p2, p2 + 1, strlen(p2)); | |
377 break; | |
378 } | |
379 } | |
380 | |
381 //putenv(pn); | |
382 putenv(cast(char*)toStringz(pp)); | |
383 | |
384 version (LOG) { | |
385 writef("\tputenv('%s')\n", pn[0..strlen(pn)]); | |
386 //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); | |
387 } | |
388 } | |
389 break; | |
390 } | |
391 } | |
392 | |
393 Lskip: | |
394 ; | |
395 } | |
396 } | |
397 | |
398 ///int response_expand(int *pargc, char ***pargv); | |
399 void browse(const(char)* url) | |
400 { | |
401 assert(false); | |
402 } | |
403 | |
404 string[] getenv_setargv(string envvar, string[] args) | |
405 { | |
406 char *p; | |
407 | |
408 string[] argv = args.dup; | |
409 int argc = args.length; | |
410 | |
411 int wildcard; // do wildcard expansion | |
412 int instring; | |
413 int slash; | |
414 char c; | |
415 int j; | |
416 | |
417 string ienv = getenv(envvar); | |
418 if (ienv is null) | |
419 return args; | |
420 | |
421 char[] env = ienv.dup; // create our own writable copy | |
422 | |
423 j = 1; // leave argv[0] alone | |
424 char* e = env.ptr; | |
425 while (1) | |
426 { | |
427 wildcard = 1; | |
428 switch (*e) | |
429 { | |
430 case ' ': | |
431 case '\t': | |
432 e++; | |
433 break; | |
434 | |
435 case 0: | |
436 goto Ldone; | |
437 | |
438 case '"': | |
439 wildcard = 0; | |
440 default: | |
441 argv ~= assumeUnique(e[0..strlen(e)]); // append | |
442 //argv.insert(j, env); // insert at position j | |
443 j++; | |
444 argc++; | |
445 p = e; | |
446 slash = 0; | |
447 instring = 0; | |
448 c = 0; | |
449 | |
450 char* ecopy = e; | |
451 | |
452 while (1) | |
453 { | |
454 c = *e++; | |
455 switch (c) | |
456 { | |
457 case '"': | |
458 p -= (slash >> 1); | |
459 if (slash & 1) | |
460 { | |
461 p--; | |
462 goto Laddc; | |
463 } | |
464 instring ^= 1; | |
465 slash = 0; | |
466 continue; | |
467 | |
468 case '\\': | |
469 slash++; | |
470 *p++ = c; | |
471 continue; | |
472 | |
473 case ' ': | |
474 case '\t': | |
475 if (instring) | |
476 goto Laddc; | |
477 case 0: | |
478 *p = 0; | |
479 if (argv.length != 0) { | |
480 argv[$-1].length = p - argv[$-1].ptr; | |
481 } | |
482 //if (wildcard) | |
483 //wildcardexpand(); // not implemented | |
484 if (c == 0) goto Ldone; | |
485 break; | |
486 | |
487 default: | |
488 Laddc: | |
489 slash = 0; | |
490 *p++ = c; | |
491 continue; | |
492 } | |
493 break; | |
494 } | |
495 } | |
496 } | |
497 | |
498 Ldone: | |
499 return argv; | |
500 } | |
501 | |
502 void error(T...)(string format, T t) | |
503 { | |
504 writefln(format, t); | |
505 exit(EXIT_FAILURE); | |
506 } | |
507 | |
508 void usage() | |
509 { | |
510 writef("Digital Mars D Compiler %s\n%s %s\n", global.version_, global.copyright, global.written); | |
511 writef( | |
512 "Documentation: http://www.digitalmars.com/d/2.0/index.html\n" | |
513 "Usage:\n" | |
514 " dmd files.d ... { -switch }\n" | |
515 "\n" | |
516 " files.d D source files\n" | |
517 " @cmdfile read arguments from cmdfile\n" | |
518 " -c do not link\n" | |
519 " -cov do code coverage analysis\n" | |
520 " -D generate documentation\n" | |
521 " -Dddocdir write documentation file to docdir directory\n" | |
522 " -Dffilename write documentation file to filename\n" | |
523 " -d allow deprecated features\n" | |
524 " -debug compile in debug code\n" | |
525 " -debug=level compile in debug code <= level\n" | |
526 " -debug=ident compile in debug code identified by ident\n" | |
527 " -debuglib=name set symbolic debug library to name\n" | |
528 " -defaultlib=name set default library to name\n" | |
529 " -deps=filename write module dependencies to filename\n" | |
530 " -g add symbolic debug info\n" | |
531 " -gc add symbolic debug info, pretend to be C\n" | |
532 " -H generate 'header' file\n" | |
533 " -Hdhdrdir write 'header' file to hdrdir directory\n" | |
534 " -Hffilename write 'header' file to filename\n" | |
535 " --help print help\n" | |
536 " -Ipath where to look for imports\n" | |
537 " -ignore ignore unsupported pragmas\n" | |
538 " -inline do function inlining\n" | |
539 " -Jpath where to look for string imports\n" | |
540 " -Llinkerflag pass linkerflag to link\n" | |
541 " -lib generate library rather than object files\n" | |
542 " -man open web browser on manual page\n" | |
543 " -nofloat do not emit reference to floating point\n" | |
544 " -O optimize\n" | |
545 " -o- do not write object file\n" | |
546 " -odobjdir write object & library files to directory objdir\n" | |
547 " -offilename name output file to filename\n" | |
548 " -op do not strip paths from source file\n" | |
549 " -profile profile runtime performance of generated code\n" | |
550 " -quiet suppress unnecessary messages\n" | |
551 " -release compile release version\n" | |
552 " -run srcfile args... run resulting program, passing args\n" | |
553 " -safe safe memory model\n" | |
554 " -unittest compile in unit tests\n" | |
555 " -v verbose\n" | |
556 " -version=level compile in version code >= level\n" | |
557 " -version=ident compile in version code identified by ident\n" | |
558 " -vtls list all variables going into thread local storage\n" | |
559 " -w enable warnings\n" | |
560 ); | |
561 } | |
562 | |
563 void fatal() | |
564 { | |
565 static if (false) { | |
566 halt(); | |
567 } else { | |
568 exit(EXIT_FAILURE); | |
569 } | |
570 } | |
571 | |
572 void halt() | |
573 { | |
574 assert(false); | |
575 } | |
576 | |
577 void initPrecedence() | |
578 { | |
579 precedence[TOK.TOKdotvar] = PREC.PREC_primary; | |
580 precedence[TOK.TOKimport] = PREC.PREC_primary; | |
581 precedence[TOK.TOKidentifier] = PREC.PREC_primary; | |
582 precedence[TOK.TOKthis] = PREC.PREC_primary; | |
583 precedence[TOK.TOKsuper] = PREC.PREC_primary; | |
584 precedence[TOK.TOKint64] = PREC.PREC_primary; | |
585 precedence[TOK.TOKfloat64] = PREC.PREC_primary; | |
586 precedence[TOK.TOKnull] = PREC.PREC_primary; | |
587 precedence[TOK.TOKstring] = PREC.PREC_primary; | |
588 precedence[TOK.TOKarrayliteral] = PREC.PREC_primary; | |
589 precedence[TOK.TOKtypeid] = PREC.PREC_primary; | |
590 precedence[TOK.TOKis] = PREC.PREC_primary; | |
591 precedence[TOK.TOKassert] = PREC.PREC_primary; | |
592 precedence[TOK.TOKfunction] = PREC.PREC_primary; | |
593 precedence[TOK.TOKvar] = PREC.PREC_primary; | |
594 version (DMDV2) { | |
595 precedence[TOK.TOKdefault] = PREC.PREC_primary; | |
596 } | |
597 | |
598 // post | |
599 precedence[TOK.TOKdotti] = PREC.PREC_primary; | |
600 precedence[TOK.TOKdot] = PREC.PREC_primary; | |
601 // precedence[TOK.TOKarrow] = PREC.PREC_primary; | |
602 precedence[TOK.TOKplusplus] = PREC.PREC_primary; | |
603 precedence[TOK.TOKminusminus] = PREC.PREC_primary; | |
604 precedence[TOK.TOKcall] = PREC.PREC_primary; | |
605 precedence[TOK.TOKslice] = PREC.PREC_primary; | |
606 precedence[TOK.TOKarray] = PREC.PREC_primary; | |
607 | |
608 precedence[TOK.TOKaddress] = PREC.PREC_unary; | |
609 precedence[TOK.TOKstar] = PREC.PREC_unary; | |
610 precedence[TOK.TOKneg] = PREC.PREC_unary; | |
611 precedence[TOK.TOKuadd] = PREC.PREC_unary; | |
612 precedence[TOK.TOKnot] = PREC.PREC_unary; | |
613 precedence[TOK.TOKtobool] = PREC.PREC_add; | |
614 precedence[TOK.TOKtilde] = PREC.PREC_unary; | |
615 precedence[TOK.TOKdelete] = PREC.PREC_unary; | |
616 precedence[TOK.TOKnew] = PREC.PREC_unary; | |
617 precedence[TOK.TOKcast] = PREC.PREC_unary; | |
618 | |
619 precedence[TOK.TOKmul] = PREC.PREC_mul; | |
620 precedence[TOK.TOKdiv] = PREC.PREC_mul; | |
621 precedence[TOK.TOKmod] = PREC.PREC_mul; | |
622 | |
623 precedence[TOK.TOKadd] = PREC.PREC_add; | |
624 precedence[TOK.TOKmin] = PREC.PREC_add; | |
625 precedence[TOK.TOKcat] = PREC.PREC_add; | |
626 | |
627 precedence[TOK.TOKshl] = PREC.PREC_shift; | |
628 precedence[TOK.TOKshr] = PREC.PREC_shift; | |
629 precedence[TOK.TOKushr] = PREC.PREC_shift; | |
630 | |
631 precedence[TOK.TOKlt] = PREC.PREC_rel; | |
632 precedence[TOK.TOKle] = PREC.PREC_rel; | |
633 precedence[TOK.TOKgt] = PREC.PREC_rel; | |
634 precedence[TOK.TOKge] = PREC.PREC_rel; | |
635 precedence[TOK.TOKunord] = PREC.PREC_rel; | |
636 precedence[TOK.TOKlg] = PREC.PREC_rel; | |
637 precedence[TOK.TOKleg] = PREC.PREC_rel; | |
638 precedence[TOK.TOKule] = PREC.PREC_rel; | |
639 precedence[TOK.TOKul] = PREC.PREC_rel; | |
640 precedence[TOK.TOKuge] = PREC.PREC_rel; | |
641 precedence[TOK.TOKug] = PREC.PREC_rel; | |
642 precedence[TOK.TOKue] = PREC.PREC_rel; | |
643 precedence[TOK.TOKin] = PREC.PREC_rel; | |
644 | |
645 static if (false) { | |
646 precedence[TOK.TOKequal] = PREC.PREC_equal; | |
647 precedence[TOK.TOKnotequal] = PREC.PREC_equal; | |
648 precedence[TOK.TOKidentity] = PREC.PREC_equal; | |
649 precedence[TOK.TOKnotidentity] = PREC.PREC_equal; | |
650 } else { | |
651 /* Note that we changed precedence, so that < and != have the same | |
652 * precedence. This change is in the parser, too. | |
653 */ | |
654 precedence[TOK.TOKequal] = PREC.PREC_rel; | |
655 precedence[TOK.TOKnotequal] = PREC.PREC_rel; | |
656 precedence[TOK.TOKidentity] = PREC.PREC_rel; | |
657 precedence[TOK.TOKnotidentity] = PREC.PREC_rel; | |
658 } | |
659 | |
660 precedence[TOK.TOKand] = PREC.PREC_and; | |
661 | |
662 precedence[TOK.TOKxor] = PREC.PREC_xor; | |
663 | |
664 precedence[TOK.TOKor] = PREC.PREC_or; | |
665 | |
666 precedence[TOK.TOKandand] = PREC.PREC_andand; | |
667 | |
668 precedence[TOK.TOKoror] = PREC.PREC_oror; | |
669 | |
670 precedence[TOK.TOKquestion] = PREC.PREC_cond; | |
671 | |
672 precedence[TOK.TOKassign] = PREC.PREC_assign; | |
673 precedence[TOK.TOKconstruct] = PREC.PREC_assign; | |
674 precedence[TOK.TOKblit] = PREC.PREC_assign; | |
675 precedence[TOK.TOKaddass] = PREC.PREC_assign; | |
676 precedence[TOK.TOKminass] = PREC.PREC_assign; | |
677 precedence[TOK.TOKcatass] = PREC.PREC_assign; | |
678 precedence[TOK.TOKmulass] = PREC.PREC_assign; | |
679 precedence[TOK.TOKdivass] = PREC.PREC_assign; | |
680 precedence[TOK.TOKmodass] = PREC.PREC_assign; | |
681 precedence[TOK.TOKshlass] = PREC.PREC_assign; | |
682 precedence[TOK.TOKshrass] = PREC.PREC_assign; | |
683 precedence[TOK.TOKushrass] = PREC.PREC_assign; | |
684 precedence[TOK.TOKandass] = PREC.PREC_assign; | |
685 precedence[TOK.TOKorass] = PREC.PREC_assign; | |
686 precedence[TOK.TOKxorass] = PREC.PREC_assign; | |
687 | |
688 precedence[TOK.TOKcomma] = PREC.PREC_expr; | |
689 } | |
690 | |
691 int runLINK() | |
692 { | |
693 version (_WIN32) { | |
694 string p; | |
695 int i; | |
696 int status; | |
697 scope OutBuffer cmdbuf = new OutBuffer(); | |
698 | |
699 global.params.libfiles.push(cast(void*)new String("user32")); | |
700 global.params.libfiles.push(cast(void*)new String("kernel32")); | |
701 | |
702 for (i = 0; i < global.params.objfiles.dim; i++) | |
703 { | |
704 if (i) | |
705 cmdbuf.writeByte('+'); | |
706 p = (cast(String)global.params.objfiles.data[i]).str; | |
707 string ext = FileName.ext(p); | |
708 if (ext) | |
709 // Write name sans extension | |
710 writeFilename(cmdbuf, p[0..p.length - ext.length - 1]); | |
711 else | |
712 writeFilename(cmdbuf, p); | |
713 } | |
714 cmdbuf.writeByte(','); | |
715 if (global.params.exefile) | |
716 writeFilename(cmdbuf, global.params.exefile); | |
717 else | |
718 { | |
719 /* Generate exe file name from first obj name. | |
720 * No need to add it to cmdbuf because the linker will default to it. | |
721 */ | |
722 string n = (cast(String)global.params.objfiles.data[0]).str; | |
723 n = FileName.name(n); | |
724 FileName fn = FileName.forceExt(n, "exe"); | |
725 global.params.exefile = fn.toChars(); | |
726 } | |
727 | |
728 // Make sure path to exe file exists | |
729 { | |
730 string pp = FileName.path(global.params.exefile); | |
731 FileName.ensurePathExists(pp); | |
732 } | |
733 | |
734 cmdbuf.writeByte(','); | |
735 if (global.params.run) | |
736 cmdbuf.writestring("nul"); | |
737 | |
738 // if (mapfile) | |
739 // cmdbuf.writestring(output); | |
740 cmdbuf.writeByte(','); | |
741 | |
742 for (i = 0; i < global.params.libfiles.dim; i++) | |
743 { | |
744 if (i) | |
745 cmdbuf.writeByte('+'); | |
746 writeFilename(cmdbuf, (cast(String)global.params.libfiles.data[i]).str); | |
747 } | |
748 | |
749 if (global.params.deffile) | |
750 { | |
751 cmdbuf.writeByte(','); | |
752 writeFilename(cmdbuf, global.params.deffile); | |
753 } | |
754 | |
755 /* Eliminate unnecessary trailing commas */ | |
756 while (1) | |
757 { | |
758 i = cmdbuf.offset; | |
759 if (!i || cmdbuf.data[i - 1] != ',') | |
760 break; | |
761 cmdbuf.offset--; | |
762 } | |
763 | |
764 if (global.params.resfile) | |
765 { | |
766 cmdbuf.writestring("/RC:"); | |
767 writeFilename(cmdbuf, global.params.resfile); | |
768 } | |
769 | |
770 static if (false) { | |
771 if (mapfile) | |
772 cmdbuf.writestring("/m"); | |
773 if (debuginfo) | |
774 cmdbuf.writestring("/li"); | |
775 if (codeview) | |
776 { | |
777 cmdbuf.writestring("/co"); | |
778 if (codeview3) | |
779 cmdbuf.writestring(":3"); | |
780 } | |
781 } else { | |
782 if (global.params.symdebug) | |
783 cmdbuf.writestring("/co"); | |
784 } | |
785 | |
786 cmdbuf.writestring("/noi"); | |
787 for (i = 0; i < global.params.linkswitches.dim; i++) | |
788 { | |
789 cmdbuf.writestring((cast(String)global.params.linkswitches.data[i]).str); | |
790 } | |
791 cmdbuf.writeByte(';'); | |
792 | |
793 p = cmdbuf.toChars(); | |
794 | |
795 FileName lnkfilename = null; | |
796 size_t plen = p.length; | |
797 if (plen > 7000) | |
798 { | |
799 lnkfilename = FileName.forceExt(global.params.exefile, "lnk"); | |
800 scope File flnk = new File(lnkfilename); | |
801 flnk.setbuffer(cast(void*)p.ptr, plen); | |
802 flnk.ref_ = 1; | |
803 if (flnk.write()) | |
804 error("error writing file %s", lnkfilename); | |
805 if (lnkfilename.len() < plen) | |
806 p = std.string.format("@%s", lnkfilename.toChars()); | |
807 } | |
808 | |
809 string linkcmd = getenv("LINKCMD"); | |
810 if (!linkcmd) | |
811 linkcmd = "link"; | |
812 | |
813 status = executecmd(linkcmd, p, 1); | |
814 if (lnkfilename) | |
815 { | |
816 remove(toStringz(lnkfilename.toChars())); | |
817 ///delete lnkfilename; | |
818 } | |
819 return status; | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
820 } else version (POSIX) {/// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
0 | 821 pid_t childpid; |
822 int i; | |
823 int status; | |
824 | |
825 // Build argv[] | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
826 Array argv = new Array(); |
0 | 827 |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
828 const(char)* cc = core.stdc.stdlib.getenv("CC"); |
0 | 829 if (!cc) |
830 cc = "gcc"; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
831 argv.push(cast(void *)cc); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
832 Array objfiles = new Array; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
833 for( i = 0; i < global.params.objfiles.dim; i++ ) |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
834 { string str = (cast(String)global.params.objfiles.data[i]).str; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
835 objfiles.push(cast(void*)toStringz(str)); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
836 } |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
837 argv.insert(1, objfiles); |
0 | 838 |
839 // None of that a.out stuff. Use explicit exe file name, or | |
840 // generate one from name of first source file. | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
841 argv.push(cast(void *)cast(char*)"-o"); |
0 | 842 if (global.params.exefile) |
843 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
844 argv.push(cast(void*)toStringz(global.params.exefile)); |
0 | 845 } |
846 else | |
847 { // Generate exe file name from first obj name | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
848 string n = (cast(String)global.params.objfiles.data[0]).str; |
0 | 849 n = FileName.name(n); |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
850 string e = FileName.ext(n); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
851 string ex = e ? n[0..$-(e.length+1)] : "a.out"; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
852 |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
853 argv.push(cast(void*)toStringz(ex)); |
0 | 854 global.params.exefile = ex; |
855 } | |
856 | |
857 // Make sure path to exe file exists | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
858 { string p = FileName.path(global.params.exefile); |
0 | 859 FileName.ensurePathExists(p); |
860 } | |
861 | |
862 if (global.params.symdebug) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
863 argv.push(cast(void *)cast(char*)"-g"); |
0 | 864 |
865 if (global.params.isX86_64) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
866 argv.push(cast(void *)cast(char*)"-m64"); |
0 | 867 else |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
868 argv.push(cast(void *)cast(char*)"-m32"); |
0 | 869 |
870 if (0 && global.params.exefile) | |
871 { | |
872 /* This switch enables what is known as 'smart linking' | |
873 * in the Windows world, where unreferenced sections | |
874 * are removed from the executable. It eliminates unreferenced | |
875 * functions, essentially making a 'library' out of a module. | |
876 * Although it is documented to work with ld version 2.13, | |
877 * in practice it does not, but just seems to be ignored. | |
878 * Thomas Kuehne has verified that it works with ld 2.16.1. | |
879 * BUG: disabled because it causes exception handling to fail | |
880 */ | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
881 argv.push(cast(void *)cast(char*)"-Xlinker"); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
882 argv.push(cast(void *)cast(char*)"--gc-sections"); |
0 | 883 } |
884 | |
885 for (i = 0; i < global.params.linkswitches.dim; i++) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
886 { char *p = cast(char *)global.params.linkswitches.data[i]; |
0 | 887 if (!p || !p[0] || !(p[0] == '-' && p[1] == 'l')) |
888 // Don't need -Xlinker if switch starts with -l | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
889 argv.push(cast(void *)cast(char*)"-Xlinker"); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
890 argv.push(cast(void *) p); |
0 | 891 } |
892 | |
893 /* Add each library, prefixing it with "-l". | |
894 * The order of libraries passed is: | |
895 * 1. any libraries passed with -L command line switch | |
896 * 2. libraries specified on the command line | |
897 * 3. libraries specified by pragma(lib), which were appended | |
898 * to global.params.libfiles. | |
899 * 4. standard libraries. | |
900 */ | |
901 for (i = 0; i < global.params.libfiles.dim; i++) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
902 { char *p = cast(char *)global.params.libfiles.data[i]; |
0 | 903 size_t plen = strlen(p); |
904 if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a') | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
905 argv.push(cast(void *)p); |
0 | 906 else |
907 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
908 char *s = cast(char *)malloc(plen + 3); |
0 | 909 s[0] = '-'; |
910 s[1] = 'l'; | |
911 memcpy(s + 2, p, plen + 1); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
912 argv.push(cast(void *)s); |
0 | 913 } |
914 } | |
915 | |
916 /* Standard libraries must go after user specified libraries | |
917 * passed with -l. | |
918 */ | |
919 const char *libname = (global.params.symdebug) | |
920 ? global.params.debuglibname | |
921 : global.params.defaultlibname; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
922 char *buf = cast(char *)malloc(2 + strlen(libname) + 1); |
0 | 923 strcpy(buf, "-l"); |
924 strcpy(buf + 2, libname); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
925 argv.push(cast(void *)buf); // turns into /usr/lib/libphobos2.a |
0 | 926 |
927 // argv.push((void *)"-ldruntime"); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
928 argv.push(cast(void *)cast(char*)"-lpthread"); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
929 argv.push(cast(void *)cast(char*)"-lm"); |
0 | 930 |
931 if (!global.params.quiet || global.params.verbose) | |
932 { | |
933 // Print it | |
934 for (i = 0; i < argv.dim; i++) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
935 printf("%s ", cast(char *)argv.data[i]); |
0 | 936 printf("\n"); |
937 fflush(stdout); | |
938 } | |
939 | |
940 argv.push(null); | |
941 childpid = fork(); | |
942 if (childpid == 0) | |
943 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
944 execvp(cast(char *)argv.data[0], cast(char **)argv.data); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
945 perror(cast(char *)argv.data[0]); // failed to execute |
0 | 946 return -1; |
947 } | |
948 | |
949 waitpid(childpid, &status, 0); | |
950 | |
951 status=WEXITSTATUS(status); | |
952 if (status) | |
953 printf("--- errorlevel %d\n", status); | |
954 return status; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
955 |
0 | 956 } else { |
957 writef ("Linking is not yet supported for this version of DMD.\n"); | |
958 return -1; | |
959 } | |
960 } | |
961 | |
962 int runProgram() | |
963 { | |
964 assert(false); | |
965 } | |
966 | |
967 void deleteExeFile() | |
968 { | |
969 assert(false); | |
970 } | |
971 | |
972 /**************************************** | |
973 * Write filename to cmdbuf, quoting if necessary. | |
974 */ | |
975 | |
976 void writeFilename(OutBuffer buf, string filename) | |
977 { | |
978 auto len = filename.length; | |
979 /* Loop and see if we need to quote | |
980 */ | |
981 for (size_t i = 0; i < len; i++) | |
982 { | |
983 char c = filename[i]; | |
984 | |
985 if (isalnum(c) || c == '_') | |
986 continue; | |
987 | |
988 /* Need to quote | |
989 */ | |
990 buf.writeByte('"'); | |
991 buf.writestring(filename); | |
992 buf.writeByte('"'); | |
993 return; | |
994 } | |
995 | |
996 /* No quoting necessary | |
997 */ | |
998 buf.writestring(filename); | |
999 } | |
1000 | |
1001 /****************************** | |
1002 * Execute a rule. Return the status. | |
1003 * cmd program to run | |
1004 * args arguments to cmd, as a string | |
1005 * useenv if cmd knows about _CMDLINE environment variable | |
1006 */ | |
1007 | |
1008 version (_WIN32) { | |
1009 int executecmd(string cmd, string args, int useenv) | |
1010 { | |
1011 int status; | |
1012 size_t len = args.length; | |
1013 | |
1014 if (!global.params.quiet || global.params.verbose) | |
1015 { | |
1016 printf("%s %s\n", cmd, args); | |
1017 fflush(stdout); | |
1018 } | |
1019 | |
1020 if (len > 255) | |
1021 { | |
1022 char* q; | |
1023 static char[9] envname = "@_CMDLINE"; | |
1024 | |
1025 envname[0] = '@'; | |
1026 switch (useenv) | |
1027 { | |
1028 case 0: goto L1; | |
1029 case 2: envname[0] = '%'; break; | |
1030 default: break; /// | |
1031 } | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
1032 version (Bug4054) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
1033 q = cast(char*) GC.malloc(envname.sizeof + len + 1); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
1034 else |
0 | 1035 q = cast(char*) alloca(envname.sizeof + len + 1); |
1036 sprintf(q, "%s=%s", envname.ptr + 1, args); | |
1037 status = putenv(q); | |
1038 if (status == 0) | |
1039 args = envname[].idup; | |
1040 else | |
1041 { | |
1042 L1: | |
1043 error("command line length of %d is too long",len); | |
1044 } | |
1045 } | |
1046 | |
1047 status = executearg0(cmd, args); | |
1048 version (_WIN32) { | |
1049 if (status == -1) { | |
1050 auto cmdZ = toStringz(cmd); | |
1051 auto argsZ = toStringz(args); | |
1052 status = spawnlp(0, cmdZ, cmdZ, argsZ, null); | |
1053 } | |
1054 } | |
1055 // if (global.params.verbose) | |
1056 // printf("\n"); | |
1057 if (status) | |
1058 { | |
1059 if (status == -1) | |
1060 printf("Can't run '%s', check PATH\n", cmd); | |
1061 else | |
1062 printf("--- errorlevel %d\n", status); | |
1063 } | |
1064 return status; | |
1065 } | |
1066 } | |
1067 | |
1068 /************************************** | |
1069 * Attempt to find command to execute by first looking in the directory | |
1070 * where DMD was run from. | |
1071 * Returns: | |
1072 * -1 did not find command there | |
1073 * !=-1 exit status from command | |
1074 */ | |
1075 | |
1076 version (_WIN32) { | |
1077 int executearg0(string cmd, string args) | |
1078 { | |
1079 string file; | |
1080 string argv0 = global.params.argv0; | |
1081 | |
1082 //printf("argv0='%s', cmd='%s', args='%s'\n",argv0,cmd,args); | |
1083 | |
1084 // If cmd is fully qualified, we don't do this | |
1085 if (FileName.absolute(cmd)) | |
1086 return -1; | |
1087 | |
1088 file = FileName.replaceName(argv0, cmd); | |
1089 | |
1090 //printf("spawning '%s'\n",file); | |
1091 version (_WIN32) { | |
1092 auto fileZ = toStringz(file); | |
1093 auto argsZ = toStringz(args); | |
1094 return spawnl(0, fileZ, fileZ, argsZ, null); | |
1095 } else version (XXX) { ///#elif linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 | |
1096 assert(false); | |
1097 /+ | |
1098 char *full; | |
1099 int cmdl = strlen(cmd); | |
1100 | |
1101 full = (char*) mem.malloc(cmdl + strlen(args) + 2); | |
1102 if (full == null) | |
1103 return 1; | |
1104 strcpy(full, cmd); | |
1105 full [cmdl] = ' '; | |
1106 strcpy(full + cmdl + 1, args); | |
1107 | |
1108 int result = system(full); | |
1109 | |
1110 mem.free(full); | |
1111 return result; | |
1112 +/ | |
1113 } else { | |
1114 static assert(false); | |
1115 } | |
1116 } | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
2
diff
changeset
|
1117 } |