Mercurial > projects > ldc
comparison gen/linker.cpp @ 677:075c1272a01d
Link using gcc instead.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 11 Oct 2008 21:21:21 +0200 |
parents | 6aaa3d3c1183 |
children | ca4a816f2440 |
comparison
equal
deleted
inserted
replaced
676:1f0a78174598 | 677:075c1272a01d |
---|---|
195 } | 195 } |
196 } | 196 } |
197 | 197 |
198 ////////////////////////////////////////////////////////////////////////////// | 198 ////////////////////////////////////////////////////////////////////////////// |
199 | 199 |
200 int linkObjToExecutable(const char* argv0) | |
201 { | |
202 Logger::println("*** Linking executable ***"); | |
203 | |
204 // error string | |
205 std::string errstr; | |
206 | |
207 // find gcc for linking | |
208 llvm::sys::Path gcc = llvm::sys::Program::FindProgramByName("gcc"); | |
209 if (gcc.isEmpty()) | |
210 { | |
211 gcc.set("gcc"); | |
212 } | |
213 | |
214 // build arguments | |
215 std::vector<const char*> args; | |
216 | |
217 // first the program name ?? | |
218 args.push_back("gcc"); | |
219 | |
220 // output filename | |
221 std::string exestr; | |
222 if (global.params.exefile) | |
223 { // explicit | |
224 exestr = global.params.exefile; | |
225 } | |
226 else | |
227 { // inferred | |
228 // try root module name | |
229 if (Module::rootModule) | |
230 exestr = Module::rootModule->toChars(); | |
231 else | |
232 exestr = "a.out"; | |
233 } | |
234 if (global.params.os == OSWindows) | |
235 exestr.append(".exe"); | |
236 | |
237 args.push_back("-o"); | |
238 args.push_back(exestr.c_str()); | |
239 | |
240 // set the global gExePath | |
241 gExePath.set(exestr); | |
242 assert(gExePath.isValid()); | |
243 | |
244 // create path to exe | |
245 llvm::sys::Path exedir(gExePath); | |
246 exedir.set(gExePath.getDirname()); | |
247 if (!exedir.exists()) | |
248 { | |
249 exedir.createDirectoryOnDisk(true, &errstr); | |
250 if (!errstr.empty()) | |
251 { | |
252 error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str()); | |
253 fatal(); | |
254 } | |
255 } | |
256 | |
257 // additional linker switches | |
258 for (int i = 0; i < global.params.linkswitches->dim; i++) | |
259 { | |
260 char *p = (char *)global.params.linkswitches->data[i]; | |
261 args.push_back(p); | |
262 } | |
263 | |
264 // user libs | |
265 for (int i = 0; i < global.params.libfiles->dim; i++) | |
266 { | |
267 char *p = (char *)global.params.libfiles->data[i]; | |
268 args.push_back(p); | |
269 } | |
270 | |
271 // default libs | |
272 switch(global.params.os) { | |
273 case OSLinux: | |
274 case OSMacOSX: | |
275 args.push_back("-ldl"); | |
276 case OSFreeBSD: | |
277 args.push_back("-lpthread"); | |
278 args.push_back("-lm"); | |
279 break; | |
280 | |
281 case OSWindows: | |
282 // FIXME: I'd assume kernel32 etc | |
283 break; | |
284 } | |
285 | |
286 // object files | |
287 for (int i = 0; i < global.params.objfiles->dim; i++) | |
288 { | |
289 char *p = (char *)global.params.objfiles->data[i]; | |
290 args.push_back(p); | |
291 } | |
292 | |
293 // print link command? | |
294 if (!global.params.quiet || global.params.verbose) | |
295 { | |
296 // Print it | |
297 for (int i = 0; i < args.size(); i++) | |
298 printf("%s ", args[i]); | |
299 printf("\n"); | |
300 fflush(stdout); | |
301 } | |
302 | |
303 Logger::println("Linking with: "); | |
304 std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); | |
305 std::ostream& logstr = Logger::cout(); | |
306 for (; I != E; ++I) | |
307 if (*I) | |
308 logstr << "'" << *I << "'" << " "; | |
309 logstr << "\n" << std::flush; | |
310 | |
311 | |
312 // terminate args list | |
313 args.push_back(NULL); | |
314 | |
315 // try to call linker!!! | |
316 if (int status = llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr)) | |
317 { | |
318 error("linking failed:\nstatus: %d", status); | |
319 if (!errstr.empty()) | |
320 error("message: %s", errstr.c_str()); | |
321 fatal(); | |
322 } | |
323 } | |
324 | |
325 ////////////////////////////////////////////////////////////////////////////// | |
326 | |
200 void deleteExecutable() | 327 void deleteExecutable() |
201 { | 328 { |
202 if (!gExePath.isEmpty()) | 329 if (!gExePath.isEmpty()) |
203 { | 330 { |
204 assert(gExePath.isValid()); | 331 assert(gExePath.isValid()); |