在应用程序中嵌入C++编译器

问题描述 投票:0回答:4

着色器是不是很酷?您可以只输入一个纯字符串,只要它是有效的源,它就会编译、链接和执行。我想知道是否有一种方法可以将 GCC 嵌入到用户应用程序中,以便它“自给自足”,例如具有编译与其自身兼容的本机二进制文件的内部功能。

到目前为止,我一直在从应用程序内部启动的进程中调用独立的 GCC,但我想知道是否有一些 API 或其他东西可以允许“直接”使用而不是独立的编译器。另外,如果可以的话,可以吗?

编辑:虽然最初的问题是关于 CGG,但我也愿意了解如何嵌入 LLVM/Clang 的信息。

现在针对无法将 2 + 2 放在一起的人进行特殊编辑:问题询问如何将 GCC 或 Clang 嵌入到可执行文件中,从而允许从代码中使用内部 API,而不是从命令调用编译迅速的。

c++ gcc embed executable
4个回答
11
投票

我会在使用 Clang/LLVM 而不是 GCC 的建议中添加+1。几个很好的理由:

  • 更加模块化和灵活
  • 编译时间可以大大低于GCC
  • 它支持您在评论中列出的平台
  • 它有一个可以在内部使用的API

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
投票

是的,这是可能的,例如QEMU就可以做到。

我在这个领域没有任何个人经验,但从我所读到的内容来看,LLVM可能比GCC更适合嵌入和扩展。


1
投票

一些较旧的 C++ 编译器和解释器列表可在 http://www.thefreecountry.com/compilers/cpp.shtml 获得。

“自给自足”应用程序的答案通常是一个好的语言解释器。它们有很多,其中许多将代码编译成字节代码文件。非常流行且易于嵌入的是 Lua 语言 解释器。就连一些实力强的玩家也使用它.

还有一个开源的 C++ 解释器,具有良好的语言兼容性,多年前以

F
开头。不记得名称的其余部分。还有许多其他工具能够生成本机二进制文件(例如 Free Pascal)。

语言和目标平台的选择取决于意图。 “自给自足”有什么好处。谁将编写这些库。一旦你清楚了——使用谷歌——那里就有野生动物。最新的野兽之一是开源 C# 编译器“Roslyn”

编辑

如果您需要一些可以“嵌入”的 C 编译器(当您生成 C 子集时),您可能正在寻找 “便携式 C 编译器”,因为您可以 将其放在 USB 记忆棒上并随身携带 。便携式应用程序可以轻松“嵌入”到其他应用程序中,并且可以轻松包含在安装程序中。

可能不需要将编译器作为静态链接代码“嵌入”到主应用程序二进制文件中。

https://stackoverflow.com/questions/7617410/portable-c-compiler-ideSO问题中描述了对便携式MinGW的一些参考。

集成了 MinGW 的开源 C++ 编辑器就在这里 https://code.google.com/p/pocketcpp/.

我没有什么可说的,因为我必须去浏览谷歌 - 所以我不会赢得赏金:)


0
投票

为什么不直接使用 fork()/

exec()
(对于类 UNIX 平台)从应用程序中
调用
编译器和链接器?创建一个共享库,然后您可以使用
dlopen()
加载该库。

这可以避免可能的许可问题,并减轻您的维护负担。

这是例如varnish 对其配置文件做什么;

VCL 语言是一种小型的特定于域的语言,旨在用于定义 Varnish Cache 的请求处理和文档缓存策略。

当加载新配置时,varnishd 管理进程将 VCL 代码翻译为 C 代码,并将其编译为共享对象,然后动态链接到服务器进程中。

© www.soinside.com 2019 - 2024. All rights reserved.