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