MCJIT 在 LLVM 14+ 中已被彻底移除,必须迁移到 LLJIT;其核心差异在于模块管理、符号解析和内存模型,旧代码会因头文件缺失和链接失败而无法编译。

MCJIT 在 LLVM 14+ 已被移除,别再查 MCJIT 教程了
LLVM 从 14 版本起正式删除 MCJIT,所有基于它的代码会编译失败或链接报错:undefined reference to 'llvm::MCJIT::create'。这不是配置问题,是 API 彻底下线。官方推荐迁移到 LLJIT(即新 JIT 引擎),它更轻量、线程安全、API 更一致。
LLJIT 替代 MCJIT 的最小可行写法(C++)
用 LLJIT 加载一个简单函数,核心就三步:构造引擎、添加模块、查找符号。注意它默认不支持全局变量初始化和弱符号解析,复杂逻辑需额外处理。
常见错误现象:getSymbolAddress 返回 0,或运行时段错误 —— 多半是没调用 addIRModule,或模块没设 data layout。
-
LLJIT::Create()后必须调用setObjectLinkingLayerCreator(仅旧版需要),新版通常直接用默认构造 - 模块必须调用
setDataLayout,否则生成的机器码可能错位;可用jit->getDataLayout()获取当前布局 -
addIRModule是异步操作,但lookup会自动等待完成,不用手动同步 - 函数指针类型要和 IR 中的签名严格匹配,C++ 里建议用
reinterpret_cast转,别用auto*直接赋值
auto jit = cantFail(LLJIT::Create());
auto module = std::make_unique<Module>("demo", jit->getGlobalContxt());
module->setDataLayout(jit->getDataLayout());
// ... 添加函数定义
cantFail(jit->addIRModule(ThreadSafeModule(std::move(module), jit->getGlobalContxt())));
auto addr = cantFail(jit->lookup("my_add"));
int (*my_add)(int, int) = reinterpret_cast<int(*)(int,int)>(addr.getAddress());
为什么你的 MCJIT 代码在 clang++ 下连不过
不是编译器问题,是头文件和链接依赖变了。LLVM 14+ 的头文件里已删掉 MCJIT.h,链接时 -lLLVMExecutionEngine 也不再导出 MCJIT 符号。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
使用场景:如果你维护的是 2020 年前的教程、旧项目或第三方库(如某些 Python binding),它们大概率卡在 ExecutionEngine::create 或 MCJIT::create 上。
- 检查 LLVM 版本:
llvm-config --version,≥14 就别挣扎了 - 头文件路径里搜
MCJIT.h,找不到就是被删了 - 链接时报
undefined reference to llvm::MCJIT::create,说明你还在用老 API 调用方式 - 兼容性影响:LLJIT 默认启用 ORCv2,不支持
RTDyldMemoryManager自定义内存管理,得换用LegacyRTDyldMemoryManager或重写分配逻辑
LLJIT 和 MCJIT 的关键参数差异
两者初始化逻辑不同,最易踩坑的是模块生命周期管理和符号可见性控制。
-
MCJIT允许反复addModule并共享全局符号;LLJIT要求每个addIRModule是独立的ThreadSafeModule,跨模块引用需显式addIRModule顺序或用ExtraModules -
MCJIT::setProcessAllSections(true)对应LLJIT中的ObjectLinkingLayer::setAutoClaimObjects(true),但默认关闭,不设就看不到全局变量 -
MCJIT的setObjectCache在LLJIT中由ObjectLinkingLayer::setNotifyLoaded+ 自定义缓存实现,没现成 wrapper - 性能上,LLJIT 启动更快、内存占用更低,但首次
lookup可能略慢(因按需编译)
真正麻烦的不是替换几行代码,而是旧项目里那些隐式依赖 MCJIT 内存模型、符号解析顺序、或自定义 memory manager 的部分 —— 这些没法自动迁移,得一行行看 IR 生成逻辑和运行时绑定方式。


















