Loading...
Searching...
No Matches
JitPlatform.hpp
1#pragma once
2#include <Library/LibrarySettings.hpp>
3
4#include <score/application/ApplicationContext.hpp>
5
6#include <QCoreApplication>
7#include <QDebug>
8#include <QDir>
9#include <QDirIterator>
10#include <QFileInfo>
11#include <QStringList>
12
13#include <llvm/ADT/StringMap.h>
14#include <llvm/ADT/StringRef.h>
15
16#if LLVM_VERSION_MAJOR >= 17
17#include <llvm/TargetParser/Host.h>
18#include <llvm/TargetParser/Triple.h>
19#else
20#include <llvm/Support/Host.h>
21#endif
22
23#include <iostream>
24#include <stdexcept>
25#include <string>
26#include <vector>
27#include <version>
28#if __has_include(<llvm/Config/llvm-config-64.h>)
29#include <llvm/Config/llvm-config-64.h>
30#elif __has_include(<llvm/Config/llvm-config.h>)
31#include <llvm/Config/llvm-config.h>
32#endif
33
34#if defined(__has_feature)
35#if __has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__)
36#define __SANITIZE_ADDRESS__ 1
37#endif
38#endif
39
40#if defined(SCORE_FHS_BUILD)
41#define SCORE_USE_DISTRO_SYSROOT 1
42#else
43#if defined(SCORE_DEPLOYMENT_BUILD)
44#define SCORE_USE_DISTRO_SYSROOT 0
45#else
46#define SCORE_USE_DISTRO_SYSROOT 1
47#endif
48#endif
49
50#include <JitCpp/JitOptions.hpp>
51
52#include <score_git_info.hpp>
53
54namespace Jit
55{
56
57static inline std::string locateSDK()
58{
59 if(QString sdk = qgetenv("SCORE_JIT_SDK"); !sdk.isEmpty())
60 return sdk.toStdString();
61
62 auto& ctx = score::AppContext().settings<Library::Settings::Model>();
63 QString path = ctx.getSDKPath();
64
65 if(QString libPath = QStringLiteral("%1/%2/usr").arg(path).arg(SCORE_TAG_NO_V);
66 QDir(libPath + "/include/c++").exists())
67 {
68 return libPath.toStdString();
69 }
70
71 if(QString libPath = path + "/usr"; QDir(libPath + "/include/c++").exists())
72 {
73 return libPath.toStdString();
74 }
75
76 auto appFolder = QCoreApplication::instance()->applicationDirPath();
77
78#if !SCORE_FHS_BUILD
79
80#if defined(_WIN32)
81 {
82 QDir d{appFolder};
83 d.cd("sdk");
84 return d.absolutePath().toStdString();
85 }
86#elif defined(__linux__)
87 {
88 QDir d{appFolder};
89 d.cdUp();
90 d.cd("usr");
91 return d.absolutePath().toStdString();
92 }
93#elif defined(__APPLE__)
94 {
95 QDir d{appFolder};
96 d.cdUp();
97 if(d.cd("Frameworks"))
98 {
99 if(d.cd("Score.Framework"))
100 {
101 return d.absolutePath().toStdString();
102 }
103 }
104 auto framework = QString(appFolder + "/Score.Framework");
105 if(QDir{}.exists(framework))
106 return framework.toStdString();
107 else
108 return "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/"
109 "Developer/SDKs/MacOSX.sdk/usr";
110 }
111#endif
112
113#else
114#if defined(__APPLE__)
115 return "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/"
116 "Developer/SDKs/MacOSX.sdk/usr";
117#endif
118 if(QFileInfo("/usr/include/c++").isDir())
119 {
120 return "/usr";
121 }
122 else
123 {
124 return ctx.getSDKPath().toStdString();
125 }
126#endif
127}
128
130{
131 std::string path;
132 enum
133 {
134 none, // Nothing was found
135 platform, // Building against /usr/include, useful for dev builds
136 official // The SDK obtained from official score releases
137 } sdk_kind
138 = none;
139
140// Do we use the score source dir or the headers from the SDK
141#if !SCORE_FHS_BUILD
142 static constexpr bool deploying = true;
143#else
144 static constexpr bool deploying = false;
145#endif
146};
147
148inline located_sdk locateSDKWithFallback()
149{
150 located_sdk ret;
151 ret.path = locateSDK();
152 if(ret.path.empty())
153 ret.sdk_kind = located_sdk::none;
154 if(ret.path.starts_with("/usr") || ret.path.starts_with("/Applications"))
155 ret.sdk_kind = located_sdk::official;
156 else
157 ret.sdk_kind = located_sdk::platform;
158
159 // An explicitly-provided or relocatable SDK (SCORE_JIT_SDK, an AppImage / .app
160 // bundle) can live outside /usr; trust it as official when it actually ships the
161 // deployed score files the addon compiler needs, otherwise prototype and include
162 // resolution wrongly falls back to the build-time source tree (absent at runtime).
163 if(ret.sdk_kind == located_sdk::platform
164 && QDir(QString::fromStdString(ret.path)).exists("lib/cmake/score/prototype.cpp.in"))
165 ret.sdk_kind = located_sdk::official;
166
167 {
168 QDir dir(QString::fromStdString(ret.path));
169 if(!dir.exists())
170 ret.sdk_kind = located_sdk::none;
171
172 if(!dir.cd("include") || !dir.cd("c++"))
173 {
174#if defined(SCORE_DEPLOYMENT_BUILD)
175 // A released score is built with the SDK's compiler and standard
176 // library: code compiled against the system's headers would not match
177 // the process it is loaded in.
178 qDebug() << "JIT: no score SDK in" << QString::fromStdString(ret.path);
179 ret.path.clear();
180 ret.sdk_kind = located_sdk::none;
181 return ret;
182#endif
183 qDebug() << "Unable to locate standard headers, fallback to /usr";
184 ret.path = "/usr";
185 dir.setPath("/usr");
186 if(!dir.cd("include") || !dir.cd("c++"))
187 {
188 qDebug() << "Unable to locate any standard headers, install C++ development "
189 "toolchain";
190 throw std::runtime_error("Unable to compile");
191 }
192 ret.sdk_kind = located_sdk::platform;
193 }
194 }
195 return ret;
196}
197
198// Locate the SDK's LLVM ORC runtime archive (compiler-rt orc_rt), if shipped.
199// The native ExecutorNativePlatform loads it into the executor to provide native
200// TLS, static-init/atexit scheduling and (COFF) exception-table registration.
201// Name and location vary per platform (liborc_rt.a / liborc_rt_osx.a /
202// liborc_rt-x86_64.a, under llvm/ or llvm-libs/), so search a few candidate roots
203// rather than hard-coding. Returns "" when absent (e.g. Windows-arm64, or an SDK
204// built before orc_rt was shipped) -- callers then keep the non-platform path.
205static inline std::string locateOrcRuntime()
206{
207 if(QString p = qgetenv("SCORE_JIT_ORC_RUNTIME"); !p.isEmpty())
208 return p.toStdString();
209
210 auto sdk = locateSDKWithFallback();
211 if(sdk.path.empty())
212 return {};
213
214 const QString base = QString::fromStdString(sdk.path);
215 const QString parent = QFileInfo(base).absolutePath();
216 const QStringList roots{base, parent,
217 parent + "/llvm", parent + "/llvm-libs",
218 base + "/llvm", base + "/llvm-libs"};
219 for(const QString& root : roots)
220 {
221 // orc_rt lives under the clang resource dir: <root>/lib/clang/<v>/lib/<t>/.
222 const QString clangLibs = root + "/lib/clang";
223 if(!QDir(clangLibs).exists())
224 continue;
225 QDirIterator it(
226 clangLibs, {"liborc_rt*.a"}, QDir::Files, QDirIterator::Subdirectories);
227 if(it.hasNext())
228 return it.next().toStdString();
229 }
230 return {};
231}
232
233// Locate compiler-rt's builtins archive (libclang_rt.builtins-<arch>.a). clang's driver
234// links it via -rtlib=compiler-rt; the JIT compiles with bare -cc1 (no driver), so
235// builtins such as __udivti3 (128-bit integer division, pulled by fmt and others)
236// are otherwise unresolved. We hand it to ORC as a definition generator. Same
237// search roots as locateOrcRuntime (it lives in the same clang resource dir);
238// prefer the COFF/windows variant. Returns "" when absent.
239static inline std::string locateBuiltinsRuntime()
240{
241 if(QString p = qgetenv("SCORE_JIT_BUILTINS"); !p.isEmpty())
242 return p.toStdString();
243
244 auto sdk = locateSDKWithFallback();
245 if(sdk.path.empty())
246 return {};
247
248 const QString base = QString::fromStdString(sdk.path);
249 const QString parent = QFileInfo(base).absolutePath();
250 const QStringList roots{base, parent,
251 parent + "/llvm", parent + "/llvm-libs",
252 base + "/llvm", base + "/llvm-libs"};
253 const llvm::Triple host{llvm::sys::getProcessTriple()};
254 const QString archive = QString::fromStdString(
255 "libclang_rt.builtins-" + llvm::Triple::getArchTypeName(host.getArch()).str()
256 + ".a");
257 QString fallback;
258 for(const QString& root : roots)
259 {
260 const QString clangLibs = root + "/lib/clang";
261 if(!QDir(clangLibs).exists())
262 continue;
263 QDirIterator it(clangLibs, {archive}, QDir::Files, QDirIterator::Subdirectories);
264 while(it.hasNext())
265 {
266 const QString f = it.next();
267 if(f.contains("/windows/") || f.contains("\\windows\\"))
268 return f.toStdString(); // prefer the COFF/windows variant
269 if(fallback.isEmpty())
270 fallback = f;
271 }
272 }
273 return fallback.toStdString();
274}
275
276// Locates a mingw-w64 CRT-support archive (libmingwex.a, libucrt.a, ...) that
277// the driver links implicitly into every mingw executable but the JIT's bare
278// -cc1 compile does not. libmingwex supplies the C99-name math functions the
279// UCRT only exports under their underscore names (e.g. hypotf wraps _hypot)
280// plus routines the CRT lacks entirely; libucrt's alias objects supply the
281// POSIX old names (fileno -> _fileno) and renamed imports (__msvcrt_assert).
282static inline std::string locateMingwRuntimeLib(const char* env, const char* name)
283{
284 if(QString p = qgetenv(env); !p.isEmpty())
285 return p.toStdString();
286
287 auto sdk = locateSDKWithFallback();
288 if(sdk.path.empty())
289 return {};
290
291 const QString base = QString::fromStdString(sdk.path);
292 const QString parent = QFileInfo(base).absolutePath();
293 const QStringList roots{base, parent,
294 parent + "/llvm", parent + "/llvm-libs",
295 base + "/llvm", base + "/llvm-libs"};
296 const QString lib = QString::fromUtf8(name);
297 for(const QString& root : roots)
298 {
299 // Shipped runtime SDK layout (create-sdk-mingw.sh) and toolchain layout.
300 for(const QString& p :
301 {QString(root + "/lib/" + lib),
302 QString(root + "/x86_64-w64-mingw32/lib/" + lib)})
303 if(QFile::exists(p))
304 return p.toStdString();
305 }
306 return {};
307}
308
309static inline std::string locateMingwexRuntime()
310{
311 return locateMingwRuntimeLib("SCORE_JIT_MINGWEX", "libmingwex.a");
312}
313
314static inline std::string locateUcrtImportLib()
315{
316 return locateMingwRuntimeLib("SCORE_JIT_UCRT", "libucrt.a");
317}
318
319static inline void
320populateCompileOptions(std::vector<std::string>& args, CompilerOptions opts)
321{
322 args.push_back("-triple");
323 const std::string processTriple = llvm::sys::getProcessTriple();
324 args.push_back(processTriple);
325
326 // On Windows/COFF the JIT maps the add-on at a high address (the reserved slab)
327 // and must reference far host symbols -- libc++abi RTTI vtables and the EH
328 // personality among them. The small (default) code model emits 32-bit
329 // relocations that truncate at that address, corrupting vtables / type_info and
330 // crashing __dynamic_cast (notably multiple-inheritance / cross-casts during
331 // plugin registration). The large code model uses 64-bit references throughout.
332 // (The JIT TargetMachine also requests Large, but this cc1 module flag is the
333 // authoritative one that actually reaches code generation.)
334 if(llvm::Triple(processTriple).isOSBinFormatCOFF())
335 {
336 args.push_back("-mcmodel=large");
337
338 // Mirror the target flags clang's *driver* injects for x86_64-w64-windows-gnu
339 // that this bare -cc1 invocation would otherwise miss. Without them the add-on
340 // is compiled differently from how score itself was built (score goes through
341 // the driver + bin/*.cfg), which is what makes host symbols fail to resolve:
342 // -D_UCRT select the Universal CRT, so printf/fprintf bind to the
343 // UCRT (__stdio_common_vfprintf -- which score imports)
344 // instead of legacy-msvcrt mingw ANSI stdio
345 // (__mingw_printf / __mingw_fprintf, absent from score).
346 // -fno-use-init-array COFF static ctors emit into .ctors (which
347 // MinGWCOFFPlatform collects), not .init_array.
348 // -funwind-tables=2 / -fno-sized-deallocation match the driver's SEH
349 // unwind-table emission and operator-delete ABI.
350 args.push_back("-D_UCRT");
351 // The JIT unconditionally passes -D_GNU_SOURCE=1 (below) for POSIX features on
352 // Linux add-ons; score itself does not define it. On mingw, _GNU_SOURCE flips
353 // __USE_MINGW_ANSI_STDIO to 1 (an independent term of that decision, so _UCRT
354 // alone doesn't undo it), which routes printf/fprintf to legacy-msvcrt
355 // __mingw_printf / __mingw_fprintf -- symbols score (UCRT) doesn't contain.
356 // Force the UCRT stdio path so the add-on binds the same printf family score
357 // does (__stdio_common_vfprintf), resolvable from the host process.
358 args.push_back("-D__USE_MINGW_ANSI_STDIO=0");
359 args.push_back("-fno-use-init-array");
360 args.push_back("-funwind-tables=2");
361 args.push_back("-fno-sized-deallocation");
362 }
363
364 args.push_back("-target-cpu");
365 args.push_back(llvm::sys::getHostCPUName().lower());
366
367 {
368 llvm::StringMap<bool> HostFeatures;
369#if LLVM_VERSION_MAJOR < 19
370 bool ok = llvm::sys::getHostCPUFeatures(HostFeatures);
371#else
372 constexpr bool ok = true;
373 HostFeatures = llvm::sys::getHostCPUFeatures();
374#endif
375 if(ok)
376 {
377 for(const llvm::StringMapEntry<bool>& F : HostFeatures)
378 {
379 args.push_back("-target-feature");
380 args.push_back((F.second ? "+" : "-") + F.first().str());
381 }
382 }
383 }
384
385 // Match the dialect score itself is built with (gnu++23, not strict c++23):
386 // avnd/halp/ossia rely on GNU extensions (anonymous structs/unions, etc.) that
387 // strict -std=c++23 (__STRICT_ANSI__) rejects or types differently, which makes
388 // some nodes that build fine in score fail to compile in the JIT (e.g. curve
389 // controls: the curve_segment concept then isn't satisfied and make_segment has
390 // no viable overload).
391 args.push_back("-std=gnu++23");
392 args.push_back("-disable-free");
393 args.push_back("-fdeprecated-macro");
394 args.push_back("-fmath-errno");
395 // disappeared in clang 11 args.push_back("-fuse-init-array");
396
397 // args.push_back("-mrelocation-model");
398 // args.push_back("static");
399 args.push_back("-mthread-model");
400 args.push_back("posix");
401 // disappeared in clang 11 args.push_back("-masm-verbose");
402 args.push_back("-mconstructor-aliases");
403
404 // args.push_back("-dwarf-column-info");
405 // args.push_back("-debugger-tuning=gdb");
406
407 args.push_back("-fno-use-cxa-atexit");
408
409 // -Ofast stuff:
410 // args.push_back("-menable-unsafe-fp-math");
411 args.push_back("-fno-signed-zeros");
412 args.push_back("-mreassociate");
413 args.push_back("-freciprocal-math");
414 args.push_back("-fno-rounding-math");
415
416 // disappeared in clang 12 args.push_back("-fno-trapping-math");
417 args.push_back("-ffp-contract=fast");
418
419#if !defined(__linux__) // || (defined(__linux__) && __GLIBC_MINOR__ >= 31)
420 // isn't that great
421 // https://reviews.llvm.org/D74712
422 args.push_back("-Ofast");
423 args.push_back("-menable-no-infs");
424 args.push_back("-menable-no-nans");
425 args.push_back("-ffinite-math-only");
426 args.push_back("-ffast-math");
427#else
428 args.push_back("-O3");
429 args.push_back("-fno-builtin");
430#endif
431
432 // Prevent emitting ___chkstk_ms calls in alloca
433 args.push_back("-mno-stack-arg-probe");
434
435 args.push_back("-fgnuc-version=4.2.1");
436
437#if defined(__APPLE__)
438 args.push_back("-fmax-type-align=16");
439
440 // Apple framework headers (CoreGraphics, ImageIO, Metadata, ...) declare
441 // block-typed parameters (`void (^)(...)`), the Apple "blocks" extension. The
442 // JIT pulls them in transitively, so enable blocks or every such declaration is
443 // a hard error ("blocks support disabled - compile with -fblocks"). We only
444 // parse these signatures; the add-on does not invoke them, so no blocks runtime
445 // is needed.
446 args.push_back("-fblocks");
447
448 // Apple's CoreFoundation CF_ENUM / CF_OPTIONS macros expand (when the fixed
449 // underlying type is available, as in C++) to a non-defining fixed-underlying-
450 // type enum embedded in a typedef, e.g. `typedef enum E : long E; enum E : long
451 // {...};`. That form is only valid in Objective-C(++) where objc_fixed_enum is
452 // a feature; in plain C++23 clang rejects it as -Welaborated-enum-base. The JIT
453 // compiles the addon as C++ but pulls these headers in transitively (Qt, ossia),
454 // so accept the Apple idiom as the extension it is. clang still assigns the enum
455 // its correct fixed-type values.
456 args.push_back("-Wno-elaborated-enum-base");
457#endif
458 args.push_back("-mrelocation-model");
459 args.push_back("pic");
460 args.push_back("-pic-level");
461 args.push_back("2");
462 //args.push_back("-pic-is-pie");
463
464 // changed from -fvisibility hidden to -fvisibility=hidden in clang 16
465 args.push_back("-fvisibility=hidden");
466
467 args.push_back("-fvisibility-inlines-hidden");
468
469 // TLS: when an Orc Platform (orc_rt) drives the executor we get *native*
470 // thread-locals on every target, and TargetOptions.EmulatedTLS is set false
471 // (see Compiler.cpp). In that case we must NOT force emulated TLS here: codegen
472 // would emit __emutls_* references the platform does not provide. Only request
473 // emulated/local-exec TLS on the legacy (no-orc_rt) path. This mirrors
474 // useNativePlatform in Compiler.cpp (same locateOrcRuntime() result).
475#if LLVM_VERSION_MAJOR >= 22
476 const bool useNativePlatform = !locateOrcRuntime().empty();
477#else
478 const bool useNativePlatform = false;
479#endif
480 // COFF has no JIT-usable native TLS (no _tls_index / .tls directory), so force
481 // emulated TLS there even with the platform on -- matching TargetOptions in
482 // Compiler.cpp. __emutls_get_address resolves from the compiler-rt builtins
483 // archive in the add-on link order.
484 // Must agree with TargetOptions::EmulatedTLS in Compiler.cpp.
485 if(!useNativePlatform || !llvm::Triple(processTriple).isOSBinFormatMachO())
486 {
487 args.push_back("-ftls-model=local-exec");
488 args.push_back("-femulated-tls");
489 }
490 else
491 {
492 // A hidden thread_local cannot be preempted, so clang picks local-exec for it
493 // even at PIC level 2, emitting an offset into the initial TLS block that
494 // JIT-loaded code is not in. One such variable fails the whole add-on.
495 args.push_back("-ftls-model=global-dynamic");
496 }
497
498 // if fsanitize:
499 args.push_back("-mrelax-all");
500 args.push_back("-disable-llvm-verifier");
501 args.push_back("-discard-value-names");
502#if defined(__SANITIZE_ADDRESS__)
503 /*
504
505 args.push_back(
506 "-fsanitize=address,alignment,array-bounds,bool,builtin,enum,float-cast-"
507 "overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-"
508 "attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-"
509 "base,shift-exponent,signed-integer-overflow,unreachable,vla-bound,vptr,"
510 "unsigned-integer-overflow,implicit-integer-truncation");
511 args.push_back(
512 "-fsanitize-recover=alignment,array-bounds,bool,builtin,enum,float-cast-"
513 "overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-"
514 "attribute,null,pointer-overflow,returns-nonnull-attribute,shift-base,"
515 "shift-exponent,signed-integer-overflow,vla-bound,vptr,unsigned-integer-"
516 "overflow,implicit-integer-truncation");
517 args.push_back(
518 "-fsanitize-blacklist=/usr/lib/clang/7.0.0/share/asan_blacklist.txt");
519 args.push_back("-fsanitize-address-use-after-scope");
520 args.push_back("-mdisable-fp-elim");
521 */
522#endif
523 args.push_back("-fno-assume-sane-operator-new");
524 // args.push_back("-fcoroutines-ts");
525 args.push_back("-stack-protector");
526 args.push_back("0");
527 if(opts.NoExceptions)
528 {
529 args.push_back("-fno-rtti");
530 }
531 else
532 {
533#if LLVM_VERSION_MAJOR <= 13
534 args.push_back("-munwind-tables");
535#endif
536
537 args.push_back("-fcxx-exceptions");
538 args.push_back("-fexceptions");
539 args.push_back("-fexternc-nounwind");
540#if defined(_WIN32)
541 args.push_back("-exception-model=seh");
542#endif
543 }
544 args.push_back("-faddrsig");
545
546 // args.push_back("-momit-leaf-frame-pointer");
547 args.push_back("-vectorize-loops");
548 args.push_back("-vectorize-slp");
549}
550
551static inline void populateDefinitions(std::vector<std::string>& args)
552{
553#if defined(__APPLE__)
554 // needed because otherwise readerwriterqueue includes CoreFoundation.h ...
555 args.push_back("-DMOODYCAMEL_MAYBE_ALIGN_TO_CACHELINE=");
556#endif
557#define XSTR(s) STR(s)
558#define STR(s) #s
559
560#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
561 args.push_back("-DBOOST_ASIO_ENABLE_BUFFER_DEBUGGING");
562#endif
563#if defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
564 args.push_back(
565 "-DBOOST_ASIO_HAS_STD_INVOKE_RESULT=" XSTR(BOOST_ASIO_HAS_STD_INVOKE_RESULT));
566#endif
567#if defined(BOOST_MATH_DISABLE_FLOAT128)
568 args.push_back("-DBOOST_MATH_DISABLE_FLOAT128=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
569#endif
570#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
571 args.push_back("-DBOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING");
572#endif
573#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
574 args.push_back("-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE");
575#endif
576#if defined(BOOST_NO_RTTI)
577 args.push_back("-DBOOST_NO_RTTI=" XSTR(BOOST_NO_RTTI));
578#endif
579#if defined(FMT_SHARED)
580 args.push_back("-DFMT_SHARED=" XSTR(FMT_SHARED));
581#endif
582 // score/libossia link fmt as header-only in deployment builds (see
583 // libossia/cmake/deps/fmt.cmake), so fmt's functions are inlined into score and
584 // no fmt archive/symbols are exported. An add-on compiled WITHOUT
585 // FMT_HEADER_ONLY emits external references (e.g. fmt::vprint) that the host
586 // cannot resolve -- JIT load then fails with "Symbols not found: fmt::...".
587 // Propagate the same mode score itself was built with so the add-on inlines fmt.
588#if defined(FMT_HEADER_ONLY)
589 args.push_back("-DFMT_HEADER_ONLY=" XSTR(FMT_HEADER_ONLY));
590#endif
591#if defined(FMT_STATIC_THOUSANDS_SEPARATOR)
592 args.push_back(
593 "-DFMT_STATIC_THOUSANDS_SEPARATOR=" XSTR(FMT_STATIC_THOUSANDS_SEPARATOR));
594#endif
595#if defined(FMT_USE_FLOAT128)
596 args.push_back("-DFMT_USE_FLOAT128=" XSTR(FMT_USE_FLOAT128));
597#endif
598#if defined(FMT_USE_INT128)
599 args.push_back("-DFMT_USE_INT128=" XSTR(FMT_USE_INT128));
600#endif
601#if defined(FMT_USE_LONG_DOUBLE)
602 args.push_back("-DFMT_USE_LONG_DOUBLE=" XSTR(FMT_USE_LONG_DOUBLE));
603#endif
604#if defined(LIBREMIDI_ALSA)
605 args.push_back("-DLIBREMIDI_ALSA");
606#endif
607#if defined(LIBREMIDI_HAS_JACK_GET_VERSION)
608 args.push_back("-DLIBREMIDI_HAS_JACK_GET_VERSION");
609#endif
610#if defined(LIBREMIDI_HAS_UDEV)
611 args.push_back("-DLIBREMIDI_HAS_UDEV");
612#endif
613#if defined(LIBREMIDI_JACK)
614 args.push_back("-DLIBREMIDI_JACK");
615#endif
616#if defined(LIBREMIDI_KEYBOARD)
617 args.push_back("-DLIBREMIDI_KEYBOARD");
618#endif
619#if defined(LIBREMIDI_PIPEWIRE)
620 args.push_back("-DLIBREMIDI_PIPEWIRE");
621#endif
622#if defined(LIBREMIDI_PIPEWIRE_UMP)
623 args.push_back("-DLIBREMIDI_PIPEWIRE_UMP");
624#endif
625#if defined(LIBREMIDI_USE_BOOST)
626 args.push_back("-DLIBREMIDI_USE_BOOST");
627#endif
628#if defined(LIBREMIDI_WEAKJACK)
629 args.push_back("-DLIBREMIDI_WEAKJACK");
630#endif
631#if defined(QT_CORE_LIB)
632 args.push_back("-DQT_CORE_LIB");
633#endif
634#if defined(QT_DISABLE_DEPRECATED_BEFORE)
635 args.push_back("-DQT_DISABLE_DEPRECATED_BEFORE=" XSTR(QT_DISABLE_DEPRECATED_BEFORE));
636#endif
637#if defined(QT_GUI_LIB)
638 args.push_back("-DQT_GUI_LIB");
639#endif
640#if defined(QT_NETWORK_LIB)
641 args.push_back("-DQT_NETWORK_LIB");
642#endif
643#if defined(QT_NO_JAVA_STYLE_ITERATORS)
644 args.push_back("-DQT_NO_JAVA_STYLE_ITERATORS");
645#endif
646#if defined(QT_NO_KEYWORDS)
647 args.push_back("-DQT_NO_KEYWORDS");
648#endif
649#if defined(QT_NO_LINKED_LIST)
650 args.push_back("-DQT_NO_LINKED_LIST");
651#endif
652#if defined(QT_NO_NARROWING_CONVERSIONS_IN_CONNECT)
653 args.push_back("-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT");
654#endif
655#if defined(QT_NO_USING_NAMESPACE)
656 args.push_back("-DQT_NO_USING_NAMESPACE");
657#endif
658#if defined(QT_OPENGL_LIB)
659 args.push_back("-DQT_OPENGL_LIB");
660#endif
661#if defined(QT_QMLINTEGRATION_LIB)
662 args.push_back("-DQT_QMLINTEGRATION_LIB");
663#endif
664#if defined(QT_QML_LIB)
665 args.push_back("-DQT_QML_LIB");
666#endif
667#if defined(QT_SERIALPORT_LIB)
668 args.push_back("-DQT_SERIALPORT_LIB");
669#endif
670#if defined(QT_SHADERTOOLS_LIB)
671 args.push_back("-DQT_SHADERTOOLS_LIB");
672#endif
673#if defined(QT_STATEMACHINE_LIB)
674 args.push_back("-DQT_STATEMACHINE_LIB");
675#endif
676#if defined(QT_USE_QSTRINGBUILDER)
677 args.push_back("-DQT_USE_QSTRINGBUILDER");
678#endif
679#if defined(QT_WEBSOCKETS_LIB)
680 args.push_back("-DQT_WEBSOCKETS_LIB");
681#endif
682#if defined(QT_WIDGETS_LIB)
683 args.push_back("-DQT_WIDGETS_LIB");
684#endif
685#if defined(RAPIDJSON_HAS_STDSTRING)
686 args.push_back("-DRAPIDJSON_HAS_STDSTRING=" XSTR(RAPIDJSON_HAS_STDSTRING));
687#endif
688#if defined(SCORE_DEBUG)
689 args.push_back("-DSCORE_DEBUG");
690#endif
691#if defined(SCORE_LIB_BASE)
692 args.push_back("-DSCORE_LIB_BASE");
693#endif
694#if defined(SCORE_LIB_DEVICE)
695 args.push_back("-DSCORE_LIB_DEVICE");
696#endif
697#if defined(SCORE_LIB_INSPECTOR)
698 args.push_back("-DSCORE_LIB_INSPECTOR");
699#endif
700#if defined(SCORE_LIB_LOCALTREE)
701 args.push_back("-DSCORE_LIB_LOCALTREE");
702#endif
703#if defined(SCORE_LIB_PROCESS)
704 args.push_back("-DSCORE_LIB_PROCESS");
705#endif
706#if defined(SCORE_LIB_STATE)
707 args.push_back("-DSCORE_LIB_STATE");
708#endif
709#if defined(SCORE_PLUGIN_AUDIO)
710 args.push_back("-DSCORE_PLUGIN_AUDIO");
711#endif
712#if defined(SCORE_PLUGIN_AUTOMATION)
713 args.push_back("-DSCORE_PLUGIN_AUTOMATION");
714#endif
715#if defined(SCORE_PLUGIN_AVND)
716 args.push_back("-DSCORE_PLUGIN_AVND");
717#endif
718#if defined(SCORE_PLUGIN_CURVE)
719 args.push_back("-DSCORE_PLUGIN_CURVE");
720#endif
721#if defined(SCORE_PLUGIN_DATAFLOW)
722 args.push_back("-DSCORE_PLUGIN_DATAFLOW");
723#endif
724#if defined(SCORE_PLUGIN_DEVICEEXPLORER)
725 args.push_back("-DSCORE_PLUGIN_DEVICEEXPLORER");
726#endif
727#if defined(SCORE_PLUGIN_ENGINE)
728 args.push_back("-DSCORE_PLUGIN_ENGINE");
729#endif
730#if defined(SCORE_PLUGIN_GFX)
731 args.push_back("-DSCORE_PLUGIN_GFX");
732#endif
733#if defined(SCORE_PLUGIN_LIBRARY)
734 args.push_back("-DSCORE_PLUGIN_LIBRARY");
735#endif
736#if defined(SCORE_PLUGIN_MEDIA)
737 args.push_back("-DSCORE_PLUGIN_MEDIA");
738#endif
739#if defined(SCORE_PLUGIN_SCENARIO)
740 args.push_back("-DSCORE_PLUGIN_SCENARIO");
741#endif
742#if defined(SCORE_PLUGIN_TRANSPORT)
743 args.push_back("-DSCORE_PLUGIN_TRANSPORT");
744#endif
745#if defined(SERVUS_USE_AVAHI_CLIENT)
746 args.push_back("-DSERVUS_USE_AVAHI_CLIENT");
747#endif
748#if defined(SPDLOG_COMPILED_LIB)
749 args.push_back("-DSPDLOG_COMPILED_LIB=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
750#endif
751#if defined(SPDLOG_DEBUG_ON)
752 args.push_back("-DSPDLOG_DEBUG_ON=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
753#endif
754#if defined(SPDLOG_FMT_EXTERNAL)
755 args.push_back("-DSPDLOG_FMT_EXTERNAL=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
756#endif
757#if defined(SPDLOG_NO_DATETIME)
758 args.push_back("-DSPDLOG_NO_DATETIME=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
759#endif
760#if defined(SPDLOG_NO_NAME)
761 args.push_back("-DSPDLOG_NO_NAME=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
762#endif
763#if defined(SPDLOG_NO_THREAD_ID)
764 args.push_back("-DSPDLOG_NO_THREAD_ID=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
765#endif
766#if defined(SPDLOG_SHARED_LIB)
767 args.push_back("-DSPDLOG_SHARED_LIB=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
768#endif
769#if defined(SPDLOG_TRACE_ON)
770 args.push_back("-DSPDLOG_TRACE_ON=" XSTR(BOOST_MATH_DISABLE_FLOAT128));
771#endif
772#if defined(TINYSPLINE_DOUBLE_PRECISION)
773 args.push_back("-DTINYSPLINE_DOUBLE_PRECISION");
774#endif
775
776#if defined(SCORE_DEBUG)
777 args.push_back("-DSCORE_DEBUG");
778#endif
779
780 // args.push_back("-DSCORE_STATIC_PLUGINS");
781 args.push_back("-D_GNU_SOURCE=1");
782 args.push_back("-D__STDC_CONSTANT_MACROS");
783 args.push_back("-D__STDC_FORMAT_MACROS");
784 args.push_back("-D__STDC_LIMIT_MACROS");
785#if defined(FFTW_SINGLE_ONLY)
786 args.push_back("-DFFTW_SINGLE_ONLY");
787#elif defined(FFTW_DOUBLE_ONLY)
788 args.push_back("-DFFTW_DOUBLE_ONLY");
789#endif
790}
791
792static inline auto getPotentialTriples()
793{
794 std::vector<QString> triples;
795 triples.push_back(LLVM_DEFAULT_TARGET_TRIPLE);
796 triples.push_back(LLVM_HOST_TRIPLE);
797#if defined(__x86_64__)
798 triples.push_back("x86_64-pc-linux-gnu");
799 triples.push_back("x86_64-unknown-linux-gnu");
800#elif defined(__i686__)
801 triples.push_back("i686-pc-linux-gnu");
802#elif defined(__i586__)
803 triples.push_back("i586-pc-linux-gnu");
804#elif defined(__i486__)
805 triples.push_back("i486-pc-linux-gnu");
806#elif defined(__i386__)
807 triples.push_back("i386-pc-linux-gnu");
808#elif defined(__arm__)
809 triples.push_back("armv8-none-linux-gnueabi");
810 triples.push_back("armv8-pc-linux-gnueabi");
811 triples.push_back("armv8-none-linux-gnu");
812 triples.push_back("armv8-pc-linux-gnu");
813 triples.push_back("armv7-none-linux-gnueabi");
814 triples.push_back("armv7-pc-linux-gnueabi");
815 triples.push_back("armv7-none-linux-gnu");
816 triples.push_back("armv7-pc-linux-gnu");
817 triples.push_back("armv6-none-linux-gnueabi");
818 triples.push_back("armv6-pc-linux-gnueabi");
819 triples.push_back("armv6-none-linux-gnu");
820 triples.push_back("armv6-pc-linux-gnu");
821#elif defined(__aarch64__)
822 triples.push_back("aarch64-none-linux-gnueabi");
823 triples.push_back("aarch64-pc-linux-gnueabi");
824 triples.push_back("aarch64-unknown-linux-gnueabi");
825 triples.push_back("aarch64-none-linux-gnu");
826 triples.push_back("aarch64-pc-linux-gnu");
827 triples.push_back("aarch64-unknown-linux-gnu");
828 triples.push_back("aarch64-redhat-linux");
829#endif
830
831 return triples;
832}
872static inline void populateIncludeDirs(std::vector<std::string>& args)
873{
874 auto sdk_location = locateSDKWithFallback();
875 if(sdk_location.sdk_kind == located_sdk::none)
876 {
877 auto& lib = score::AppContext().settings<Library::Settings::Model>();
878 throw std::runtime_error(
879 QStringLiteral("The score SDK is not installed: C++ cannot be compiled. "
880 "Install it from the package manager, in %1/%2.")
881 .arg(lib.getSDKPath(), QStringLiteral(SCORE_TAG_NO_V))
882 .toStdString());
883 }
884 auto& sdk = sdk_location.path;
885 auto qsdk = QString::fromStdString(sdk);
886
887 qDebug() << "SDK located: " << qsdk;
888 std::string llvm_lib_version = SCORE_LLVM_VERSION;
889#if defined(__APPLE__) && SCORE_FHS_BUILD
890 llvm_lib_version = "13.0.0";
891#endif
892
893 QDir resDir = QString(qsdk + "/lib/clang");
894 auto entries = resDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
895 if(!entries.empty() && !entries.contains(SCORE_LLVM_VERSION))
896 llvm_lib_version = entries.front().toStdString();
897
898#if defined(__APPLE__) && SCORE_FHS_BUILD
899 std::string appleSharedSdk
900 = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/"
901 "usr";
902 args.push_back("-resource-dir");
903 args.push_back(appleSharedSdk + "/lib/clang/" + llvm_lib_version);
904#else
905 args.push_back("-resource-dir");
906 args.push_back(sdk + "/lib/clang/" + llvm_lib_version);
907#endif
908
909#if defined(_LIBCPP_VERSION)
910 args.push_back("-stdlib=libc++");
911 args.push_back("-internal-isystem");
912
913#if defined(__APPLE__) && SCORE_FHS_BUILD
914 args.push_back(appleSharedSdk + "/include/c++/v1");
915#else
916 args.push_back(sdk + "/include/c++/v1");
917#endif
918
919 // libc++'s per-target __config_site lives at include/<triple>/c++/v1 (multiarch
920 // layout) and is #include'd by the main libc++ headers, so that dir must also be
921 // on the search path.
922 {
923 const QDir incdir(qsdk + "/include");
924 for(const auto& d : incdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
925 {
926 if(QFileInfo::exists(qsdk + "/include/" + d + "/c++/v1/__config_site"))
927 {
928 args.push_back("-internal-isystem");
929 args.push_back(sdk + "/include/" + d.toStdString() + "/c++/v1");
930 break;
931 }
932 }
933 }
934
935#elif defined(_GLIBCXX_RELEASE)
936 // Try to locate the correct libstdc++ folder
937 // TODO these are only heuristics. how to make them better ?
938 {
939 const auto libstdcpp_major = QString::number(_GLIBCXX_RELEASE);
940
941 QDir cpp_dir{"/usr/include/c++"};
942 // Note: as this is only used for debugging we look in the host /usr
943 QDirIterator cpp_it{cpp_dir};
944 while(cpp_it.hasNext())
945 {
946 cpp_it.next();
947 auto ver = cpp_it.fileName();
948 if(!ver.isEmpty() && ver.startsWith(libstdcpp_major))
949 {
950 auto gcc = ver.toStdString();
951
952 // e.g. /usr/include/c++/8.2.1
953 args.push_back("-internal-isystem");
954 args.push_back("/usr/include/c++/" + gcc);
955
956 cpp_dir.cd(ver);
957 for(auto& triple : getPotentialTriples())
958 {
959 if(cpp_dir.exists(triple))
960 {
961 // e.g. /usr/include/c++/8.2.1/x86_64-pc-linux-gnu
962 args.push_back("-internal-isystem");
963 args.push_back("/usr/include/c++/" + gcc + "/" + triple.toStdString());
964 break;
965 }
966 }
967
968 break;
969 }
970 }
971 }
972#endif
973
974#if defined(__APPLE__) && SCORE_FHS_BUILD
975 args.push_back("-internal-isystem");
976 args.push_back(appleSharedSdk + "/lib/clang/" + llvm_lib_version + "/include");
977 args.push_back("-internal-externc-isystem");
978 args.push_back(
979 "/Applications/Xcode.app/Contents/Developer//Platforms/MacOSX.platform/Developer/"
980 "SDKs/MacOSX.sdk/usr/include");
981#else
982 args.push_back("-internal-isystem");
983 args.push_back(sdk + "/lib/clang/" + llvm_lib_version + "/include");
984 args.push_back("-internal-externc-isystem");
985 args.push_back(sdk + "/include");
986#endif
987
988#if defined(__APPLE__)
989 // macOS framework headers are bundled flat in the SDK under include/macos-sdks
990 // (e.g. macos-sdks/ApplicationServices/ApplicationServices.h). In -cc1 mode no
991 // default framework path is added, so addons that transitively include a system
992 // framework (e.g. ApplicationServices via score/tools/Cursor.hpp) need this.
993 if(QFileInfo{qsdk + "/include/macos-sdks"}.isDir())
994 args.push_back("-isystem" + sdk + "/include/macos-sdks");
995#endif
996
997 // -resource-dir
998 // /opt/score-sdk/llvm/lib/clang/11.0.0
999 // -internal-isystem
1000 // /opt/score-sdk/llvm/bin/../include/c++/v1
1001 // -internal-isystem
1002 // /opt/score-sdk/llvm/lib/clang/11.0.0/include
1003 //-internal-externc-isystem
1005
1006 auto include = [&](const std::string& path) {
1007 std::string path_to_include = sdk + "/include/" + path;
1008 auto qpath = QString::fromStdString(path_to_include);
1009 if(!QFileInfo{qpath}.isDir())
1010 {
1011 qDebug() << "Trying to include non-existent path: " << qpath;
1012 }
1013 else
1014 {
1015 args.push_back("-isystem" + sdk + "/include/" + path);
1016 }
1017 };
1018
1019#if defined(__linux__)
1020// #debian
1021#if defined(__x86_64__)
1022 include("x86_64-linux-gnu");
1023#else
1024 include("aarch64-linux-gnu");
1025#endif
1026#endif
1027
1028 // include(""); // /usr/include
1029 std::string qt_folder = "qt";
1030 if(QFile::exists(qsdk + "/include/qt6/QtCore"))
1031 qt_folder = "qt6";
1032
1033 QDirIterator qtVersionFolder{
1034 qsdk + "/include/" + QString::fromStdString(qt_folder) + "/QtCore",
1035 {},
1036 QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot,
1037 {}};
1038 std::string qt_version = QT_VERSION_STR;
1039 if(qtVersionFolder.hasNext())
1040 {
1041 QDir sub = qtVersionFolder.next();
1042 qt_version = sub.dirName().toStdString();
1043 }
1044 include(qt_folder + "");
1045 include(qt_folder + "/QtCore");
1046 include(qt_folder + "/QtCore/" + qt_version);
1047 include(qt_folder + "/QtCore/" + qt_version + "/QtCore");
1048 include(qt_folder + "/QtGui");
1049 include(qt_folder + "/QtGui/" + qt_version);
1050 include(qt_folder + "/QtGui/" + qt_version + "/QtGui");
1051 include(qt_folder + "/QtWidgets");
1052 include(qt_folder + "/QtWidgets/" + qt_version);
1053 include(qt_folder + "/QtWidgets/" + qt_version + "/QtWidgets");
1054 include(qt_folder + "/QtQml");
1055 include(qt_folder + "/QtQml/" + qt_version);
1056 include(qt_folder + "/QtQml/" + qt_version + "/QtQml");
1057 include(qt_folder + "/QtQuick");
1058 include(qt_folder + "/QtQuick/" + qt_version);
1059 include(qt_folder + "/QtQuick/" + qt_version + "/QtQuick");
1060 include(qt_folder + "/QtXml");
1061 include(qt_folder + "/QtNetwork");
1062 include(qt_folder + "/QtSvg");
1063 include(qt_folder + "/QtSql");
1064 include(qt_folder + "/QtOpenGL");
1065 include(qt_folder + "/QtShaderTools");
1066 include(qt_folder + "/QtShaderTools/" + qt_version);
1067 include(qt_folder + "/QtShaderTools/" + qt_version + "/QtShaderTools");
1068 include(qt_folder + "/QtSerialPort");
1069
1070 if(sdk_location.sdk_kind == located_sdk::official && sdk_location.deploying)
1071 {
1072 include("score");
1073 }
1074 else
1075 {
1076 auto thirdparty_include_dirs = {
1077 "/3rdparty/libossia/3rdparty/boost_1_88_0",
1078 "/3rdparty/libossia/3rdparty/nano-signal-slot/include",
1079 "/3rdparty/libossia/3rdparty/spdlog/include",
1080 "/3rdparty/libossia/3rdparty/dr_libs",
1081 "/3rdparty/libossia/3rdparty/Flicks",
1082 "/3rdparty/libossia/3rdparty/fmt/include",
1083 "/3rdparty/libossia/3rdparty/magic_enum/include",
1084 "/3rdparty/libossia/3rdparty/readerwriterqueue",
1085 "/3rdparty/libossia/3rdparty/concurrentqueue",
1086 "/3rdparty/libossia/3rdparty/SmallFunction/smallfun/include",
1087 "/3rdparty/libossia/3rdparty/websocketpp",
1088 "/3rdparty/libossia/3rdparty/rapidjson/include",
1089 "/3rdparty/libossia/3rdparty/libremidi/include",
1090 "/3rdparty/libossia/3rdparty/oscpack",
1091 "/3rdparty/libossia/3rdparty/rnd/include",
1092 "/3rdparty/libossia/3rdparty/span/include",
1093 "/3rdparty/libossia/3rdparty/tuplet/include",
1094 "/3rdparty/libossia/3rdparty/unordered_dense/include",
1095 "/3rdparty/libossia/3rdparty/multi_index/include",
1096 "/3rdparty/libossia/3rdparty/verdigris/src",
1097 "/3rdparty/libossia/3rdparty/weakjack",
1098 };
1099 for(auto path : thirdparty_include_dirs)
1100 {
1101 args.push_back("-isystem" + std::string(SCORE_ROOT_SOURCE_DIR) + path);
1102 }
1103 auto src_include_dirs
1104 = {"/3rdparty/libossia/src",
1105 "/3rdparty/avendish/include",
1106 "/src/lib",
1107 "/src/plugins/score-lib-state",
1108 "/src/plugins/score-lib-device",
1109 "/src/plugins/score-lib-process",
1110 "/src/plugins/score-lib-inspector",
1111 "/src/plugins/score-plugin-avnd",
1112 "/src/plugins/score-plugin-gfx",
1113 "/src/plugins/score-plugin-jit",
1114 "/src/plugins/score-plugin-nodal",
1115 "/src/plugins/score-plugin-remotecontrol",
1116 "/src/plugins/score-plugin-audio",
1117 "/src/plugins/score-plugin-curve",
1118 "/src/plugins/score-plugin-dataflow",
1119 "/src/plugins/score-plugin-engine",
1120 "/src/plugins/score-plugin-scenario",
1121 "/src/plugins/score-plugin-library",
1122 "/src/plugins/score-plugin-deviceexplorer",
1123 "/src/plugins/score-plugin-media",
1124 "/src/plugins/score-plugin-loop",
1125 "/src/plugins/score-plugin-midi",
1126 "/src/plugins/score-plugin-protocols",
1127 "/src/plugins/score-plugin-recording",
1128 "/src/plugins/score-plugin-automation",
1129 "/src/plugins/score-plugin-js",
1130 "/src/plugins/score-plugin-mapping"};
1131
1132 for(auto path : src_include_dirs)
1133 {
1134 args.push_back("-I" + std::string(SCORE_ROOT_SOURCE_DIR) + path);
1135 }
1136
1137 auto src_build_dirs
1138 = {"/.",
1139 "/src/lib",
1140 "/src/plugins/score-lib-state",
1141 "/src/plugins/score-lib-device",
1142 "/src/plugins/score-lib-process",
1143 "/src/plugins/score-lib-inspector",
1144 "/src/plugins/score-plugin-avnd",
1145 "/src/plugins/score-plugin-gfx",
1146 "/src/plugins/score-plugin-jit",
1147 "/src/plugins/score-plugin-nodal",
1148 "/src/plugins/score-plugin-remotecontrol",
1149 "/src/plugins/score-plugin-audio",
1150 "/src/plugins/score-plugin-curve",
1151 "/src/plugins/score-plugin-dataflow",
1152 "/src/plugins/score-plugin-engine",
1153 "/src/plugins/score-plugin-scenario",
1154 "/src/plugins/score-plugin-library",
1155 "/src/plugins/score-plugin-deviceexplorer",
1156 "/src/plugins/score-plugin-media",
1157 "/src/plugins/score-plugin-loop",
1158 "/src/plugins/score-plugin-midi",
1159 "/src/plugins/score-plugin-protocols",
1160 "/src/plugins/score-plugin-recording",
1161 "/src/plugins/score-plugin-automation",
1162 "/src/plugins/score-plugin-js",
1163 "/src/plugins/score-plugin-mapping",
1164 "/3rdparty/libossia/src"};
1165
1166 for(auto path : src_build_dirs)
1167 {
1168 args.push_back("-I" + std::string(SCORE_ROOT_BINARY_DIR) + path);
1169 }
1170 }
1171}
1172
1173}
Definition LibrarySettings.hpp:46
Definition JitPlatform.hpp:130
T & settings() const
Access a specific Settings model instance.
Definition ApplicationContext.hpp:41