bool SerializationTest::Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint, ASTContext &Ctx) { { // Pretty-print the decls to a temp file. std::string Err; llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), true, Err); assert (Err.empty() && "Could not open file for printing out decls."); llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl(); for (DeclContext::decl_iterator I = TUD->decls_begin(Ctx), E = TUD->decls_end(Ctx); I != E; ++I) FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I)); } // Serialize the translation unit. // Reserve 256K for bitstream buffer. std::vector<unsigned char> Buffer; Buffer.reserve(256*1024); Ctx.EmitASTBitcodeBuffer(Buffer); // Write the bits to disk. if (FILE* fp = fopen(Filename.c_str(),"wb")) { fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp); fclose(fp); return true; } return false; }
static int ExecuteToolAndWait(llvm::sys::Path tool, std::vector<std::string> args, bool verbose = false) { // Construct real argument list. // First entry is the tool itself, last entry must be NULL. std::vector<const char *> realargs; realargs.reserve(args.size() + 2); realargs.push_back(tool.c_str()); for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) { realargs.push_back((*it).c_str()); } realargs.push_back(NULL); // Print command line if requested if (verbose) { // Print it for (int i = 0; i < realargs.size()-1; i++) printf("%s ", realargs[i]); printf("\n"); fflush(stdout); } // Execute tool. std::string errstr; if (int status = llvm::sys::Program::ExecuteAndWait(tool, &realargs[0], NULL, NULL, 0, 0, &errstr)) { error("%s failed with status: %d", tool.c_str(), status); if (!errstr.empty()) error("message: %s", errstr.c_str()); return status; } return 0; }
int runExecutable() { assert(!gExePath.isEmpty()); assert(gExePath.isValid()); // build arguments std::vector<const char*> args; // args[0] should be the name of the executable args.push_back(gExePath.c_str()); // Skip first argument to -run; it's a D source file. for (size_t i = 1, length = opts::runargs.size(); i < length; i++) { args.push_back(opts::runargs[i].c_str()); } // terminate args list args.push_back(NULL); // try to call linker!!! std::string errstr; int status = llvm::sys::Program::ExecuteAndWait(gExePath, &args[0], NULL, NULL, 0,0, &errstr); if (status < 0) { error("program received signal %d (%s)", -status, strsignal(-status)); return -status; } if (!errstr.empty()) { error("failed to execute program"); if (!errstr.empty()) error("error message: %s", errstr.c_str()); fatal(); } return status; }
void deleteExecutable() { if (!gExePath.isEmpty()) { assert(gExePath.isValid()); assert(!gExePath.isDirectory()); gExePath.eraseFromDisk(false); } }
void FileManager::FixupRelativePath(llvm::sys::Path &path, const FileSystemOptions &FSOpts) { if (FSOpts.WorkingDir.empty() || llvm::sys::path::is_absolute(path.str())) return; llvm::SmallString<128> NewPath(FSOpts.WorkingDir); llvm::sys::path::append(NewPath, path.str()); path = NewPath; }
void deleteExecutable() { if (!gExePath.isEmpty()) { assert(gExePath.isValid()); bool is_directory; assert(!(!llvm::sys::fs::is_directory(gExePath.str(), is_directory) && is_directory)); gExePath.eraseFromDisk(false); } }
void MetaSema::actOnxCommand(llvm::sys::Path file, llvm::StringRef args) { // Fall back to the meta processor for now. m_LastResultedValue = StoredValueRef::invalidValue(); m_MetaProcessor.executeFile(file.str(), args.str(), &m_LastResultedValue); //m_Interpreter.loadFile(path.str()); // TODO: extra checks. Eg if the path is readable, if the file exists... }
int runExecutable() { assert(!gExePath.isEmpty()); assert(gExePath.isValid()); // Run executable int status = ExecuteToolAndWait(gExePath, opts::runargs, !quiet || global.params.verbose); if (status < 0) { #if defined(_MSC_VER) error("program received signal %d", -status); #else error("program received signal %d (%s)", -status, strsignal(-status)); #endif return -status; } return status; }
/** * Prints usage information to stdout. */ void printUsage(const char* argv0, ls::Path ldcPath) { // Print version information by actually invoking ldc -version. const char* args[] = { ldcPath.c_str(), "-version", NULL }; execute(ldcPath, args); printf("\n\ Usage:\n\ %s files.d ... { -switch }\n\
/** * Runs the given executable, returning its error code. */ int execute(ls::Path exePath, const char** args) { std::string errorMsg; int rc = ls::Program::ExecuteAndWait(exePath, args, NULL, NULL, 0, 0, &errorMsg); if (!errorMsg.empty()) { error("Could not execute %s: %s", exePath.c_str(), errorMsg.c_str()); } return rc; }
void clang::LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, unsigned num_unsaved_files, struct CXUnsavedFile *unsaved_files, FileManager &FileMgr, SourceManager &SourceMgr, SmallVectorImpl<StoredDiagnostic> &Diags) { using llvm::MemoryBuffer; using llvm::StringRef; MemoryBuffer *F = MemoryBuffer::getFile(DiagnosticsPath.c_str()); if (!F) return; // Enter the unsaved files into the file manager. for (unsigned I = 0; I != num_unsaved_files; ++I) { const FileEntry *File = FileMgr.getVirtualFile(unsaved_files[I].Filename, unsaved_files[I].Length, 0); if (!File) { // FIXME: Hard to localize when we have no diagnostics engine! Diags.push_back(StoredDiagnostic(Diagnostic::Fatal, (Twine("could not remap from missing file ") + unsaved_files[I].Filename).str())); delete F; return; } MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(unsaved_files[I].Contents, unsaved_files[I].Contents + unsaved_files[I].Length); if (!Buffer) { delete F; return; } SourceMgr.overrideFileContents(File, Buffer); SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User); } // Parse the diagnostics, emitting them one by one until we've // exhausted the data. StringRef Buffer = F->getBuffer(); const char *Memory = Buffer.data(), *MemoryEnd = Memory + Buffer.size(); while (Memory != MemoryEnd) { StoredDiagnostic Stored = StoredDiagnostic::Deserialize(FileMgr, SourceMgr, Memory, MemoryEnd); if (!Stored) break; Diags.push_back(Stored); } delete F; }
bool SerializationTest::Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint) { // Deserialize the translation unit. ASTContext *NewCtx; { // Create the memory buffer that contains the contents of the file. llvm::OwningPtr<llvm::MemoryBuffer> MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str())); if (!MBuffer) return false; NewCtx = ASTContext::ReadASTBitcodeBuffer(*MBuffer, FMgr); } if (!NewCtx) return false; { // Pretty-print the deserialized decls to a temp file. std::string Err; llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), true, Err); assert (Err.empty() && "Could not open file for printing out decls."); llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP)); TranslationUnitDecl *TUD = NewCtx->getTranslationUnitDecl(); for (DeclContext::decl_iterator I = TUD->decls_begin(*NewCtx), E = TUD->decls_end(*NewCtx); I != E; ++I) FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I)); } delete NewCtx; return true; }
MetaSema::ActionResult MetaSema::actOnxCommand(llvm::sys::Path file, llvm::StringRef args, StoredValueRef* result) { // Fall back to the meta processor for now. Interpreter::CompilationResult compRes = Interpreter::kFailure; m_MetaProcessor.executeFile(file.str(), args.str(), compRes, result); ActionResult actionResult = AR_Failure; if (compRes == Interpreter::kSuccess) actionResult = AR_Success; return actionResult; //m_Interpreter.loadFile(path.str()); // TODO: extra checks. Eg if the path is readable, if the file exists... }
int linkExecutable(const char* argv0) { Logger::println("*** Linking executable ***"); // error string std::string errstr; // find the llvm-ld program llvm::sys::Path ldpath = llvm::sys::Program::FindProgramByName("llvm-ld"); if (ldpath.isEmpty()) { ldpath.set("llvm-ld"); } // build arguments std::vector<const char*> args; // first the program name ?? args.push_back("llvm-ld"); // output filename std::string exestr; if (global.params.exefile) { // explicit exestr = global.params.exefile; } else { // inferred // try root module name if (Module::rootModule) exestr = Module::rootModule->toChars(); else exestr = "a.out"; } if (global.params.os == OSWindows && !(exestr.substr(exestr.length()-4) == ".exe")) exestr.append(".exe"); std::string outopt = "-o=" + exestr; args.push_back(outopt.c_str()); // set the global gExePath gExePath.set(exestr); assert(gExePath.isValid()); // create path to exe llvm::sys::Path exedir(llvm::sys::path::parent_path(gExePath.str())); if (!llvm::sys::fs::exists(exedir.str())) { exedir.createDirectoryOnDisk(true, &errstr); if (!errstr.empty()) { error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str()); fatal(); } } // strip debug info if (!global.params.symdebug) args.push_back("-strip-debug"); // optimization level if (!optimize()) args.push_back("-disable-opt"); else { switch(optLevel()) { case 0: args.push_back("-disable-opt"); break; case 1: args.push_back("-globaldce"); args.push_back("-disable-opt"); args.push_back("-globaldce"); args.push_back("-mem2reg"); case 2: case 3: case 4: case 5: // use default optimization break; default: assert(0); } } // inlining if (!(global.params.useInline || doInline())) { args.push_back("-disable-inlining"); } // additional linker switches for (unsigned i = 0; i < global.params.linkswitches->dim; i++) { char *p = (char *)global.params.linkswitches->data[i]; args.push_back(p); } // native please args.push_back("-native"); // user libs for (unsigned i = 0; i < global.params.libfiles->dim; i++) { char *p = (char *)global.params.libfiles->data[i]; args.push_back(p); } // default libs switch(global.params.os) { case OSLinux: case OSMacOSX: args.push_back("-ldl"); case OSFreeBSD: args.push_back("-lpthread"); args.push_back("-lm"); break; case OSHaiku: args.push_back("-lroot"); break; case OSWindows: // FIXME: I'd assume kernel32 etc break; } // object files for (unsigned i = 0; i < global.params.objfiles->dim; i++) { char *p = (char *)global.params.objfiles->data[i]; args.push_back(p); } // print link command? if (!quiet || global.params.verbose) { // Print it for (int i = 0; i < args.size(); i++) printf("%s ", args[i]); printf("\n"); fflush(stdout); } // terminate args list args.push_back(NULL); // try to call linker!!! if (int status = llvm::sys::Program::ExecuteAndWait(ldpath, &args[0], NULL, NULL, 0,0, &errstr)) { error("linking failed:\nstatus: %d", status); if (!errstr.empty()) error("message: %s", errstr.c_str()); return status; } return 0; }
static bool generateBinary(llvm::Module *module, const string &outputFile, const llvm::sys::Path &gccPath, unsigned optLevel, bool /*exceptions*/, bool sharedLib, bool genPIC, const vector<string> &arguments) { llvm::sys::Path tempAsm("clayasm"); string errMsg; if (tempAsm.createTemporaryFileOnDisk(false, &errMsg)) { cerr << "error: " << errMsg << '\n'; return false; } llvm::sys::RemoveFileOnSignal(tempAsm); errMsg.clear(); llvm::raw_fd_ostream asmOut(tempAsm.c_str(), errMsg, llvm::raw_fd_ostream::F_Binary); if (!errMsg.empty()) { cerr << "error: " << errMsg << '\n'; return false; } generateAssembly(module, &asmOut, false, optLevel, sharedLib, genPIC); asmOut.close(); vector<const char *> gccArgs; gccArgs.push_back(gccPath.c_str()); switch (llvmTargetData->getPointerSizeInBits()) { case 32 : gccArgs.push_back("-m32"); break; case 64 : gccArgs.push_back("-m64"); break; default : assert(false); } if (sharedLib) gccArgs.push_back("-shared"); gccArgs.push_back("-o"); gccArgs.push_back(outputFile.c_str()); gccArgs.push_back("-x"); gccArgs.push_back("assembler"); gccArgs.push_back(tempAsm.c_str()); for (unsigned i = 0; i < arguments.size(); ++i) gccArgs.push_back(arguments[i].c_str()); gccArgs.push_back(NULL); int result = llvm::sys::Program::ExecuteAndWait(gccPath, &gccArgs[0]); if (tempAsm.eraseFromDisk(false, &errMsg)) { cerr << "error: " << errMsg << '\n'; return false; } return (result == 0); }
int linkObjToBinary(bool sharedLib) { Logger::println("*** Linking executable ***"); // error string std::string errstr; // find gcc for linking llvm::sys::Path gcc = getGcc(); // get a string version for argv[0] const char* gccStr = gcc.c_str(); // build arguments std::vector<const char*> args; // first the program name ?? args.push_back(gccStr); // object files for (unsigned i = 0; i < global.params.objfiles->dim; i++) { char *p = (char *)global.params.objfiles->data[i]; args.push_back(p); } // output filename std::string output; if (!sharedLib && global.params.exefile) { // explicit output = global.params.exefile; } else if (sharedLib && global.params.objname) { // explicit output = global.params.objname; } else { // inferred // try root module name if (Module::rootModule) output = Module::rootModule->toChars(); else if (global.params.objfiles->dim) output = FileName::removeExt((char*)global.params.objfiles->data[0]); else output = "a.out"; if (sharedLib) { std::string libExt = std::string(".") + global.dll_ext; if (!endsWith(output, libExt)) { if (global.params.os != OSWindows) output = "lib" + output + libExt; else output.append(libExt); } args.push_back("-shared"); } else if (global.params.os == OSWindows && !endsWith(output, ".exe")) { output.append(".exe"); } } args.push_back("-o"); args.push_back(output.c_str()); // set the global gExePath gExePath.set(output); assert(gExePath.isValid()); // create path to exe llvm::sys::Path exedir(llvm::sys::path::parent_path(gExePath.str())); if (!exedir.empty() && !llvm::sys::fs::exists(exedir.str())) { exedir.createDirectoryOnDisk(true, &errstr); if (!errstr.empty()) { error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str()); fatal(); } } // additional linker switches for (unsigned i = 0; i < global.params.linkswitches->dim; i++) { char *p = (char *)global.params.linkswitches->data[i]; args.push_back("-Xlinker"); args.push_back(p); } // user libs for (unsigned i = 0; i < global.params.libfiles->dim; i++) { char *p = (char *)global.params.libfiles->data[i]; args.push_back(p); } // default libs bool addSoname = false; switch(global.params.os) { case OSLinux: addSoname = true; args.push_back("-lrt"); // fallthrough case OSMacOSX: args.push_back("-ldl"); // fallthrough case OSFreeBSD: addSoname = true; args.push_back("-lpthread"); args.push_back("-lm"); break; case OSSolaris: args.push_back("-lm"); args.push_back("-lumem"); // solaris TODO break; case OSWindows: // FIXME: I'd assume kernel32 etc break; } //FIXME: enforce 64 bit if (global.params.is64bit) args.push_back("-m64"); else // Assume 32-bit? args.push_back("-m32"); OutBuffer buf; if (opts::createSharedLib && addSoname) { std::string soname = opts::soname.getNumOccurrences() == 0 ? output : opts::soname; if (!soname.empty()) { buf.writestring("-Wl,-soname,"); buf.writestring(soname.c_str()); args.push_back(buf.toChars()); } } // print link command? if (!quiet || global.params.verbose) { // Print it for (int i = 0; i < args.size(); i++) printf("%s ", args[i]); printf("\n"); fflush(stdout); } Logger::println("Linking with: "); std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); Stream logstr = Logger::cout(); for (; I != E; ++I) if (*I) logstr << "'" << *I << "'" << " "; logstr << "\n"; // FIXME where's flush ? // terminate args list args.push_back(NULL); // try to call linker if (int status = llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr)) { error("linking failed:\nstatus: %d", status); if (!errstr.empty()) error("message: %s", errstr.c_str()); return status; } return 0; }
int linkObjToBinaryWin(bool sharedLib) { Logger::println("*** Linking executable ***"); // find link.exe for linking llvm::sys::Path tool = getLink(); // build arguments std::vector<std::string> args; // be verbose if requested if (!global.params.verbose) args.push_back("/NOLOGO"); // specify that the image will contain a table of safe exception handlers (32bit only) if (!global.params.is64bit) args.push_back("/SAFESEH"); // mark executable to be compatible with Windows Data Execution Prevention feature args.push_back("/NXCOMPAT"); // use address space layout randomization (ASLR) feature args.push_back("/DYNAMICBASE"); // because of a LLVM bug args.push_back("/LARGEADDRESSAWARE:NO"); // specify creation of DLL if (sharedLib) args.push_back("/DLL"); // output filename std::string output; if (!sharedLib && global.params.exefile) { // explicit output = global.params.exefile; } else if (sharedLib && global.params.objname) { // explicit output = global.params.objname; } else { // inferred // try root module name if (Module::rootModule) output = Module::rootModule->toChars(); else if (global.params.objfiles->dim) output = FileName::removeExt(static_cast<char*>(global.params.objfiles->data[0])); else output = "a.out"; if (sharedLib) { std::string libExt = std::string(".") + global.dll_ext; if (!endsWith(output, libExt)) { if (global.params.os != OSWindows) output = "lib" + output + libExt; else output.append(libExt); } } else if (global.params.os == OSWindows && !endsWith(output, ".exe")) { output.append(".exe"); } } args.push_back("/OUT:" + output); // object files for (unsigned i = 0; i < global.params.objfiles->dim; i++) { char *p = static_cast<char *>(global.params.objfiles->data[i]); args.push_back(p); } // user libs for (unsigned i = 0; i < global.params.libfiles->dim; i++) { char *p = static_cast<char *>(global.params.libfiles->data[i]); args.push_back(p); } // set the global gExePath gExePath.set(output); assert(gExePath.isValid()); // create path to exe CreateDirectoryOnDisk(gExePath.str()); // additional linker switches for (unsigned i = 0; i < global.params.linkswitches->dim; i++) { static const std::string LIBPATH("-L"); static const std::string LIB("-l"); std::string str(static_cast<char *>(global.params.linkswitches->data[i])); if (str.length() > 2) { if (std::equal(LIBPATH.begin(), LIBPATH.end(), str.begin())) str = "/LIBPATH:" + str.substr(2); else if (std::equal(LIB.begin(), LIB.end(), str.begin())) { str = str.substr(2) + ".lib"; } } args.push_back(str); } // default libs // TODO check which libaries are necessary args.push_back("kernel32.lib"); args.push_back("user32.lib"); args.push_back("gdi32.lib"); args.push_back("winspool.lib"); args.push_back("shell32.lib"); // required for dmain2.d args.push_back("ole32.lib"); args.push_back("oleaut32.lib"); args.push_back("uuid.lib"); args.push_back("comdlg32.lib"); args.push_back("advapi32.lib"); Logger::println("Linking with: "); std::vector<std::string>::const_iterator I = args.begin(), E = args.end(); Stream logstr = Logger::cout(); for (; I != E; ++I) if (!(*I).empty()) logstr << "'" << *I << "'" << " "; logstr << "\n"; // FIXME where's flush ? // try to call linker return ExecuteToolAndWait(tool, args, !quiet || global.params.verbose); }
int linkObjToBinaryGcc(bool sharedLib) { Logger::println("*** Linking executable ***"); // find gcc for linking llvm::sys::Path gcc = getGcc(); // build arguments std::vector<std::string> args; // object files for (unsigned i = 0; i < global.params.objfiles->dim; i++) { char *p = static_cast<char *>(global.params.objfiles->data[i]); args.push_back(p); } // user libs for (unsigned i = 0; i < global.params.libfiles->dim; i++) { char *p = static_cast<char *>(global.params.libfiles->data[i]); args.push_back(p); } // output filename std::string output; if (!sharedLib && global.params.exefile) { // explicit output = global.params.exefile; } else if (sharedLib && global.params.objname) { // explicit output = global.params.objname; } else { // inferred // try root module name if (Module::rootModule) output = Module::rootModule->toChars(); else if (global.params.objfiles->dim) output = FileName::removeExt(static_cast<char*>(global.params.objfiles->data[0])); else output = "a.out"; if (sharedLib) { std::string libExt = std::string(".") + global.dll_ext; if (!endsWith(output, libExt)) { if (global.params.os != OSWindows) output = "lib" + output + libExt; else output.append(libExt); } } else if (global.params.os == OSWindows && !endsWith(output, ".exe")) { output.append(".exe"); } } if (sharedLib) args.push_back("-shared"); args.push_back("-o"); args.push_back(output); // set the global gExePath gExePath.set(output); assert(gExePath.isValid()); // create path to exe CreateDirectoryOnDisk(gExePath.str()); // additional linker switches for (unsigned i = 0; i < global.params.linkswitches->dim; i++) { char *p = static_cast<char *>(global.params.linkswitches->data[i]); args.push_back("-Xlinker"); args.push_back(p); } // default libs bool addSoname = false; switch(global.params.os) { case OSLinux: addSoname = true; args.push_back("-lrt"); // fallthrough case OSMacOSX: args.push_back("-ldl"); // fallthrough case OSFreeBSD: addSoname = true; args.push_back("-lpthread"); args.push_back("-lm"); break; case OSSolaris: args.push_back("-lm"); args.push_back("-lumem"); // solaris TODO break; case OSWindows: // FIXME: I'd assume kernel32 etc break; } //FIXME: enforce 64 bit if (global.params.is64bit) args.push_back("-m64"); else // Assume 32-bit? args.push_back("-m32"); if (opts::createSharedLib && addSoname) { std::string soname = opts::soname; if (!soname.empty()) { args.push_back("-Wl,-soname," + soname); } } Logger::println("Linking with: "); std::vector<std::string>::const_iterator I = args.begin(), E = args.end(); Stream logstr = Logger::cout(); for (; I != E; ++I) if (!(*I).empty()) logstr << "'" << *I << "'" << " "; logstr << "\n"; // FIXME where's flush ? // try to call linker return ExecuteToolAndWait(gcc, args, !quiet || global.params.verbose); }
bool ConfigFile::locate(sys::Path& p, const char* argv0, void* mainAddr, const char* filename) { // temporary configuration // try the current working dir p = sys::Path::GetCurrentDirectory(); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; // try next to the executable p = sys::Path::GetMainExecutable(argv0, mainAddr); p.eraseComponent(); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; // user configuration // try ~/.ldc p = sys::Path::GetUserHomeDirectory(); p.appendComponent(".ldc"); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; #if _WIN32 // try home dir p = sys::Path::GetUserHomeDirectory(); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; #endif // system configuration // try in etc relative to the executable: exe\..\etc // do not use .. in path because of security risks p = sys::Path::GetMainExecutable(argv0, mainAddr); p.eraseComponent(); p.eraseComponent(); if (!p.isEmpty()) { p.appendComponent("etc"); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; } #if _WIN32 // try the install-prefix p = sys::Path(LDC_INSTALL_PREFIX); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; #else // try the install-prefix/etc p = sys::Path(LDC_INSTALL_PREFIX); p.appendComponent("etc"); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; // try the install-prefix/etc/ldc p = sys::Path(LDC_INSTALL_PREFIX); p.appendComponent("etc"); p.appendComponent("ldc"); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; // try /etc (absolute path) p = sys::Path("/etc"); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; // try /etc/ldc (absolute path) p = sys::Path("/etc/ldc"); p.appendComponent(filename); if (sys::fs::exists(p.str())) return true; #endif return false; }
void MetaSema::actOnLCommand(llvm::sys::Path file) const { m_Interpreter.loadFile(file.str()); // TODO: extra checks. Eg if the path is readable, if the file exists... }
MetaSema::ActionResult MetaSema::actOnLCommand(llvm::sys::Path file) const { // TODO: extra checks. Eg if the path is readable, if the file exists... if (m_Interpreter.loadFile(file.str()) == Interpreter::kSuccess) return AR_Success; return AR_Failure; }
void MetaSema::actOnICommand(llvm::sys::Path path) const { if (path.isEmpty()) m_Interpreter.DumpIncludePath(); else m_Interpreter.AddIncludePath(path.str()); }
int linkObjToExecutable(const char* argv0) { Logger::println("*** Linking executable ***"); // error string std::string errstr; // find gcc for linking llvm::sys::Path gcc = getGcc(); // get a string version for argv[0] const char* gccStr = gcc.c_str(); // build arguments std::vector<const char*> args; // first the program name ?? args.push_back(gccStr); // object files for (int i = 0; i < global.params.objfiles->dim; i++) { char *p = (char *)global.params.objfiles->data[i]; args.push_back(p); } // output filename std::string exestr; if (global.params.exefile) { // explicit exestr = global.params.exefile; } else { // inferred // try root module name if (Module::rootModule) exestr = Module::rootModule->toChars(); else if (global.params.objfiles->dim) exestr = FileName::removeExt((char*)global.params.objfiles->data[0]); else exestr = "a.out"; } if (global.params.os == OSWindows && !(exestr.rfind(".exe") == exestr.length()-4)) exestr.append(".exe"); args.push_back("-o"); args.push_back(exestr.c_str()); // set the global gExePath gExePath.set(exestr); assert(gExePath.isValid()); // create path to exe llvm::sys::Path exedir(gExePath); exedir.set(gExePath.getDirname()); if (!exedir.exists()) { exedir.createDirectoryOnDisk(true, &errstr); if (!errstr.empty()) { error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str()); fatal(); } } // additional linker switches for (int i = 0; i < global.params.linkswitches->dim; i++) { char *p = (char *)global.params.linkswitches->data[i]; args.push_back(p); } // user libs for (int i = 0; i < global.params.libfiles->dim; i++) { char *p = (char *)global.params.libfiles->data[i]; args.push_back(p); } // default libs switch(global.params.os) { case OSLinux: args.push_back("-lrt"); // fallthrough case OSMacOSX: args.push_back("-ldl"); // fallthrough case OSFreeBSD: args.push_back("-lpthread"); args.push_back("-lm"); break; case OSSolaris: args.push_back("-lm"); args.push_back("-lumem"); // solaris TODO break; case OSWindows: // FIXME: I'd assume kernel32 etc break; } //FIXME: enforce 64 bit if (global.params.is64bit) args.push_back("-m64"); else // Assume 32-bit? args.push_back("-m32"); // print link command? if (!quiet || global.params.verbose) { // Print it for (int i = 0; i < args.size(); i++) printf("%s ", args[i]); printf("\n"); fflush(stdout); } Logger::println("Linking with: "); std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); Stream logstr = Logger::cout(); for (; I != E; ++I) if (*I) logstr << "'" << *I << "'" << " "; logstr << "\n"; // FIXME where's flush ? // terminate args list args.push_back(NULL); // try to call linker if (int status = llvm::sys::Program::ExecuteAndWait(gcc, &args[0], NULL, NULL, 0,0, &errstr)) { error("linking failed:\nstatus: %d", status); if (!errstr.empty()) error("message: %s", errstr.c_str()); return status; } return 0; }