64 LILA_INFO(Emitter::INTERPRETER,
"Initializing Clang interpreter");
66#ifdef MAYAFLUX_PLATFORM_WINDOWS
67 llvm::sys::DynamicLibrary::LoadLibraryPermanently(
"msvcp140.dll");
68 llvm::sys::DynamicLibrary::LoadLibraryPermanently(
"vcruntime140.dll");
69 llvm::sys::DynamicLibrary::LoadLibraryPermanently(
"ucrtbase.dll");
72 llvm::InitializeNativeTarget();
73 llvm::InitializeNativeTargetAsmPrinter();
74 llvm::InitializeNativeTargetAsmParser();
76 m_impl->compile_flags.clear();
77 m_impl->compile_flags.emplace_back(
"-std=c++23");
78 m_impl->compile_flags.emplace_back(
"-DMAYASIMPLE");
80#ifdef MAYAFLUX_PLATFORM_LINUX
81 m_impl->compile_flags.emplace_back(
"-mcmodel=large");
82 m_impl->compile_flags.emplace_back(
"-fPIC");
83 m_impl->compile_flags.emplace_back(
"-fPIE");
87 if (std::filesystem::exists(MayaFlux::Config::PCH_RUNTIME_PATH)) {
88 pch_dir = MayaFlux::Config::RUNTIME_DATA_DIR;
90 std::string(
"Using installed PCH from: ") + std::string(MayaFlux::Config::PCH_RUNTIME_PATH));
92 }
else if (std::filesystem::exists(MayaFlux::Config::PCH_SOURCE_PATH)) {
93 pch_dir = std::string(MayaFlux::Config::SOURCE_DIR) +
"/cmake";
95 std::string(
"Using source PCH from: ") + std::string(MayaFlux::Config::PCH_SOURCE_PATH));
98 m_last_error =
"Cannot find pch.h in runtime or source locations";
99 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
103 m_impl->compile_flags.push_back(
"-I" + pch_dir);
106 if (!resource_dir.empty()) {
107 m_impl->compile_flags.push_back(
"-resource-dir=" + resource_dir);
109 std::string(
"Using clang resource dir: ") + resource_dir);
111 m_impl->compile_flags.emplace_back(
"-resource-dir=/usr/lib/clang/21");
113 "Using default clang resource dir: /usr/lib/clang/21");
117 for (
const auto& include : system_includes) {
118 m_impl->compile_flags.push_back(
"-isystem" + include);
121#ifndef MAYAFLUX_PLATFORM_WINDOWS
123 if (!eigen_include.empty()) {
124 m_impl->compile_flags.push_back(
"-isystem" + eigen_include);
126 std::string(
"Added Eigen include path: ") + eigen_include);
129 "Could not find Eigen include path - some features may not work");
133 if (!freetype_include.empty()) {
134 m_impl->compile_flags.push_back(
"-isystem" + freetype_include);
136 std::string(
"Added FreeType include path: ") + freetype_include);
139 "Could not find FreeType include path - some features may not work");
143#ifdef MAYAFLUX_PLATFORM_MACOS
146 std::string sdk_path = MayaFlux::Platform::SystemConfig::get_macos_sdk_path();
147 if (!sdk_path.empty()) {
148 m_impl->compile_flags.push_back(
"-isysroot" + sdk_path);
149 LILA_DEBUG(Emitter::INTERPRETER,
"Using macOS SDK: " + sdk_path);
152 "Could not find macOS SDK - JIT may fail to find system headers");
156 for (
const auto& path : m_impl->include_paths) {
157 m_impl->compile_flags.push_back(
"-I" + path);
160#ifdef MAYAFLUX_PLATFORM_WINDOWS
161 m_impl->compile_flags.emplace_back(
"-fno-function-sections");
162 m_impl->compile_flags.emplace_back(
"-fno-data-sections");
163 m_impl->compile_flags.emplace_back(
"-fno-unique-section-names");
166 std::vector<const char*> args;
167 for (
const auto& flag : m_impl->compile_flags) {
168 args.push_back(flag.c_str());
171 clang::IncrementalCompilerBuilder ICB;
172 ICB.SetCompilerArgs(args);
174 auto CI = ICB.CreateCpp();
176 m_last_error =
"Failed to create CompilerInstance: " + llvm::toString(CI.takeError());
177 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
181 auto interp = clang::Interpreter::create(std::move(*CI));
183 m_last_error =
"Failed to create interpreter: " + llvm::toString(interp.takeError());
184 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
188 m_impl->interpreter = std::move(*interp);
190 LILA_INFO(Emitter::INTERPRETER,
"Clang interpreter created successfully");
192 if (skip_host_library_load) {
194 "Skipping MayaFluxLib load: host process already resident");
197 "MayaFluxLib", std::string(MayaFlux::Config::INSTALL_PREFIX));
199 LILA_DEBUG(Emitter::INTERPRETER,
"Loading MayaFlux library: " + lib_to_load);
201 if (
auto err = m_impl->interpreter->LoadDynamicLibrary(lib_to_load.c_str())) {
202 m_last_error =
"Failed to load " + lib_to_load +
": "
203 + llvm::toString(std::move(err));
204 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
208 LILA_DEBUG(Emitter::INTERPRETER,
"Loaded " + lib_to_load);
211 const char* header_include = skip_host_library_load
212 ?
"#include \"pch.h\"\n"
213 "#include \"MayaFlux/MayaFlux.hpp\"\n"
214 :
"#include \"pch.h\"\n"
215 "#include \"Lila/LiveAid.hpp\"\n";
217 auto result = m_impl->interpreter->ParseAndExecute(header_include);
220 std::string warning =
"Failed to load MayaFlux headers: " + llvm::toString(std::move(result));
221 LILA_WARN(Emitter::INTERPRETER, warning);
223 LILA_INFO(Emitter::INTERPRETER,
"MayaFlux headers loaded successfully");
226 result = m_impl->interpreter->ParseAndExecute(
"std::cout << \"Ready for Live\" << std::flush;");
233#ifdef MAYAFLUX_PLATFORM_MACOS
239 if (!
m_impl->interpreter) {
240 result.
error =
"Interpreter not initialized";
241 LILA_ERROR(Emitter::INTERPRETER, result.error);
245 LILA_DEBUG(Emitter::INTERPRETER,
"Evaluating code...");
247#ifdef MAYAFLUX_PLATFORM_MACOS
248 dispatch_sync(dispatch_get_main_queue(), ^{
249 auto eval_result =
m_impl->interpreter->ParseAndExecute(code);
252 result.success =
true;
253 LILA_DEBUG(Emitter::INTERPRETER,
"Code evaluation succeeded");
255 result.success =
false;
256 result.error =
"Execution failed: " + llvm::toString(std::move(eval_result));
257 LILA_ERROR(Emitter::INTERPRETER, result.error);
261#elif defined(MAYAFLUX_PLATFORM_WINDOWS)
262 auto completed = std::make_shared<std::atomic<bool>>(
false);
264 auto* task =
static_cast<std::function<
void()
>*>(
265 HeapAlloc(GetProcessHeap(), 0,
sizeof(std::function<
void()>)));
266 new (task) std::function<
void()>([&, completed]() {
267 auto eval_result =
m_impl->interpreter->ParseAndExecute(code);
270 result.success =
true;
271 LILA_DEBUG(Emitter::INTERPRETER,
"Code evaluation succeeded");
273 result.success =
false;
274 result.error =
"Execution failed: " + llvm::toString(std::move(eval_result));
275 LILA_ERROR(Emitter::INTERPRETER, result.error);
278 completed->store(
true, std::memory_order_release);
281 PostThreadMessage(MayaFlux::Parallel::g_MainThreadId, MAYAFLUX_WM_DISPATCH, 0, (LPARAM)task);
283 while (!completed->load(std::memory_order_acquire)) {
284 std::this_thread::sleep_for(std::chrono::microseconds(100));
288 auto eval_result =
m_impl->interpreter->ParseAndExecute(code);
291 result.success =
true;
292 LILA_DEBUG(Emitter::INTERPRETER,
"Code evaluation succeeded");
294 result.success =
false;
295 result.error =
"Execution failed: " + llvm::toString(std::move(eval_result));
296 LILA_ERROR(Emitter::INTERPRETER, result.error);