1

Currently I am implementing a compiler for my programming language. So my compiler compiles source files to .o object files, and since I want my programming language to have access to C functions like printf, I need link the .o file to libc.

To be clear, using g++ or ld in commandline as the linker works perfectly, but I want to invoke LLVM linker (lld) using C++. However, after searching through lld's documentation, I didn't find anything about its C++ API.

For anyone experienced in making a compiler using LLVM, is there a C++ API for lld? If yes, then how can I use the API or where is its documentation?

I don't want to use things like system() to call lld

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
tjysdsg
  • 656
  • 8
  • 19
  • Backticks are for formatting *code*, not for emphasis. Names like “C++” shouldn’t be formatted as code. – Konrad Rudolph Feb 27 '20 at 13:37
  • "I don't want to use things like system() to call lld" Why not? And "compiler compiles source files to .o object " Really? You create the binary code? For which CPU model/family? And finally: ld (lld ?) is a program, a tool, who says that there must be a C++ API? – Rene Feb 27 '20 at 14:21
  • 1
    https://stackoverflow.com/questions/10675661/what-exactly-is-the-llvm-c-api#10680514 – Bord81 Feb 27 '20 at 15:42
  • 1
    I'm not sure where the documentation is, but you use something similar to `elf::link(args, exitEarly, stdoutOS, stderrOS)` depending on the linker type. The usage can be found in the main function of lld. – lxr196 Jan 10 '21 at 06:45

1 Answers1

3

In order to do this, you must use the llvm c++ api

First, create your main file:

#include <lld/Common/Driver.h>

int main() {
    std::vector<const char *> args;

    // Equivalent to calling lld from the command line
    args.push_back("ld64.lld");
    args.push_back("-dynamic");
    args.push_back("-arch");
    args.push_back("x86_64");
    args.push_back("-platform_version");
    args.push_back("macos");
    args.push_back("11.0.0");
    args.push_back("11.0.0");
    args.push_back("-syslibroot");
    args.push_back("/Library/Developer/CommandLineTools/SDKs/MacOSX11.sdk");
    args.push_back("-lSystem");
    args.push_back("/usr/local/Cellar/llvm/15.0.5/lib/clang/15.0.5/lib/darwin/libclang_rt.osx.a");
    args.push_back("test.o");

    // Replace macho with elf, mingw, wasm, or coff depending on your target system
    lld::macho::link(args, llvm::outs(), llvm::errs(), false, false);
    return 0;
}

Next, compile using:

clang++ <insert c++ file name> `llvm-config --cxxflags --ldflags --system-libs --libs core` -llldMACHO -llldCOFF -llldELF -llldCommon -llldMinGW -llldWasm -lxar

If you want to see what command and flags you need for lld on your system, one way you could do that is by running clang on a c file and add -v to see the separate commands.

JSGuy
  • 76
  • 8