예제 #1
0
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;
}
예제 #2
0
파일: linker.cpp 프로젝트: roysc/ldc
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;
}
예제 #3
0
파일: linker.cpp 프로젝트: odis-project/ldc
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;
}
예제 #4
0
파일: linker.cpp 프로젝트: odis-project/ldc
void deleteExecutable()
{
    if (!gExePath.isEmpty())
    {
        assert(gExePath.isValid());
        assert(!gExePath.isDirectory());
        gExePath.eraseFromDisk(false);
    }
}
예제 #5
0
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;
}
예제 #6
0
파일: linker.cpp 프로젝트: torje/ldc
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);
    }
}
예제 #7
0
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...
}
예제 #8
0
파일: linker.cpp 프로젝트: roysc/ldc
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;
}
예제 #9
0
파일: ldmd.cpp 프로젝트: John-Colvin/ldc
/**
 * 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\
예제 #10
0
파일: ldmd.cpp 프로젝트: John-Colvin/ldc
/**
 * 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;
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
  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...
  }
예제 #14
0
파일: linker.cpp 프로젝트: torje/ldc
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;
}
예제 #15
0
파일: main.cpp 프로젝트: ceninan/clay
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);
}
예제 #16
0
파일: linker.cpp 프로젝트: torje/ldc
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;
}
예제 #17
0
파일: linker.cpp 프로젝트: roysc/ldc
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);
}
예제 #18
0
파일: linker.cpp 프로젝트: roysc/ldc
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);
}
예제 #19
0
파일: configfile.cpp 프로젝트: alexrp/ldc
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;
}
예제 #20
0
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...
}
예제 #21
0
 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;
 }
예제 #22
0
void MetaSema::actOnICommand(llvm::sys::Path path) const {
    if (path.isEmpty())
        m_Interpreter.DumpIncludePath();
    else
        m_Interpreter.AddIncludePath(path.str());
}
예제 #23
0
파일: linker.cpp 프로젝트: odis-project/ldc
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;
}