Embed C++ compiler in application

2019-04-06 14:46发布

问题:

Aren't shaders cool? You can toss in just a plain string and as long as it is valid source, it will compile, link and execute. I was wondering if there is a way to embed GCC inside a user application so that it is "self sufficient" e.g. has the internal capability to compile native binaries compatible to itself.

So far I've been invoking stand alone GCC from a process, started inside the application, but I was wondering if there is some API or something that could allow to use "directly" rather than a standalone compiler. Also, in the case it is possible, is it permitted?

EDIT: Although the original question was about CGG, I'd settle for information how to embed LLVM/Clang too.

And now a special edit for people who cannot put 2 + 2 together: The question asks about how to embed GCC or Clang inside of an executable in a way that allows an internal API to be used from code rather than invoking compilation from a command prompt.

回答1:

I'd add +1 to the suggestion to use Clang/LLVM instead of GCC. A few good reasons why:

  • it is more modular and flexible
  • compilation time can be substantially lower than GCC
  • it supports the platforms you listed in the comments
  • it has an API that can be used internally

string source = "app.c";
string target= "app"; 

llvm::sys::Path clangPath = llvm::sys::Program::FindProgramByName("clang");

// arguments
vector<const char *> args;
args.push_back(clangPath.c_str());
args.push_back(source.c_str());
args.push_back("-l");
args.push_back("curl");

clang::TextDiagnosticPrinter *DiagClient = new clang::TextDiagnosticPrinter(llvm::errs(), clang::DiagnosticOptions());
clang::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
clang::DiagnosticsEngine Diags(DiagID, DiagClient);

clang::driver::Driver TheDriver(args[0], llvm::sys::getDefaultTargetTriple(), target, true, Diags);

clang::OwningPtr<clang::driver::Compilation> c(TheDriver.BuildCompilation(args));

int res = 0;
const clang::driver::Command *FailingCommand = 0;
if (c) res = TheDriver.ExecuteCompilation(*c, FailingCommand);
if (res < 0) TheDriver.generateCompilationDiagnostics(*c, FailingCommand);


回答2:

Yes, it is possible, for example, QEMU does it.

I don't have any personal experience in this field, but from what I've read, it seems that LLVM might be better suited for embedding and extending than GCC.



回答3:

Why not just call the compiler and linker from your application using fork()/exec() (for UNIX-like platforms)? Create a shared library that you can then load with dlopen().

This avoids possible licensing issues and gives you less of a maintenance burden.

This is e.g. what varnish does with its configuration files;

The VCL language is a small domain-specific language designed to be used to define request handling and document caching policies for Varnish Cache.

When a new configuration is loaded, the varnishd management process translates the VCL code to C and compiles it to a shared object which is then dynamically linked into the server process.



回答4:

Some older list of C++ compilers and interpreters is available at http://www.thefreecountry.com/compilers/cpp.shtml.

Answer to the "self sufficient" application is usually a good language interpreter. There are many of them out there, many compile the code into a byte code files. Very popular and easily embeddable is the Lua language interpreter. Even some strong players use it.

There was also an open source C++ interpreter with great language compatibility produced years ago starting with F.. Don't remember the rest of the name. There are also many other tools able to produce native binaries (e.g. Free Pascal).

Choice of the language and the target platform depends on the intentions. What would be the "self sufficiency" good for. Who will write those libraries. Once you have that clear - use Google - there is a wildlife out there. One of the latest beasts is the open sourced C# compiler "Roslyn"

EDIT

If you need some C compiler (as you generate C subset) that can be "embedded" you are probably looking for a "portable C compiler" in the sense that you can put it on USB stick and carry with you. Portable applications can be easily "embedded" into other applications and can be easily included in the installer.

Possibility to "embed" compiler as statically linked code into main application binary is probably not required.

Some reference to portable MinGW is described in this https://stackoverflow.com/questions/7617410/portable-c-compiler-ide SO question.

An open source C++ editor with integrated MinGW is here https://code.google.com/p/pocketcpp/.

I don't have anything more to say as I'd have to go and browse Google - so I will not win the bounty :)