Initializes the Clang interpreter and prepares for code evaluation.
43{
44 LILA_INFO(Emitter::INTERPRETER,
"Initializing Clang interpreter");
45
46#ifdef MAYAFLUX_PLATFORM_WINDOWS
47 llvm::sys::DynamicLibrary::LoadLibraryPermanently("msvcp140.dll");
48 llvm::sys::DynamicLibrary::LoadLibraryPermanently("vcruntime140.dll");
49 llvm::sys::DynamicLibrary::LoadLibraryPermanently("ucrtbase.dll");
50 llvm::sys::DynamicLibrary::LoadLibraryPermanently("MayaFluxLib.dll");
51#endif
52
53 llvm::InitializeNativeTarget();
54 llvm::InitializeNativeTargetAsmPrinter();
55 llvm::InitializeNativeTargetAsmParser();
56
57 m_impl->compile_flags.clear();
58 m_impl->compile_flags.emplace_back(
"-std=c++23");
59 m_impl->compile_flags.emplace_back(
"-DMAYASIMPLE");
60
61 std::string pch_dir;
62 if (std::filesystem::exists(MayaFlux::Config::PCH_RUNTIME_PATH)) {
63 pch_dir = MayaFlux::Config::RUNTIME_DATA_DIR;
65 std::string("Using installed PCH from: ") + std::string(MayaFlux::Config::PCH_RUNTIME_PATH));
66
67 } else if (std::filesystem::exists(MayaFlux::Config::PCH_SOURCE_PATH)) {
68 pch_dir = std::string(MayaFlux::Config::SOURCE_DIR) + "/cmake";
70 std::string("Using source PCH from: ") + std::string(MayaFlux::Config::PCH_SOURCE_PATH));
71
72 } else {
73 m_last_error =
"Cannot find pch.h in runtime or source locations";
75 return false;
76 }
77
78 m_impl->compile_flags.push_back(
"-I" + pch_dir);
79
80 std::string resource_dir = MayaFlux::Platform::SystemConfig::get_clang_resource_dir();
81 if (!resource_dir.empty()) {
82 m_impl->compile_flags.push_back(
"-resource-dir=" + resource_dir);
84 std::string("Using clang resource dir: ") + resource_dir);
85 } else {
86 m_impl->compile_flags.emplace_back(
"-resource-dir=/usr/lib/clang/20");
88 "Using default clang resource dir: /usr/lib/clang/20");
89 }
90
91 auto system_includes = MayaFlux::Platform::SystemConfig::get_system_includes();
92 for (const auto& include : system_includes) {
93 m_impl->compile_flags.push_back(
"-isystem" + include);
94 }
95
96#ifdef MAYAFLUX_PLATFORM_MACOS
97
98
99 std::string sdk_path = MayaFlux::Platform::SystemConfig::get_macos_sdk_path();
100 if (!sdk_path.empty()) {
101 m_impl->compile_flags.push_back(
"-isysroot" + sdk_path);
102 LILA_DEBUG(Emitter::INTERPRETER,
"Using macOS SDK: " + sdk_path);
103 } else {
105 "Could not find macOS SDK - JIT may fail to find system headers");
106 }
107#endif
108
109 for (
const auto& path :
m_impl->include_paths) {
110 m_impl->compile_flags.push_back(
"-I" + path);
111 }
112
113#ifdef MAYAFLUX_PLATFORM_WINDOWS
114 m_impl->compile_flags.emplace_back(
"-fno-function-sections");
115 m_impl->compile_flags.emplace_back(
"-fno-data-sections");
116 m_impl->compile_flags.emplace_back(
"-fno-unique-section-names");
117#endif
118
119 std::vector<const char*> args;
120 for (
const auto& flag :
m_impl->compile_flags) {
121 args.push_back(flag.c_str());
122 }
123
124 clang::IncrementalCompilerBuilder ICB;
125 ICB.SetCompilerArgs(args);
126
127 auto CI = ICB.CreateCpp();
128 if (!CI) {
129 m_last_error =
"Failed to create CompilerInstance: " + llvm::toString(CI.takeError());
131 return false;
132 }
133
134 auto interp = clang::Interpreter::create(std::move(*CI));
135 if (!interp) {
136 m_last_error =
"Failed to create interpreter: " + llvm::toString(interp.takeError());
138 return false;
139 }
140
141 m_impl->interpreter = std::move(*interp);
142
143 LILA_INFO(Emitter::INTERPRETER,
"Clang interpreter created successfully");
144
145 auto result =
m_impl->interpreter->ParseAndExecute(
146 "#include \"pch.h\"\n"
147 "#include \"Lila/LiveAid.hpp\"\n");
148
149 if (result) {
150 std::string warning = "Failed to load MayaFlux headers: " + llvm::toString(std::move(result));
151 LILA_WARN(Emitter::INTERPRETER, warning);
152 } else {
153 LILA_INFO(Emitter::INTERPRETER,
"MayaFlux headers loaded successfully");
154 }
155
156 result =
m_impl->interpreter->ParseAndExecute(
"std::cout << \"Ready for Live\" << std::flush;");
157
158 return true;
159}
std::unique_ptr< Impl > m_impl
Internal implementation details.