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());