MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ initialize()

bool Lila::ClangInterpreter::initialize ( bool  skip_host_library_load = false)

Initialize the Clang interpreter.

Parameters
skip_host_library_loadIf true, do not call LoadDynamicLibrary on MayaFluxLib. Pass true when the host process has already loaded MayaFluxLib (attach scenario). Pass false for standalone use (lila_server).
Returns
true on success.

Definition at line 62 of file ClangInterpreter.cpp.

63{
64 LILA_INFO(Emitter::INTERPRETER, "Initializing Clang interpreter");
65
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");
70#endif
71
72 llvm::InitializeNativeTarget();
73 llvm::InitializeNativeTargetAsmPrinter();
74 llvm::InitializeNativeTargetAsmParser();
75
76 m_impl->compile_flags.clear();
77 m_impl->compile_flags.emplace_back("-std=c++23");
78
79#ifdef MAYAFLUX_PLATFORM_LINUX
80 m_impl->compile_flags.emplace_back("-mcmodel=large");
81 m_impl->compile_flags.emplace_back("-fPIC");
82 m_impl->compile_flags.emplace_back("-fPIE");
83#endif
84
85 std::string pch_dir;
86 if (std::filesystem::exists(MayaFlux::Config::PCH_RUNTIME_PATH)) {
87 pch_dir = MayaFlux::Config::RUNTIME_DATA_DIR;
88 LILA_DEBUG(Emitter::INTERPRETER,
89 std::string("Using installed PCH from: ") + std::string(MayaFlux::Config::PCH_RUNTIME_PATH));
90
91 } else if (std::filesystem::exists(MayaFlux::Config::PCH_SOURCE_PATH)) {
92 pch_dir = std::string(MayaFlux::Config::SOURCE_DIR) + "/cmake";
93 LILA_DEBUG(Emitter::INTERPRETER,
94 std::string("Using source PCH from: ") + std::string(MayaFlux::Config::PCH_SOURCE_PATH));
95
96 } else {
97 m_last_error = "Cannot find pch.h in runtime or source locations";
98 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
99 return false;
100 }
101
102 m_impl->compile_flags.push_back("-I" + pch_dir);
103
104 const std::string& resource_dir = MayaFlux::Platform::SystemConfig::get_clang_resource_dir();
105 if (!resource_dir.empty()) {
106 m_impl->compile_flags.push_back("-resource-dir=" + resource_dir);
107 LILA_DEBUG(Emitter::INTERPRETER,
108 std::string("Using clang resource dir: ") + resource_dir);
109 } else {
110 m_impl->compile_flags.emplace_back("-resource-dir=/usr/lib/clang/21");
111 LILA_WARN(Emitter::INTERPRETER,
112 "Using default clang resource dir: /usr/lib/clang/21");
113 }
114
115 const auto& system_includes = MayaFlux::Platform::SystemConfig::get_system_includes();
116 for (const auto& include : system_includes) {
117 m_impl->compile_flags.push_back("-isystem" + include);
118 }
119
120#ifndef MAYAFLUX_PLATFORM_WINDOWS
121 const auto& eigen_include = MayaFlux::Platform::SystemConfig::get_dep_includes("eigen");
122 if (!eigen_include.empty()) {
123 m_impl->compile_flags.push_back("-isystem" + eigen_include);
124 LILA_DEBUG(Emitter::INTERPRETER,
125 std::string("Added Eigen include path: ") + eigen_include);
126 } else {
127 LILA_WARN(Emitter::INTERPRETER,
128 "Could not find Eigen include path - some features may not work");
129 }
130
131 const auto& freetype_include = MayaFlux::Platform::SystemConfig::get_dep_includes("freetype2");
132 if (!freetype_include.empty()) {
133 m_impl->compile_flags.push_back("-isystem" + freetype_include);
134 LILA_DEBUG(Emitter::INTERPRETER,
135 std::string("Added FreeType include path: ") + freetype_include);
136 } else {
137 LILA_WARN(Emitter::INTERPRETER,
138 "Could not find FreeType include path - some features may not work");
139 }
140#endif
141
142 const std::string magic_enum_include = std::string(MayaFlux::Config::MAGIC_ENUM_INCLUDE);
143 if (!magic_enum_include.empty()) {
144 m_impl->compile_flags.push_back("-I" + magic_enum_include);
145 LILA_DEBUG(Emitter::INTERPRETER,
146 std::string("Added magic_enum include path: ") + magic_enum_include);
147 } else {
148 LILA_WARN(Emitter::INTERPRETER,
149 "Could not find magic_enum include path - some features may not work");
150 }
151
152#ifdef MAYAFLUX_PLATFORM_MACOS
153 // CRITICAL: JIT uses Homebrew LLVM but needs macOS SDK for system headers
154 // Homebrew LLVM's libc++ requires pthread.h, sched.h, time.h, etc. from SDK
155 std::string sdk_path = MayaFlux::Platform::SystemConfig::get_macos_sdk_path();
156 if (!sdk_path.empty()) {
157 m_impl->compile_flags.push_back("-isysroot" + sdk_path);
158 LILA_DEBUG(Emitter::INTERPRETER, "Using macOS SDK: " + sdk_path);
159 } else {
160 LILA_WARN(Emitter::INTERPRETER,
161 "Could not find macOS SDK - JIT may fail to find system headers");
162 }
163 m_impl->compile_flags.emplace_back("-fexperimental-library");
164#endif
165
166 for (const auto& path : m_impl->include_paths) {
167 m_impl->compile_flags.push_back("-I" + path);
168 }
169
170#ifdef MAYAFLUX_PLATFORM_WINDOWS
171 m_impl->compile_flags.emplace_back("-fno-function-sections");
172 m_impl->compile_flags.emplace_back("-fno-data-sections");
173 m_impl->compile_flags.emplace_back("-fno-unique-section-names");
174 m_impl->compile_flags.emplace_back("-D_CRT_SECURE_NO_WARNINGS");
175#endif
176
177 std::vector<const char*> args;
178 for (const auto& flag : m_impl->compile_flags) {
179 args.push_back(flag.c_str());
180 }
181
182 clang::IncrementalCompilerBuilder ICB;
183 ICB.SetCompilerArgs(args);
184
185 auto CI = ICB.CreateCpp();
186 if (!CI) {
187 m_last_error = "Failed to create CompilerInstance: " + llvm::toString(CI.takeError());
188 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
189 return false;
190 }
191
192 auto interp = clang::Interpreter::create(std::move(*CI));
193 if (!interp) {
194 m_last_error = "Failed to create interpreter: " + llvm::toString(interp.takeError());
195 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
196 return false;
197 }
198
199 m_impl->interpreter = std::move(*interp);
200
201 LILA_INFO(Emitter::INTERPRETER, "Clang interpreter created successfully");
202
203 if (skip_host_library_load) {
204 LILA_DEBUG(Emitter::INTERPRETER,
205 "Skipping MayaFluxLib load: host process already resident");
206 } else {
208 "MayaFluxLib", std::string(MayaFlux::Config::INSTALL_PREFIX));
209
210 LILA_DEBUG(Emitter::INTERPRETER, "Loading MayaFlux library: " + lib_to_load);
211
212 if (auto err = m_impl->interpreter->LoadDynamicLibrary(lib_to_load.c_str())) {
213 m_last_error = "Failed to load " + lib_to_load + ": "
214 + llvm::toString(std::move(err));
215 LILA_ERROR(Emitter::INTERPRETER, m_last_error);
216 return false;
217 }
218
219 LILA_DEBUG(Emitter::INTERPRETER, "Loaded " + lib_to_load);
220 }
221
222 const char* header_include = "#include \"pch.h\"\n"
223 "#include \"MayaFlux/MayaFlux.hpp\"\n";
224
225 auto result = m_impl->interpreter->ParseAndExecute(header_include);
226
227 if (result) {
228 std::string warning = "Failed to load MayaFlux headers: " + llvm::toString(std::move(result));
229 LILA_WARN(Emitter::INTERPRETER, warning);
230 } else {
231 LILA_INFO(Emitter::INTERPRETER, "MayaFlux headers loaded successfully");
232 }
233
234 result = m_impl->interpreter->ParseAndExecute("std::cout << \"Ready for Live\" << std::flush;");
235
236 return true;
237}
#define LILA_WARN(emitter, msg)
#define LILA_ERROR(emitter, msg)
#define LILA_DEBUG(emitter, msg)
#define LILA_INFO(emitter, msg)
std::unique_ptr< Impl > m_impl
Internal implementation details.
static const std::string & get_clang_resource_dir()
static const std::string & find_dep_library(const std::string &library_name, const std::string &prefix="")
static const std::string & get_dep_includes(const std::string &library_name)
static const std::vector< std::string > & get_system_includes()

References MayaFlux::Platform::SystemConfig::find_dep_library(), MayaFlux::Platform::SystemConfig::get_clang_resource_dir(), MayaFlux::Platform::SystemConfig::get_dep_includes(), MayaFlux::Platform::SystemConfig::get_system_includes(), LILA_DEBUG, LILA_ERROR, LILA_INFO, and LILA_WARN.

+ Here is the call graph for this function: