15#include <CoreFoundation/CoreFoundation.h>
50map<string, VuoFileUtilities::File *> VuoCompiler::Environment::moduleCacheFileForLocking;
51dispatch_queue_t VuoCompiler::Environment::moduleCacheBuildingQueue = dispatch_queue_create(
"org.vuo.compiler.cache", NULL);
52const string VuoCompiler::Environment::pidCacheDirPrefix =
"pid-";
53set<VuoCompiler *> VuoCompiler::allCompilers;
54dispatch_queue_t VuoCompiler::environmentQueue = dispatch_queue_create(
"org.vuo.compiler.environment", NULL);
55map<string, vector< vector<VuoCompiler::Environment *> > > VuoCompiler::sharedEnvironments;
56map<string, map<string, vector<VuoCompiler::Environment *> > > VuoCompiler::environmentsForCompositionFamily;
57dispatch_group_t VuoCompiler::moduleSourceCompilersExistGlobally = dispatch_group_create();
58string VuoCompiler::vuoFrameworkInProgressPath;
67static void __attribute__((constructor)) VuoCompiler_init(
void)
70 struct rlimit rl{OPEN_MAX, OPEN_MAX};
71 getrlimit(RLIMIT_NOFILE, &rl);
72 rl.rlim_cur =
MIN(OPEN_MAX, rl.rlim_max);
73 if (setrlimit(RLIMIT_NOFILE, &rl))
74 VUserLog(
"Warning: Couldn't set open-files limit: %s", strerror(errno));
77 llvmQueue = dispatch_queue_create(
"org.vuo.compiler.llvm", NULL);
81 llvm::InitializeAllTargetMCs();
82 llvm::InitializeAllTargets();
91 raw_string_ostream stream(message);
92 DiagnosticPrinterRawOStream printer(stream);
95 if (! message.empty())
97 const char *severityName;
98 if (DI.getSeverity() == DS_Error)
99 severityName =
"error";
100 else if (DI.getSeverity() == DS_Warning)
101 severityName =
"warning";
103 severityName =
"note";
105 VuoLog(
VuoLog_moduleName, __FILE__, __LINE__,
"llvmDiagnosticHandler",
"%s: %s", severityName, message.c_str());
139VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
const string &relativePath,
140 bool isSourceFile,
bool isSubcomposition)
143 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
149VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
150 bool isSourceFile,
bool isSubcomposition)
152 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
158void VuoCompiler::ModuleInfo::initialize(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
159 bool isSourceFile,
bool isSubcomposition)
161 this->environment = environment;
162 this->searchPath = searchPath;
165 sourceCodeOverridden =
false;
167 longestDownstreamPath = 0;
177 loading = dispatch_group_create();
180 if (isSubcomposition)
194VuoCompiler::ModuleInfo::~ModuleInfo(
void)
203 dispatch_release(loading);
206VuoCompiler::Environment * VuoCompiler::ModuleInfo::getEnvironment(
void)
const
211string VuoCompiler::ModuleInfo::getSearchPath(
void)
const
216string VuoCompiler::ModuleInfo::getModuleKey(
void)
const
226string VuoCompiler::ModuleInfo::getSourceCode(
void)
const
231void VuoCompiler::ModuleInfo::setSourceCode(
const string &sourceCode)
233 this->sourceCode = sourceCode;
236void VuoCompiler::ModuleInfo::revertSourceCode(
void)
241bool VuoCompiler::ModuleInfo::isSourceCodeOverridden(
void)
const
243 return sourceCodeOverridden;
246void VuoCompiler::ModuleInfo::setSourceCodeOverridden(
bool overridden)
248 sourceCodeOverridden = overridden;
251bool VuoCompiler::ModuleInfo::isNewerThan(ModuleInfo *other)
const
253 return lastModified > other->lastModified;
256bool VuoCompiler::ModuleInfo::isNewerThan(
unsigned long ageInSeconds)
const
258 return lastModified > ageInSeconds;
261bool VuoCompiler::ModuleInfo::isOlderThan(
unsigned long ageInSeconds)
const
263 return lastModified < ageInSeconds;
266void VuoCompiler::ModuleInfo::setLastModifiedToNow(
void)
269 gettimeofday(&t, NULL);
270 lastModified = t.tv_sec;
273set<string> VuoCompiler::ModuleInfo::getContainedNodeClasses(
void)
const
275 return containedNodeClasses;
278int VuoCompiler::ModuleInfo::getLongestDownstreamPath(
void)
const
280 return longestDownstreamPath;
283void VuoCompiler::ModuleInfo::setLongestDownstreamPath(
int pathLength)
285 longestDownstreamPath = pathLength;
288bool VuoCompiler::ModuleInfo::getAttempted(
void)
const
293void VuoCompiler::ModuleInfo::setAttempted(
bool attempted)
295 this->attempted = attempted;
298dispatch_group_t VuoCompiler::ModuleInfo::getLoadingGroup(
void)
const
303void VuoCompiler::ModuleInfo::dump()
const
305 fprintf(stderr,
"module %s:\n"
306 "\tloadingGroup=%p\n"
311 "\tsourceCodeOverridden=%d\n"
313 "\tcontainedNodeClasses:\n",
318 environment->getCompiledModuleCachePath().c_str(),
322 sourceCodeOverridden,
324 for (
auto i: containedNodeClasses)
325 fprintf(stderr,
"\t\t%s\n", i.c_str());
328VuoCompiler::DependencyGraphVertex * VuoCompiler::DependencyGraphVertex::vertexForDependency(
const string &dependency,
VuoDirectedAcyclicGraph *graph)
332 return dynamic_cast<DependencyGraphVertex *
>(v);
334 DependencyGraphVertex *vv =
new DependencyGraphVertex();
335 vv->dependency = dependency;
336 vv->environment = NULL;
337 vv->compatible =
true;
341string VuoCompiler::DependencyGraphVertex::getDependency(
void)
346VuoCompiler::Environment * VuoCompiler::DependencyGraphVertex::getEnvironment(
void)
351void VuoCompiler::DependencyGraphVertex::setEnvironment(Environment *environment)
353 this->environment = environment;
356string VuoCompiler::DependencyGraphVertex::key(
void)
368VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos,
369 const string &overriddenCompiledModuleCachePath)
371 this->allModuleInfos = allModuleInfos;
372 this->overriddenCompiledModuleCachePath = overriddenCompiledModuleCachePath;
373 hasSearchModuleKeys =
false;
384VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos,
385 const string &overriddenCompiledModuleCachePath,
386 const set<string> &searchModuleKeys)
388 this->allModuleInfos = allModuleInfos;
389 this->overriddenCompiledModuleCachePath = overriddenCompiledModuleCachePath;
390 this->searchModuleKeys = searchModuleKeys;
391 hasSearchModuleKeys =
true;
400void VuoCompiler::ModuleInfoIterator::initialize(
void)
402 currSearchPath = allModuleInfos->begin();
403 hasCurrModuleKey =
false;
405 if (! overriddenCompiledModuleCachePath.empty())
407 auto i = allModuleInfos->find(overriddenCompiledModuleCachePath);
408 if (i != allModuleInfos->end())
410 std::transform(i->second.begin(), i->second.end(),
411 std::inserter(overriddenModuleKeys, overriddenModuleKeys.begin()),
412 [](
const pair<string, ModuleInfo *> &p) { return p.first; });
422VuoCompiler::ModuleInfo * VuoCompiler::ModuleInfoIterator::next(
void)
424 for ( ; currSearchPath != allModuleInfos->end(); ++currSearchPath)
426 if (! hasCurrModuleKey)
428 currModuleKey = currSearchPath->second.begin();
429 hasCurrModuleKey =
true;
432 bool isOverriddenCompiledModuleCachePath = ! overriddenCompiledModuleCachePath.empty() &&
435 for ( ; currModuleKey != currSearchPath->second.end(); ++currModuleKey)
437 if ((! hasSearchModuleKeys || searchModuleKeys.find(currModuleKey->first) != searchModuleKeys.end()) &&
438 (isOverriddenCompiledModuleCachePath || overriddenModuleKeys.find(currModuleKey->first) == overriddenModuleKeys.end()))
440 ModuleInfo *moduleInfo = currModuleKey->second;
446 hasCurrModuleKey =
false;
455VuoCompiler::Environment::Environment(
string target,
bool builtIn,
bool generated)
456 : target(target), builtIn(builtIn), generated(generated)
458 compilersToNotifyQueue = dispatch_queue_create(
"org.vuo.compiler.notify", 0);
459 moduleSearchPathContentsChangedQueue = dispatch_queue_create(
"org.vuo.compiler.watch", 0);
460 lastModuleCacheRebuild = 0;
461 isModuleCacheableDataDirty =
false;
462 isModuleCacheInitialized =
false;
463 isModuleCacheAvailable =
false;
472VuoCompiler::Environment::~Environment(
void)
474 stopWatchingModuleSearchPaths();
475 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{});
477 dispatch_release(moduleSearchPathContentsChangedQueue);
478 dispatch_release(compilersToNotifyQueue);
480 for (map<string, VuoCompilerNodeClass *>::iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
481 destroyModule(i->second);
483 for (map<string, VuoCompilerType *>::iterator i = types.begin(); i != types.end(); ++i)
484 destroyModule(i->second);
486 for (map<string, VuoCompilerModule *>::iterator i = libraryModules.begin(); i != libraryModules.end(); ++i)
487 destroyModule(i->second);
489 for (set<VuoCompilerGenericType *>::iterator i = genericTypes.begin(); i != genericTypes.end(); ++i)
491 VuoType *base = (*i)->getBase();
496 for (map<string, VuoNodeSet *>::iterator i = nodeSetForName.begin(); i != nodeSetForName.end(); ++i)
499 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
500 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
503 for (map<
string, map<string, ModuleInfo *> >::iterator i = sourceFilesAtSearchPath.begin(); i != sourceFilesAtSearchPath.end(); ++i)
504 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
507 delete dependencyGraph;
508 delete compositionDependencyGraph;
514string VuoCompiler::Environment::getTarget()
522void VuoCompiler::Environment::addCompilerToNotify(
VuoCompiler *compiler)
524 dispatch_sync(compilersToNotifyQueue, ^{
525 compilersToNotify.insert(compiler);
532void VuoCompiler::Environment::removeCompilerToNotify(
VuoCompiler *compiler)
534 dispatch_sync(compilersToNotifyQueue, ^{
535 compilersToNotify.erase(compiler);
544map<string, VuoCompilerNodeClass *> VuoCompiler::Environment::getNodeClasses(
void)
556 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
557 if (nodeClassIter != nodeClasses.end())
558 return nodeClassIter->second;
571 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
572 if (nodeClassIter != nodeClasses.end())
574 nodeClass = nodeClassIter->second;
576 nodeClasses.erase(nodeClassIter);
577 removeFromDependencyGraph(nodeClass);
589map<string, VuoCompilerType *> VuoCompiler::Environment::getTypes(
void)
599VuoCompilerType * VuoCompiler::Environment::getType(
const string &moduleKey)
601 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
602 if (typeIter != types.end())
603 return typeIter->second;
613map<string, VuoNodeSet *> VuoCompiler::Environment::getNodeSets(
void)
615 return nodeSetForName;
623VuoCompilerModule *VuoCompiler::Environment::getLibraryModule(
const string &libraryModuleName)
625 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(libraryModuleName);
626 if (libraryIter != libraryModules.end())
627 return libraryIter->second;
637map<string, VuoCompilerModule *> VuoCompiler::Environment::getLibraryModules(
void)
639 return libraryModules;
650 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
651 if (nodeClassIter != nodeClasses.end())
652 return nodeClassIter->second;
654 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
655 if (typeIter != types.end())
656 return typeIter->second;
658 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(moduleKey);
659 if (libraryIter != libraryModules.end())
660 return libraryIter->second;
670VuoNodeSet * VuoCompiler::Environment::findNodeSet(
const string &name)
673 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(name);
674 if (nodeSetIter != nodeSetForName.end())
675 return nodeSetIter->second;
686void VuoCompiler::Environment::addModuleSearchPath(
const string &path,
bool shouldWatch)
688 moduleSearchPaths.push_back(path);
690 updateModulesAtSearchPath(path);
691 updateSourceFilesAtSearchPath(path);
694 startWatchingModuleSearchPath(path);
702vector<string> VuoCompiler::Environment::getModuleSearchPaths(
void)
704 return moduleSearchPaths;
712void VuoCompiler::Environment::addHeaderSearchPath(
const string &path)
714 headerSearchPaths.push_back(path);
722vector<string> VuoCompiler::Environment::getHeaderSearchPaths(
void)
724 return headerSearchPaths;
732void VuoCompiler::Environment::addLibrarySearchPath(
const string &path)
734 librarySearchPaths.push_back(path);
742vector<string> VuoCompiler::Environment::getLibrarySearchPaths(
void)
744 return librarySearchPaths;
752void VuoCompiler::Environment::addFrameworkSearchPath(
const string &path)
754 frameworkSearchPaths.push_back(path);
762vector<string> VuoCompiler::Environment::getFrameworkSearchPaths(
void)
764 return frameworkSearchPaths;
769 return dependencyGraph;
774 return compositionDependencyGraph;
782void VuoCompiler::Environment::setModuleCachePath(
const string &path,
bool shouldAddModuleSearchPath)
784 moduleCachePath = path;
786 if (shouldAddModuleSearchPath)
788 addModuleSearchPath(getCompiledModuleCachePath(),
false);
789 addModuleSearchPath(getOverriddenCompiledModuleCachePath(),
false);
798string VuoCompiler::Environment::getCompiledModuleCachePath(
void)
800 return (moduleCachePath.empty() ?
"" : moduleCachePath +
"/Modules/" + VuoCompiler::getTargetArch(target));
808string VuoCompiler::Environment::getOverriddenCompiledModuleCachePath(
void)
810 if (moduleCachePath.empty())
816 string dir, moduleCacheDirName, ext;
819 return (
VuoFileUtilities::getCachePath() +
"/" + pidCacheDirPrefix + pid.str() +
"/" + moduleCacheDirName +
"/Modules/" + VuoCompiler::getTargetArch(target));
829void VuoCompiler::Environment::addExpatriateSourceFile(
const string &sourcePath)
831 expatriateSourceFiles.push_back(sourcePath);
833 if (find(moduleSearchPaths.begin(), moduleSearchPaths.end(),
"") == moduleSearchPaths.end())
834 moduleSearchPaths.push_back(
"");
836 auto iter = sourceFilesAtSearchPath.find(
"");
837 if (iter != sourceFilesAtSearchPath.end())
838 sourceFilesAtSearchPath.erase(iter);
846void VuoCompiler::Environment::removeExpatriateSourceFile(
const string &sourcePath)
848 for (
auto i = expatriateSourceFiles.begin(); i != expatriateSourceFiles.end(); ++i)
852 expatriateSourceFiles.erase(i);
854 auto iter = sourceFilesAtSearchPath.find(
"");
855 if (iter != sourceFilesAtSearchPath.end())
856 sourceFilesAtSearchPath.erase(iter);
875void VuoCompiler::Environment::updateModulesAtSearchPath(
const string &path)
877 if (moduleFilesAtSearchPath.find(path) != moduleFilesAtSearchPath.end())
880 set<string> moduleExtensions;
881 moduleExtensions.insert(
"vuonode");
882 moduleExtensions.insert(
"vuonode+");
883 moduleExtensions.insert(
"bc");
884 moduleExtensions.insert(
"bc+");
885 set<string> archiveExtensions;
886 archiveExtensions.insert(
"vuonode");
889 map<string, ModuleInfo *> fileForModuleKey;
890 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
898 ModuleInfo *m =
new ModuleInfo(
this, path, moduleFile,
false,
false);
899 fileForModuleKey[m->getModuleKey()] = m;
902 if (path == getCompiledModuleCachePath())
904 for (map<string, ModuleInfo *>::iterator i = fileForModuleKey.begin(); i != fileForModuleKey.end(); )
906 ModuleInfo *sourceInfo = listSourceFile(i->first);
907 if (! sourceInfo || sourceInfo->isNewerThan(i->second))
909 ModuleInfo *m = i->second;
912 fileForModuleKey.erase(i++);
919 moduleFilesAtSearchPath[path] = fileForModuleKey;
927void VuoCompiler::Environment::updateModuleAtSearchPath(
const string &moduleSearchPath,
const string &moduleRelativePath)
929 string dir, file, ext;
932 set<string> moduleExtensions;
933 moduleExtensions.insert(ext);
934 set<string> archiveExtensions;
935 archiveExtensions.insert(
"vuonode");
939 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
943 ModuleInfo *m =
new ModuleInfo(
this, moduleSearchPath, moduleFile,
false,
false);
944 moduleFilesAtSearchPath[moduleSearchPath][m->getModuleKey()] = m;
955void VuoCompiler::Environment::updateSourceFilesAtSearchPath(
const string &path)
957 map<string, map<string, ModuleInfo *> >::iterator sourceFilesIter = sourceFilesAtSearchPath.find(path);
958 if (sourceFilesIter != sourceFilesAtSearchPath.end())
961 set<VuoFileUtilities::File *> sourceFiles;
964 set<string> sourceExtensions;
965 sourceExtensions.insert(
"vuo");
966 sourceExtensions.insert(
"fs");
968 sourceExtensions.insert(cext.begin(), cext.end());
973 for (
const string &sourcePath : expatriateSourceFiles)
975 string dir, file, ext;
978 sourceFiles.insert(sourceFile);
982 map<string, ModuleInfo *> fileForModuleKey;
983 for (set<VuoFileUtilities::File *>::iterator i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
987 string dir, moduleKey, ext;
989 bool isSubcomposition = (ext ==
"vuo");
992 if (path.empty() && !sourceFile->
exists())
995 ModuleInfo *m =
new ModuleInfo(
this, path, sourceFile,
true, isSubcomposition);
996 if (fileForModuleKey.find(m->getModuleKey()) != fileForModuleKey.end())
997 VUserLog(
"Warning: Conflicting source files for module %s are installed at %s", m->getModuleKey().c_str(), path.c_str());
998 fileForModuleKey[m->getModuleKey()] = m;
1000 if (isSubcomposition)
1002 DependencyGraphVertex *compositionVertex = DependencyGraphVertex::vertexForDependency(moduleKey, compositionDependencyGraph);
1003 compositionDependencyGraph->addVertex(compositionVertex);
1005 compositionVertex->setEnvironment(
this);
1007 set<string> dependencies = m->getContainedNodeClasses();
1008 for (set<string>::iterator j = dependencies.begin(); j != dependencies.end(); ++j)
1010 DependencyGraphVertex *dependencyVertex = DependencyGraphVertex::vertexForDependency(*j, compositionDependencyGraph);
1011 compositionDependencyGraph->addEdge(compositionVertex, dependencyVertex);
1016 sourceFilesAtSearchPath[path] = fileForModuleKey;
1024VuoCompiler::ModuleInfo * VuoCompiler::Environment::listModule(
const string &moduleKey)
1026 for (
const auto &moduleFiles : moduleFilesAtSearchPath)
1028 map<string, ModuleInfo *>::const_iterator foundIter = moduleFiles.second.find(moduleKey);
1029 if (foundIter != moduleFiles.second.end())
1030 return foundIter->second;
1041VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listModules(
const set<string> &moduleKeys)
1043 for (
const string &path : moduleSearchPaths)
1044 updateModulesAtSearchPath(path);
1046 return ModuleInfoIterator(&moduleFilesAtSearchPath, getOverriddenCompiledModuleCachePath(), moduleKeys);
1054VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllModules(
void)
1056 for (
const string &path : moduleSearchPaths)
1057 updateModulesAtSearchPath(path);
1059 return ModuleInfoIterator(&moduleFilesAtSearchPath, getOverriddenCompiledModuleCachePath());
1067VuoCompiler::ModuleInfo * VuoCompiler::Environment::listSourceFile(
const string &moduleKey)
1069 for (
const auto &sourceFiles : sourceFilesAtSearchPath)
1071 map<string, ModuleInfo *>::const_iterator foundIter = sourceFiles.second.find(moduleKey);
1072 if (foundIter != sourceFiles.second.end())
1073 return foundIter->second;
1084VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listSourceFiles(
const set<string> &moduleKeys)
1086 for (
const string &path : moduleSearchPaths)
1087 updateSourceFilesAtSearchPath(path);
1089 return ModuleInfoIterator(&sourceFilesAtSearchPath,
"", moduleKeys);
1097VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllSourceFiles(
void)
1099 for (
const string &path : moduleSearchPaths)
1100 updateSourceFilesAtSearchPath(path);
1102 return ModuleInfoIterator(&sourceFilesAtSearchPath,
"");
1108vector<string> VuoCompiler::Environment::getBuiltInModuleSearchPaths(
void)
1110 vector<string> builtInModuleSearchPaths;
1112 string vuoFrameworkPath = getVuoFrameworkPath();
1113 if (! vuoFrameworkPath.empty())
1115 builtInModuleSearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1119 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/library");
1120 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/node");
1121 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type");
1122 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1125 return builtInModuleSearchPaths;
1131vector<string> VuoCompiler::Environment::getBuiltInHeaderSearchPaths(
void)
1133 vector<string> builtInHeaderSearchPaths;
1135 string vuoFrameworkPath = getVuoFrameworkPath();
1136 if (! vuoFrameworkPath.empty())
1138 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/Headers/lib/c++/v1");
1139 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers");
1140 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos");
1141 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos/pthread");
1145 builtInHeaderSearchPaths.push_back(LLVM_ROOT
"/include/c++/v1");
1146 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/library");
1147 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/node");
1148 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type");
1149 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type/list");
1150 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/runtime");
1151 builtInHeaderSearchPaths.push_back(JSONC_ROOT
"/include");
1154 return builtInHeaderSearchPaths;
1160vector<string> VuoCompiler::Environment::getBuiltInLibrarySearchPaths(
void)
1162 vector<string> builtInLibrarySearchPaths;
1164 string vuoFrameworkPath = getVuoFrameworkPath();
1165 if (! vuoFrameworkPath.empty())
1167 builtInLibrarySearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1170 builtInLibrarySearchPaths.push_back(OPENSSL_ROOT
"/lib");
1174 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/library");
1175 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/node");
1176 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type");
1177 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1178 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/runtime");
1181 builtInLibrarySearchPaths.insert(builtInLibrarySearchPaths.end(), conanLibDirs.begin(), conanLibDirs.end());
1184 return builtInLibrarySearchPaths;
1190vector<string> VuoCompiler::Environment::getBuiltInFrameworkSearchPaths(
void)
1192 vector<string> builtInFrameworkSearchPaths;
1194 string vuoFrameworkPath = getVuoFrameworkPath();
1195 if (! vuoFrameworkPath.empty())
1197 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Modules/");
1198 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/");
1201 return builtInFrameworkSearchPaths;
1210void VuoCompiler::Environment::startWatchingModuleSearchPath(
const string &moduleSearchPath)
1213 moduleSearchPathWatchers.insert(watcher);
1221void VuoCompiler::Environment::stopWatchingModuleSearchPaths(
void)
1223 for (set<VuoFileWatcher *>::iterator i = moduleSearchPathWatchers.begin(); i != moduleSearchPathWatchers.end(); ++i)
1226 moduleSearchPathWatchers.clear();
1233void VuoCompiler::Environment::fileChanged(
const string &moduleSearchPath)
1235 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{
1236 moduleSearchPathContentsChanged(moduleSearchPath);
1247void VuoCompiler::Environment::moduleSearchPathContentsChanged(
const string &moduleSearchPath)
1252 __block set<string> modulesAdded;
1253 __block set<string> modulesModifed;
1254 __block set<string> modulesRemoved;
1255 __block set<string> compositionsAdded;
1256 __block set<string> compositionsModifed;
1257 __block set<string> compositionsRemoved;
1259 dispatch_sync(environmentQueue, ^{
1263 map<string, ModuleInfo *> oldModules;
1264 map<string, ModuleInfo *> oldCompositions;
1266 map<string, map<string, ModuleInfo *> >::iterator mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1267 if (mf != moduleFilesAtSearchPath.end())
1269 for (map<string, ModuleInfo *>::iterator j = mf->second.begin(); j != mf->second.end(); ++j)
1271 oldModules[j->first] = j->second;
1274 moduleFilesAtSearchPath.erase(mf);
1277 map<string, map<string, ModuleInfo *> >::iterator cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1278 if (cf != sourceFilesAtSearchPath.end())
1280 for (map<string, ModuleInfo *>::iterator j = cf->second.begin(); j != cf->second.end(); ++j)
1282 oldCompositions[j->first] = j->second;
1284 VuoDirectedAcyclicGraph::Vertex *vertex = compositionDependencyGraph->findVertex(j->first);
1285 compositionDependencyGraph->removeVertex(vertex);
1288 sourceFilesAtSearchPath.erase(cf);
1293 updateModulesAtSearchPath(moduleSearchPath);
1294 updateSourceFilesAtSearchPath(moduleSearchPath);
1298 auto omf = moduleFilesAtSearchPath.find(getOverriddenCompiledModuleCachePath());
1299 if (omf != moduleFilesAtSearchPath.end())
1301 for (
auto oldComposition : oldCompositions)
1303 for (
auto i = omf->second.begin(); i != omf->second.end(); ++i)
1305 if (i->first == oldComposition.first)
1308 omf->second.erase(i);
1317 mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1318 if (mf != moduleFilesAtSearchPath.end())
1320 for (map<string, ModuleInfo *>::iterator n = mf->second.begin(); n != mf->second.end(); ++n)
1322 string moduleKey = n->first;
1324 map<string, ModuleInfo *>::iterator o = oldModules.find(moduleKey);
1325 if (o != oldModules.end())
1327 if (n->second->isNewerThan(o->second))
1329 modulesModifed.insert(moduleKey);
1333 n->second->setAttempted(o->second->getAttempted());
1337 oldModules.erase(o);
1341 modulesAdded.insert(moduleKey);
1346 cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1347 if (cf != sourceFilesAtSearchPath.end())
1349 for (map<string, ModuleInfo *>::iterator n = cf->second.begin(); n != cf->second.end(); ++n)
1351 string moduleKey = n->first;
1353 map<string, ModuleInfo *>::iterator o = oldCompositions.find(moduleKey);
1354 if (o != oldCompositions.end())
1356 if (n->second->isNewerThan(o->second))
1358 compositionsModifed.insert(moduleKey);
1362 n->second->setAttempted(o->second->getAttempted());
1363 n->second->setSourceCode(o->second->getSourceCode());
1367 oldCompositions.erase(o);
1371 compositionsAdded.insert(moduleKey);
1376 for (map<string, ModuleInfo *>::iterator o = oldModules.begin(); o != oldModules.end(); ++o)
1379 modulesRemoved.insert(o->first);
1382 for (map<string, ModuleInfo *>::iterator o = oldCompositions.begin(); o != oldCompositions.end(); ++o)
1385 compositionsRemoved.insert(o->first);
1388 compilerForLoading->loadModulesAndSources(modulesAdded, modulesModifed, modulesRemoved,
1389 compositionsAdded, compositionsModifed, compositionsRemoved,
1390 false,
false,
this,
nullptr,
nullptr,
"");
1393 delete compilerForLoading;
1402void VuoCompiler::Environment::moduleFileChanged(
const string &modulePath,
const string &moduleSourceCode,
1403 std::function<
void(
void)> moduleLoadedCallback,
1407 dispatch_sync(environmentQueue, ^{
1409 string moduleDir, moduleKey, ext;
1415 bool foundOldModule =
false;
1416 auto moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1417 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1419 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1420 if (moduleIter != moduleSearchPathIter->second.end())
1422 delete moduleIter->second;
1423 moduleSearchPathIter->second.erase(moduleIter);
1424 foundOldModule =
true;
1430 updateModuleAtSearchPath(moduleDir, moduleKey +
"." + ext);
1434 bool foundNewModule =
false;
1435 moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1436 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1438 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1439 if (moduleIter != moduleSearchPathIter->second.end())
1441 foundNewModule =
true;
1445 set<string> modulesAdded;
1446 set<string> modulesModified;
1447 set<string> modulesRemoved;
1451 modulesModified.insert(moduleKey);
1453 else if (! foundOldModule && foundNewModule)
1455 modulesAdded.insert(moduleKey);
1457 else if (foundOldModule && ! foundNewModule)
1459 modulesRemoved.insert(moduleKey);
1462 compiler->loadModulesAndSources(modulesAdded, modulesModified, modulesRemoved,
1463 set<string>(), set<string>(), set<string>(),
1464 false,
false,
this, issues, moduleLoadedCallback, moduleSourceCode);
1472void VuoCompiler::Environment::notifyCompilers(
const set<VuoCompilerModule *> &modulesAdded,
1473 const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
1475 bool oldModulesInvalidated)
1477 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()) )
1479 set< pair<VuoCompilerModule *, VuoCompilerModule *> > invalidatedModulesModified;
1480 set<VuoCompilerModule *> invalidatedModulesRemoved;
1481 if (oldModulesInvalidated)
1483 invalidatedModulesModified = modulesModified;
1484 invalidatedModulesRemoved = modulesRemoved;
1487 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(invalidatedModulesModified, invalidatedModulesRemoved, issues);
1489 map<string, VuoCompilerModule *> modulesAddedMap;
1490 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModifiedMap;
1491 map<string, VuoCompilerModule *> modulesRemovedMap;
1493 modulesAddedMap[m->getPseudoBase()->getModuleKey()] = m;
1494 for (pair<VuoCompilerModule *, VuoCompilerModule *> m : modulesModified)
1495 modulesModifiedMap[m.first->getPseudoBase()->getModuleKey()] = m;
1497 modulesRemovedMap[m->getPseudoBase()->getModuleKey()] = m;
1499 dispatch_sync(compilersToNotifyQueue, ^{
1500 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1501 delegateData->retain();
1503 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1504 (*i)->loadedModules(modulesAddedMap, modulesModifiedMap, modulesRemovedMap, issues, delegateData, this);
1524set<VuoCompilerModule *> VuoCompiler::Environment::loadCompiledModules(
const set<string> &moduleKeys,
const map<string, string> &sourceCodeForModule)
1526 ModuleInfoIterator modulesToLoadIter = listModules(moduleKeys);
1527 set<VuoCompilerModule *> modulesLoaded;
1529 ModuleInfo *moduleInfo;
1530 while ((moduleInfo = modulesToLoadIter.next()))
1532 string moduleKey = moduleInfo->getModuleKey();
1536 if (moduleInfo->getEnvironment() !=
this || findModule(moduleKey) || moduleInfo->getAttempted())
1539 moduleInfo->setAttempted(
true);
1546 modulesLoaded.insert(module);
1547 addToDependencyGraph(module);
1551 string searchPath = moduleInfo->getSearchPath();
1558 ModuleInfo *sourceInfo = listSourceFile(moduleKey);
1562 auto sourceCodeIter = sourceCodeForModule.find(moduleKey);
1563 if (sourceCodeIter != sourceCodeForModule.end())
1570 return modulesLoaded;
1584set<dispatch_group_t> VuoCompiler::Environment::loadSpecializedModules(
const set<string> &moduleKeys,
1587 set<dispatch_group_t > loadingGroups;
1589 for (
string moduleKey : moduleKeys)
1593 if (moduleKey.find(
".") == string::npos ||
1600 if (findModule(moduleKey))
1605 map<string, dispatch_group_t>::iterator iter = specializedModulesLoading.find(moduleKey);
1606 if (iter != specializedModulesLoading.end())
1608 loadingGroups.insert(iter->second);
1609 dispatch_retain(iter->second);
1613 dispatch_group_t loadingGroup = dispatch_group_create();
1614 specializedModulesLoading[moduleKey] = loadingGroup;
1615 loadingGroups.insert(loadingGroup);
1621 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1622 dispatch_group_async(loadingGroup, queue, ^{
1636 compiler->loadNodeClassGeneratedAtRuntime(specNodeClass,
this);
1639 if (!dependencies.empty())
1640 compiler->loadModulesIfNeeded(dependencies);
1643 dispatch_sync(environmentQueue, ^{
1644 specializedModulesLoading.erase(moduleKey);
1649 return loadingGroups;
1664set<dispatch_group_t> VuoCompiler::Environment::compileModulesFromSourceCode(
const set<string> &moduleKeys,
bool shouldRecompileIfUnchanged)
1666 ModuleInfoIterator modulesToLoadIter = listSourceFiles(moduleKeys);
1668 int environmentIndex = sharedEnvironments[target].size();
1669 for (
int i = 0; i < sharedEnvironments[target].size(); ++i)
1670 if (
this == sharedEnvironments[target].at(i).at(0))
1671 environmentIndex = i;
1673 set<dispatch_group_t> sourcesLoading;
1674 int sourcesEnqueued = 0;
1675 ModuleInfo *sourceInfo;
1676 while ((sourceInfo = modulesToLoadIter.next()))
1678 string moduleKey = sourceInfo->getModuleKey();
1680 dispatch_group_t loadingGroup = sourceInfo->getLoadingGroup();
1681 sourcesLoading.insert(loadingGroup);
1686 if (sourceInfo->getAttempted())
1691 string sourceCode = sourceInfo->getSourceCode();
1693 if (! shouldRecompileIfUnchanged)
1696 if (existingNodeClass && existingNodeClass->
getSourceCode() == sourceCode)
1702 sourceInfo->setAttempted(
true);
1704 dispatch_group_enter(loadingGroup);
1705 dispatch_group_enter(moduleSourceCompilersExistGlobally);
1709 queueItem->
sourcePath = sourceInfo->getFile()->path();
1711 queueItem->
sourceFile = sourceInfo->getFile();
1712 queueItem->
cachedModulesPath = sourceInfo->isSourceCodeOverridden() ? getOverriddenCompiledModuleCachePath() : getCompiledModuleCachePath();
1715 queueItem->
priority = { environmentIndex, sourceInfo->getLongestDownstreamPath() };
1716 moduleCompilationQueue->enqueue(queueItem);
1725 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1726 dispatch_async(queue, ^{
1727 for (
int i = 0; i < sourcesEnqueued; ++i)
1730 VUserLog(
"Compiling %s", queueItem->moduleKey.c_str());
1732 dispatch_async(queue, ^{
1741 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1748 auto moduleLoadedCallback = [=](){
1749 dispatch_group_leave(queueItemForCallback->
loadingGroup);
1750 moduleCompilationQueue->completed(queueItemForCallback);
1753 string ext = queueItem->sourceFile->extension();
1764 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1771 auto getType = [&compiler] (
const string &moduleKey) {
return compiler->
getType(moduleKey); };
1778 setTargetForModule(module, target);
1779 writeModuleToBitcode(module, queueItem->compiledModulePath);
1787 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1790 moduleLoadedCallback();
1798 compiler->
compileModule(queueItem->sourcePath, queueItem->compiledModulePath, vector<string>());
1808 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1818 Module *module = compiler->compileCompositionToModule(composition, queueItem->moduleKey,
false, issues);
1823 setTargetForModule(module, target);
1824 writeModuleToBitcode(module, queueItem->compiledModulePath);
1829 delete baseComposition;
1839 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1843 dispatch_group_leave(moduleSourceCompilersExistGlobally);
1848 return sourcesLoading;
1859set<VuoCompilerModule *> VuoCompiler::Environment::unloadCompiledModules(
const set<string> &moduleKeys)
1861 set<VuoCompilerModule *> modulesUnloaded;
1863 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1865 string moduleKey = *i;
1868 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
1869 if (nodeClassIter != nodeClasses.end())
1871 module = nodeClassIter->second;
1872 nodeClasses.erase(nodeClassIter);
1876 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
1877 if (typeIter != types.end())
1879 module = typeIter->second;
1880 types.erase(typeIter);
1884 map<string, VuoCompilerModule *>::iterator libraryModuleIter = libraryModules.find(moduleKey);
1885 if (libraryModuleIter != libraryModules.end())
1887 module = libraryModuleIter->second;
1888 libraryModules.erase(libraryModuleIter);
1895 modulesUnloaded.insert(module);
1896 removeFromDependencyGraph(module);
1901 return modulesUnloaded;
1909void VuoCompiler::Environment::deleteModulesCompiledFromSourceCode(
const set<string> &moduleKeys)
1911 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1913 string moduleKey = *i;
1915 map<string, ModuleInfo *>::iterator iter = moduleFilesAtSearchPath[getCompiledModuleCachePath()].find(moduleKey);
1916 if (iter != moduleFilesAtSearchPath[getCompiledModuleCachePath()].end())
1930 string moduleKey = moduleInfo->getModuleKey();
1944 __block
size_t inputDataBytes;
1945 __block
char *rawInputData;
1949 rawInputData = moduleInfo->getFile()->getContentsAsRawData(inputDataBytes);
1953 rawInputData = NULL;
1954 VUserLog(
"Warning: Couldn't load module '%s'. Its file may have been deleted. (%s)", moduleKey.c_str(), e.
what());
1960 char *processedInputData;
1962 processedInputData = loadModule_Pro0(moduleInfo, moduleKey, inputDataBytes, rawInputData);
1964 processedInputData = rawInputData;
1967 Module *module = NULL;
1968 set<string> moduleArchs;
1969 bool moduleParseError = !processedInputData;
1970 if (!moduleParseError)
1972 string moduleReadError;
1973 string arch = VuoCompiler::getTargetArch(target);
1974 VuoLog_status(
"Loading module \"%s\" (%s)", moduleKey.c_str(), arch.c_str());
1975 module = readModuleFromBitcodeData(processedInputData, inputDataBytes, arch, moduleArchs, moduleReadError);
1977 free(processedInputData);
1981 moduleParseError =
true;
1986 VUserLog(
"Error: Couldn't load module '%s' into %s environment: %s.", moduleKey.c_str(), arch.c_str(), moduleReadError.c_str());
1990 if (!moduleParseError)
1993 if (! moduleInfo->getFile()->isInArchive())
1994 modulePath = moduleInfo->getFile()->path();
2012 libraryModules[moduleKey] = compilerModule;
2017 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(nodeSet->
getName());
2018 if (nodeSetIter == nodeSetForName.end())
2020 nodeSetForName[nodeSet->
getName()] = nodeSet;
2025 nodeSet = nodeSetIter->second;
2027 compilerModule->getPseudoBase()->setNodeSet(nodeSet);
2031 loadModule_Pro1(rawInputData, processedInputData, compilerModule);
2034 compilerModule->setBuiltIn( isBuiltInOriginal() );
2036 return compilerModule;
2040 destroyLlvmModule(module);
2059 removeFromDependencyGraph(oldNodeClass);
2060 destroyModule(oldNodeClass);
2063 nodeClasses[moduleKey] = newNodeClass;
2064 addToDependencyGraph(newNodeClass);
2070 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
2071 dependencyGraph->addVertex(vertex);
2073 vertex->setEnvironment(
this);
2076 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
2078 DependencyGraphVertex *depVertex = DependencyGraphVertex::vertexForDependency(*i, dependencyGraph);
2079 dependencyGraph->addEdge(vertex, depVertex);
2083void VuoCompiler::Environment::removeFromDependencyGraph(
VuoCompilerModule *module)
2085 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
2086 dependencyGraph->removeVertex(vertex);
2099void VuoCompiler::Environment::reifyPortTypes(
const map<string, VuoCompilerType *> &inheritedTypes)
2101 map<string, VuoCompilerType *> availableTypes = inheritedTypes;
2102 availableTypes.insert(types.begin(), types.end());
2104 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
2110 vector<VuoPortClass *> portClasses;
2111 portClasses.insert(portClasses.end(), inputPortClasses.begin(), inputPortClasses.end());
2112 portClasses.insert(portClasses.end(), outputPortClasses.begin(), outputPortClasses.end());
2114 for (vector<VuoPortClass *>::iterator j = portClasses.begin(); j != portClasses.end(); ++j)
2134 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2135 if (reifiedTypeIter != availableTypes.end())
2138 reifiedType = reifiedTypeIter->second;
2149 for (vector<VuoCompilerTriggerDescription *>::iterator j = triggers.begin(); j != triggers.end(); ++j)
2157 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2158 if (reifiedTypeIter != availableTypes.end())
2179void VuoCompiler::Environment::getCacheableModulesAndDependencies(set<string> &cacheableModulesAndDependencies,
2180 set<string> &dylibsNeededToLinkToThisCache,
2181 set<string> &frameworksNeededToLinkToThisCache)
2183 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty)
2185 cacheableModulesAndDependencies = moduleCacheContents;
2186 dylibsNeededToLinkToThisCache = moduleCacheDylibs;
2187 frameworksNeededToLinkToThisCache = moduleCacheFrameworks;
2194 map<string, VuoCompilerModule *> allModules;
2195 allModules.insert(nodeClasses.begin(), nodeClasses.end());
2196 allModules.insert(types.begin(), types.end());
2197 allModules.insert(libraryModules.begin(), libraryModules.end());
2199 set<string> dependencies;
2200 for (map<string, VuoCompilerModule *>::iterator i = allModules.begin(); i != allModules.end(); ++i)
2202 string moduleKey = i->first;
2207 if (module->requiresPro())
2215 cacheableModulesAndDependencies.insert(moduleKey);
2218 dependencies.insert(moduleDependencies.begin(), moduleDependencies.end());
2222 if (builtIn && ! generated)
2224 vector<string> coreDependencies = getCoreVuoDependencies();
2225 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
2230 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
2232 string dependency = *i;
2233 if (allModules.find(dependency) == allModules.end())
2236 frameworksNeededToLinkToThisCache.insert(dependency);
2239 string dependencyPath = VuoCompiler::getLibraryPath(dependency, librarySearchPaths);
2240 if (! dependencyPath.empty())
2243 dylibsNeededToLinkToThisCache.insert(dependencyPath);
2245 cacheableModulesAndDependencies.insert(dependency);
2251 moduleCacheDylibs = dylibsNeededToLinkToThisCache;
2252 moduleCacheFrameworks = frameworksNeededToLinkToThisCache;
2259 if (!vuoFrameworkInProgressPath.empty())
2260 currentModuleCacheDylib +=
"-" + VuoCompiler::getTargetArch(target);
2284void VuoCompiler::Environment::useModuleCache(
bool shouldUseExistingCache,
VuoCompiler *compiler,
2285 set<string> cacheableModulesAndDependencies,
2286 set<string> dylibsNeededToLinkToCaches, set<string> frameworksNeededToLinkToCaches,
2287 unsigned long lastPrerequisiteModuleCacheRebuild)
2291 static dispatch_once_t checked = 0;
2292 static bool prelinkCache =
true;
2293 dispatch_once(&checked, ^{
2295 bool result = CFPreferencesGetAppBooleanValue(CFSTR(
"prelinkCache"), CFSTR(
"org.vuo.Editor"), &valid);
2297 prelinkCache = result;
2301 VDebugLog(
"Ignoring the module cache since the 'prelinkCache' preference is false.");
2307 if (moduleCachePath.empty())
2313 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty &&
2314 (builtIn || lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild))
2316 VDebugLog(
"No need to recheck %s.", cacheDescription.c_str());
2322 VDebugLog(
"Checking if %s is up-to-date…", cacheDescription.c_str());
2324 bool isCacheUpToDate =
true;
2326 if (isModuleCacheInitialized && isModuleCacheableDataDirty)
2327 isCacheUpToDate =
false;
2329 isModuleCacheInitialized =
true;
2330 isModuleCacheableDataDirty =
false;
2333 if (!vuoFrameworkInProgressPath.empty())
2334 indexPath +=
"-" + VuoCompiler::getTargetArch(target);
2335 string dir, file, ext;
2337 string indexFileName = file +
"." + ext;
2344 if (shouldUseExistingCache)
2345 throw VuoException(
"Trying to use the existing cache, but the cache directory doesn't exist.",
false);
2348 isCacheUpToDate =
false;
2352 if (! indexFileExists)
2354 if (shouldUseExistingCache)
2355 throw VuoException(
"Trying to use the existing cache, but the cache index doesn't exist.",
false);
2358 isCacheUpToDate =
false;
2365 fileForLocking = moduleCacheFileForLocking[indexPath];
2366 if (! fileForLocking)
2369 moduleCacheFileForLocking[indexPath] = fileForLocking;
2373 VDebugLog(
"\tWarning: Couldn't lock for reading.");
2378 if (currentModuleCacheDylib.empty())
2381 if (shouldUseExistingCache && currentModuleCacheDylib.empty())
2382 throw VuoException(
"Trying to use the existing cache, but the cache dylib doesn't exist.",
false);
2386 if (isCacheUpToDate)
2387 isCacheUpToDate = lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild;
2391 if (isCacheUpToDate)
2396 if (shouldUseExistingCache)
2397 throw VuoException(
"Trying to use the existing cache, but the cache doesn't contain readable data.",
false);
2399 isCacheUpToDate =
false;
2405 const char separator =
'\n';
2406 if (isCacheUpToDate || shouldUseExistingCache)
2409 string index = indexFile.getContentsAsString();
2412 moduleCacheContents.clear();
2413 moduleCacheContents.insert(actualIndex.begin(), actualIndex.end());
2415 if (shouldUseExistingCache)
2417 isModuleCacheAvailable =
true;
2424 if (isCacheUpToDate)
2426 if (moduleCacheContents.size() != cacheableModulesAndDependencies.size())
2427 isCacheUpToDate =
false;
2430 set<string> contentsInBoth;
2431 std::set_intersection(moduleCacheContents.begin(), moduleCacheContents.end(),
2432 cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end(),
2433 std::inserter(contentsInBoth, contentsInBoth.begin()));
2435 if (contentsInBoth.size() != cacheableModulesAndDependencies.size())
2436 isCacheUpToDate =
false;
2442 if (isCacheUpToDate)
2446 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
2448 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2450 if (! j->second->isOlderThan(cacheLastModified))
2452 isCacheUpToDate =
false;
2461 if (isCacheUpToDate)
2465 isModuleCacheAvailable =
true;
2476 gettimeofday(&t, NULL);
2477 lastModuleCacheRebuild = t.tv_sec;
2480 dispatch_async(moduleCacheBuildingQueue, ^{
2481 VUserLog(
"Rebuilding %s…", cacheDescription.c_str());
2483 set<Module *> modulesToLink;
2484 set<string> librariesToLink;
2485 set<string> frameworksToLink;
2487 compiler->getLinkerInputs(cacheableModulesAndDependencies, Optimization_SmallBinary, modulesToLink, librariesToLink, frameworksToLink);
2489 librariesToLink.insert(dylibsNeededToLinkToCaches.begin(), dylibsNeededToLinkToCaches.end());
2490 frameworksToLink.insert(frameworksNeededToLinkToCaches.begin(), frameworksNeededToLinkToCaches.end());
2493 bool gotLockForWriting =
false;
2498 if (! gotLockForWriting)
2499 throw VuoException(
"The cache file is being used by another process. "
2500 "If any composition windows are open from previous Vuo sessions, quit them. "
2501 "If any processes whose names start with \"VuoComposition\" or one of your composition file names appear in Activity Monitor, force-quit them.",
2505 string dir, file, ext;
2508 vector<string> rPaths = compiler->getRunPathSearchPaths(
this);
2510 compiler->link(tmpPath, modulesToLink, librariesToLink, frameworksToLink,
true, rPaths,
false, issues);
2513 VUserLog(
"Warning: May not have fully rebuilt %s for the \"faster build\" optimization:\n%s", cacheDescription.c_str(), issues->
getLongDescription(
false).c_str());
2520 getVuoFrameworkPath() +
"/Helpers/install_name_tool",
2522 currentModuleCacheDylib,
2523 currentModuleCacheDylib,
2529 if (vuoFrameworkInProgressPath.empty())
2530 adHocCodeSign(currentModuleCacheDylib);
2533 vector<string> expectedContents(cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end());
2542 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2544 dispatch_sync(environmentQueue, ^{
2545 moduleCacheContents = cacheableModulesAndDependencies;
2546 isModuleCacheAvailable =
true;
2552 if (gotLockForWriting)
2554 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2556 VUserLog(
"Warning: Couldn't rebuild %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2564 if (vuoFrameworkInProgressPath.empty())
2565 VUserLog(
"Warning: Couldn't use %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2572void VuoCompiler::Environment::waitForModuleCachesToBuild(
void)
2574 dispatch_sync(moduleCacheBuildingQueue, ^{});
2586bool VuoCompiler::Environment::findInModuleCache(
const string &moduleOrDependency,
string &cachePath)
2588 if (isModuleCacheAvailable && moduleCacheContents.find(moduleOrDependency) != moduleCacheContents.end())
2590 cachePath = currentModuleCacheDylib;
2600string VuoCompiler::Environment::getCurrentModuleCacheDylib(
void)
2602 return currentModuleCacheDylib;
2609unsigned long VuoCompiler::Environment::getLastModuleCacheRebuild(
void)
2611 return lastModuleCacheRebuild;
2620void VuoCompiler::Environment::modulesChanged(
void)
2622 isModuleCacheableDataDirty =
true;
2623 isModuleCacheAvailable =
false;
2629bool VuoCompiler::Environment::isBuiltInOriginal()
2631 return builtIn && ! generated;
2637bool VuoCompiler::Environment::isBuiltIn()
2645bool VuoCompiler::Environment::isGenerated()
2653string VuoCompiler::Environment::getName()
2655 if (isBuiltInOriginal())
2657 else if (
this == sharedEnvironments[target][0][1])
2658 return "builtin (generated)";
2659 else if (
this == sharedEnvironments[target][1][0])
2661 else if (
this == sharedEnvironments[target][1][1])
2662 return "system (generated)";
2663 else if (
this == sharedEnvironments[target][2][0])
2665 else if (
this == sharedEnvironments[target][2][1])
2666 return "user (generated)";
2667 return "composition-local";
2673void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *))
2675 dispatch_sync(environmentQueue, ^{
2676 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2677 doForEnvironment((*i)[0]);
2685void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *,
bool *,
string),
bool *result,
string arg)
2687 dispatch_sync(environmentQueue, ^{
2688 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2689 doForEnvironment((*i)[0], result, arg);
2697void VuoCompiler::applyToAllEnvironments(
void (^doForEnvironment)(Environment *environment))
2699 dispatch_sync(environmentQueue, ^{
2700 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2701 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j) {
2702 doForEnvironment(*j);
2725 this->target = target = getProcessTarget();
2726 VDebugLog(
"%p target=%s (from current process)",
this, this->target.c_str());
2730 this->target = target;
2731 VDebugLog(
"%p target=%s",
this, this->target.c_str());
2738 shouldLoadAllModules =
true;
2739 hasLoadedAllModules =
false;
2740 modulesToLoadQueue = dispatch_queue_create(
"org.vuo.compiler.modules", NULL);
2741 moduleSourceCompilersExist = dispatch_group_create();
2742 moduleCacheBuilding = dispatch_group_create();
2743 dependencyGraph = NULL;
2744 compositionDependencyGraph = NULL;
2746 _shouldShowSplashWindow =
false;
2748 delegateQueue = dispatch_queue_create(
"org.vuo.compiler.delegate", NULL);
2751 if (! vuoFrameworkPath.empty())
2752 clangPath = vuoFrameworkPath +
"/Helpers/clang";
2754 clangPath = LLVM_ROOT
"/bin/clang";
2756 dispatch_sync(environmentQueue, ^{
2757 allCompilers.insert(
this);
2759 if (sharedEnvironments[target].empty())
2761 sharedEnvironments[target] = vector< vector<Environment *> >(3, vector<Environment *>(2, NULL));
2762 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2763 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2764 *j =
new Environment(this->target, i == sharedEnvironments[target].begin(), j != i->begin());
2766 vector<string> builtInModuleSearchPaths = Environment::getBuiltInModuleSearchPaths();
2767 for (vector<string>::iterator i = builtInModuleSearchPaths.begin(); i != builtInModuleSearchPaths.end(); ++i)
2768 sharedEnvironments[target][0][0]->addModuleSearchPath(*i,
false);
2770 vector<string> builtInHeaderSearchPaths = Environment::getBuiltInHeaderSearchPaths();
2771 for (vector<string>::iterator i = builtInHeaderSearchPaths.begin(); i != builtInHeaderSearchPaths.end(); ++i)
2772 sharedEnvironments[target][0][0]->addHeaderSearchPath(*i);
2774 vector<string> builtInLibrarySearchPaths = Environment::getBuiltInLibrarySearchPaths();
2775 for (vector<string>::iterator i = builtInLibrarySearchPaths.begin(); i != builtInLibrarySearchPaths.end(); ++i)
2776 sharedEnvironments[target][0][0]->addLibrarySearchPath(*i);
2778 vector<string> builtInFrameworkSearchPaths = Environment::getBuiltInFrameworkSearchPaths();
2779 for (vector<string>::iterator i = builtInFrameworkSearchPaths.begin(); i != builtInFrameworkSearchPaths.end(); ++i)
2780 sharedEnvironments[target][0][0]->addFrameworkSearchPath(*i);
2794 if (! vuoFrameworkPath.empty())
2796 vector<string> moduleCachePaths(3);
2797 moduleCachePaths[0] = vuoFrameworkPath +
"/Modules/Builtin";
2801 for (
size_t i = 0; i < moduleCachePaths.size(); ++i)
2803 string moduleCachePath = moduleCachePaths[i];
2805 sharedEnvironments[target][i][0]->setModuleCachePath(moduleCachePath,
true);
2806 sharedEnvironments[target][i][1]->setModuleCachePath(moduleCachePath,
false);
2824 dispatch_sync(environmentQueue, ^{
2825 allCompilers.erase(
this);
2828 dispatch_group_wait(moduleCacheBuilding, DISPATCH_TIME_FOREVER);
2829 dispatch_release(moduleCacheBuilding);
2831 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
2832 (*i)[0]->removeCompilerToNotify(
this);
2834 dispatch_sync(delegateQueue, ^{});
2836 dispatch_release(modulesToLoadQueue);
2837 dispatch_release(delegateQueue);
2839 delete dependencyGraph;
2840 delete compositionDependencyGraph;
2846void VuoCompiler::reset(
void)
2848 dispatch_group_wait(moduleSourceCompilersExistGlobally, DISPATCH_TIME_FOREVER);
2850 dispatch_sync(environmentQueue, ^{
2852 for (
auto e : sharedEnvironments)
2853 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2855 (*i)[0]->stopWatchingModuleSearchPaths();
2856 dispatch_sync((*i)[0]->moduleSearchPathContentsChangedQueue, ^{});
2859 for (
auto e : environmentsForCompositionFamily)
2860 for (map<
string, vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2862 (i->second)[0]->stopWatchingModuleSearchPaths();
2863 dispatch_sync((i->second)[0]->moduleSearchPathContentsChangedQueue, ^{});
2866 for (
auto e : sharedEnvironments)
2867 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2868 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2871 for (
auto e : environmentsForCompositionFamily)
2872 for (map<
string, vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2873 for (vector<Environment *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2876 allCompilers.clear();
2877 sharedEnvironments.clear();
2878 environmentsForCompositionFamily.clear();
2890 dispatch_async(delegateQueue, ^{
2891 this->delegate = delegate;
2906 string compositionModulesDir;
2907 string compositionBaseDir;
2908 lastCompositionIsSubcomposition =
false;
2909 if (! compositionPath.empty())
2917 string compositionDir;
2920 lastCompositionIsSubcomposition = (compositionDir == compositionModulesDir);
2925 dispatch_sync(environmentQueue, ^{
2926 if (! environments.empty() && compositionBaseDir == lastCompositionBaseDir) {
2929 lastCompositionBaseDir = compositionBaseDir;
2933 Environment *oldCompositionFamilyInstalledEnvironment =
nullptr;
2934 vector<Environment *> compositionEnvironments;
2935 if (! environments.empty())
2937 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2938 (*i)[0]->removeCompilerToNotify(this);
2941 if (environments.size() >= 5) {
2942 oldCompositionFamilyInstalledEnvironment = environments[3][0];
2945 compositionEnvironments = environments.back();
2947 environments.clear();
2954 bool isCompositionInSharedEnvironment =
false;
2955 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2957 environments.push_back(*i);
2959 vector<string> moduleSearchPaths = (*i)[0]->getModuleSearchPaths();
2960 for (vector<string>::iterator j = moduleSearchPaths.begin(); j != moduleSearchPaths.end(); ++j)
2962 string moduleSearchPath = *j;
2963 VuoFileUtilities::canonicalizePath(moduleSearchPath);
2964 if (moduleSearchPath == compositionModulesDir)
2966 isCompositionInSharedEnvironment = true;
2971 if (isCompositionInSharedEnvironment) {
2978 Environment *newCompositionFamilyInstalledEnvironment =
nullptr;
2979 if (! isCompositionInSharedEnvironment && ! compositionPath.empty())
2981 vector<Environment *> compositionFamilyEnvironments = environmentsForCompositionFamily[target][compositionBaseDir];
2982 if (compositionFamilyEnvironments.empty())
2984 compositionFamilyEnvironments = vector<Environment *>(2, NULL);
2985 compositionFamilyEnvironments[0] = new Environment(this->target, false, false);
2986 compositionFamilyEnvironments[1] = new Environment(this->target, false, true);
2987 environmentsForCompositionFamily[target][compositionBaseDir] = compositionFamilyEnvironments;
2991 compositionFamilyEnvironments[0]->addModuleSearchPath(compositionModulesDir);
2995 string moduleCachePath = getCachePathForComposition(compositionBaseDir);
2997 compositionFamilyEnvironments[0]->setModuleCachePath(moduleCachePath, true);
2998 compositionFamilyEnvironments[1]->setModuleCachePath(moduleCachePath, false);
3000 environments.push_back(compositionFamilyEnvironments);
3002 newCompositionFamilyInstalledEnvironment = compositionFamilyEnvironments[0];
3007 if (compositionEnvironments.empty())
3009 compositionEnvironments = vector<Environment *>(2, NULL);
3010 compositionEnvironments[0] = new Environment(this->target, false, false);
3011 compositionEnvironments[1] = new Environment(this->target, false, true);
3013 environments.push_back(compositionEnvironments);
3015 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
3016 (*i)[0]->addCompilerToNotify(this);
3019 delete dependencyGraph;
3020 delete compositionDependencyGraph;
3021 dependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getDependencyGraph(); });
3022 compositionDependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getCompositionDependencyGraph(); });
3027 if (oldCompositionFamilyInstalledEnvironment != newCompositionFamilyInstalledEnvironment)
3029 auto getModules = [] (Environment *env)
3031 map<string, VuoCompilerModule *> modules;
3034 for (
auto i : env->getNodeClasses()) {
3037 for (
auto i : env->getTypes()) {
3040 for (
auto i : env->getLibraryModules()) {
3047 map<string, VuoCompilerModule *> modulesAdded = getModules(newCompositionFamilyInstalledEnvironment);
3048 map<string, VuoCompilerModule *> modulesRemoved = getModules(oldCompositionFamilyInstalledEnvironment);
3050 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified;
3051 for (map<string, VuoCompilerModule *>::iterator
add = modulesAdded.begin();
add != modulesAdded.end(); )
3053 map<string, VuoCompilerModule *>::iterator rem = modulesRemoved.find(
add->first);
3054 if (rem != modulesRemoved.end())
3056 modulesModified[
add->first] = make_pair(rem->second,
add->second);
3057 modulesAdded.erase(
add++);
3058 modulesRemoved.erase(rem);
3066 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty()) )
3069 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues);
3070 delegateData->retain();
3072 Environment *scopeEnvironment = newCompositionFamilyInstalledEnvironment;
3073 if (! scopeEnvironment) {
3074 scopeEnvironment = compositionEnvironments.at(0);
3077 loadedModules(modulesAdded, modulesModified, modulesRemoved, issues, delegateData, scopeEnvironment);
3091 if (!graphForEnvironment)
3096 for (vector< vector<Environment *> >::const_iterator i = environments.begin(); i != environments.end(); ++i)
3100 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(i->at(1)));
3104 for (vector< vector<Environment *> >::const_iterator ii = environments.begin(); ii != i; ++ii)
3106 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(ii->at(0)));
3107 network->
addEdge(graphForEnvironment(i->at(1)), graphForEnvironment(ii->at(0)));
3134void VuoCompiler::loadModulesIfNeeded(
const set<string> &moduleKeys)
3136 __block
bool willLoadAllModules =
false;
3137 if (moduleKeys.empty())
3139 dispatch_sync(modulesToLoadQueue, ^{
3140 if (shouldLoadAllModules && ! hasLoadedAllModules) {
3141 willLoadAllModules =
true;
3142 hasLoadedAllModules =
true;
3147 if (! willLoadAllModules && moduleKeys.empty())
3152 dispatch_group_enter(moduleSourceCompilersExist);
3153 __block set<dispatch_group_t> sourcesLoading;
3154 dispatch_sync(environmentQueue, ^{
3155 sourcesLoading = loadModulesAndSources(moduleKeys, set<string>(), set<string>(),
3156 moduleKeys, set<string>(), set<string>(),
3157 willLoadAllModules,
false,
nullptr,
nullptr,
nullptr,
"");
3163 for (set<dispatch_group_t>::iterator i = sourcesLoading.begin(); i != sourcesLoading.end(); ++i)
3165 dispatch_group_wait(*i, DISPATCH_TIME_FOREVER);
3166 dispatch_release(*i);
3168 dispatch_group_leave(moduleSourceCompilersExist);
3179set<dispatch_group_t> VuoCompiler::loadModulesAndSources(
const set<string> &modulesAddedKeys,
const set<string> &modulesModifiedKeys,
const set<string> &modulesRemovedKeys,
3180 const set<string> &sourcesAddedKeys,
const set<string> &sourcesModifiedKeys,
const set<string> &sourcesRemovedKeys,
3181 bool willLoadAllModules,
bool shouldRecompileSourcesIfUnchanged,
3182 Environment *currentEnvironment,
VuoCompilerIssues *issuesForCurrentEnvironment,
3183 std::function<
void(
void)> moduleLoadedCallback,
const string &moduleAddedOrModifiedSourceCode)
3195 map<Environment *, set<string> > modulesAdded;
3196 map<Environment *, set<string> > modulesModified;
3197 map<Environment *, set<string> > modulesRemoved;
3198 map<Environment *, set<string> > sourcesAdded;
3199 map<Environment *, set<string> > sourcesModified;
3200 map<Environment *, set<string> > sourcesRemoved;
3201 map<Environment *, set<string> > potentialSpecializedModules;
3203 if (currentEnvironment)
3205 modulesAdded[currentEnvironment] = modulesAddedKeys;
3206 modulesModified[currentEnvironment] = modulesModifiedKeys;
3207 modulesRemoved[currentEnvironment] = modulesRemovedKeys;
3208 sourcesAdded[currentEnvironment] = sourcesAddedKeys;
3209 sourcesModified[currentEnvironment] = sourcesModifiedKeys;
3210 sourcesRemoved[currentEnvironment] = sourcesRemovedKeys;
3214 Environment *genEnv =
nullptr;
3215 if (! willLoadAllModules)
3221 int scope = environments.size() - (lastCompositionIsSubcomposition ? 2 : 1);
3222 genEnv = environments.at(scope).at(1);
3223 potentialSpecializedModules[genEnv] = modulesAddedKeys;
3226 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3228 Environment *env = (*i).at(0);
3230 ModuleInfoIterator modulesAddedIter = (willLoadAllModules ? env->listAllModules() : env->listModules(modulesAddedKeys));
3231 ModuleInfoIterator sourcesAddedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesAddedKeys));
3232 ModuleInfoIterator sourcesModifiedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesModifiedKeys));
3234 ModuleInfo *moduleInfo;
3235 while ((moduleInfo = modulesAddedIter.next()))
3237 string moduleKey = moduleInfo->getModuleKey();
3239 modulesAdded[env].insert(moduleKey);
3241 if (! willLoadAllModules)
3243 auto foundIter = potentialSpecializedModules[genEnv].find(moduleKey);
3244 if (foundIter != potentialSpecializedModules[genEnv].end())
3245 potentialSpecializedModules[genEnv].erase(foundIter);
3251 auto isCompiledModuleAtSameSearchPath = [&env] (ModuleInfo *sourceInfo)
3253 ModuleInfo *compiledModuleInfo = env->listModule(sourceInfo->getModuleKey());
3254 return (compiledModuleInfo && compiledModuleInfo->getSearchPath() == sourceInfo->getSearchPath());
3257 while ((moduleInfo = sourcesAddedIter.next()))
3259 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3262 sourcesAdded[env].insert( moduleInfo->getModuleKey() );
3265 while ((moduleInfo = sourcesModifiedIter.next()))
3267 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3270 sourcesModified[env].insert( moduleInfo->getModuleKey() );
3275 map<Environment *, VuoCompilerIssues *> issues;
3276 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3278 Environment *env = (*i).at(0);
3279 issues[env] = (env == currentEnvironment && issuesForCurrentEnvironment ? issuesForCurrentEnvironment :
new VuoCompilerIssues());
3284 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3286 Environment *env = (*i).at(0);
3291 set<VuoDirectedAcyclicGraph::Vertex *> circularDependencies = env->getCompositionDependencyGraph()->getCycleVertices();
3293 set<string> sourcesAddedModified;
3294 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3295 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3297 for (set<string>::iterator j = sourcesAddedModified.begin(); j != sourcesAddedModified.end(); ++j)
3299 string moduleKey = *j;
3302 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator k = circularDependencies.begin(); k != circularDependencies.end(); ++k)
3304 DependencyGraphVertex *vertex =
static_cast<DependencyGraphVertex *
>(*k);
3305 if (vertex->getDependency() == moduleKey)
3314 sourcesAdded[env].erase(moduleKey);
3315 sourcesModified[env].erase(moduleKey);
3318 "Subcomposition contains itself",
3319 "%moduleKey contains an instance of itself, "
3320 "or contains another subcomposition that contains an instance of %moduleKey.");
3321 issue.setModuleKey(moduleKey);
3323 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3325 issue.setFilePath(sourceInfo->getFile()->path());
3327 issues[env]->append(issue);
3334 for (
const vector<Environment *> &envs : environments)
3336 Environment *env = envs.at(0);
3338 set<string> sourcesAddedModified;
3339 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3340 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3342 for (
const string &moduleKey : sourcesAddedModified)
3345 int pathLength = env->getCompositionDependencyGraph()->getLongestDownstreamPath(vertex);
3347 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3348 sourceInfo->setLongestDownstreamPath(pathLength);
3356 map<Environment *, set<string> > modulesDepOnModulesModified;
3357 map<Environment *, set<string> > sourcesDepOnModulesModified;
3358 map<Environment *, set<string> > modulesDepOnModulesRemoved;
3359 map<Environment *, set<string> > sourcesDepOnModulesRemoved;
3362 __block map<Environment *, set<string> > modulesDepOnModulesModified_otherCompiler;
3363 __block map<Environment *, set<string> > sourcesDepOnModulesModified_otherCompiler;
3364 __block map<Environment *, set<string> > modulesDepOnModulesRemoved_otherCompiler;
3365 __block map<Environment *, set<string> > sourcesDepOnModulesRemoved_otherCompiler;
3367 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3369 searchDependencyGraphs.push_back(compiler->dependencyGraph);
3371 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getDependencyGraph() :
nullptr);
3373 findDependentModulesAndSources(modulesModified, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3374 modulesDepOnModulesModified, modulesDepOnModulesModified_otherCompiler,
3375 sourcesDepOnModulesModified, sourcesDepOnModulesModified_otherCompiler);
3377 findDependentModulesAndSources(modulesRemoved, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3378 modulesDepOnModulesRemoved, modulesDepOnModulesRemoved_otherCompiler,
3379 sourcesDepOnModulesRemoved, sourcesDepOnModulesRemoved_otherCompiler);
3381 set<Environment *> otherEnvironments;
3382 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesModified_otherCompiler.begin(); i != modulesDepOnModulesModified_otherCompiler.end(); ++i)
3383 otherEnvironments.insert(i->first);
3384 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesModified_otherCompiler.begin(); i != sourcesDepOnModulesModified_otherCompiler.end(); ++i)
3385 otherEnvironments.insert(i->first);
3386 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesRemoved_otherCompiler.begin(); i != modulesDepOnModulesRemoved_otherCompiler.end(); ++i)
3387 otherEnvironments.insert(i->first);
3388 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesRemoved_otherCompiler.begin(); i != sourcesDepOnModulesRemoved_otherCompiler.end(); ++i)
3389 otherEnvironments.insert(i->first);
3391 for (Environment *env : otherEnvironments)
3395 for (
const vector<Environment *> &ee : c->environments)
3396 for (Environment *e : ee)
3400 goto foundOtherCompiler;
3404 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3405 dispatch_sync(environmentQueue, ^{
3406 otherCompiler->loadModulesAndSources(set<string>(), modulesDepOnModulesModified_otherCompiler[env], modulesDepOnModulesRemoved_otherCompiler[env],
3407 set<string>(), sourcesDepOnModulesModified_otherCompiler[env], sourcesDepOnModulesRemoved_otherCompiler[env],
3408 false,
true, env,
nullptr,
nullptr,
"");
3418 map<Environment *, set<VuoCompilerModule *> > actualModulesRemoved;
3419 for (
const vector<Environment *> &envs : environments)
3421 for (Environment *env : envs)
3423 set<string> modulesToUnload;
3424 modulesToUnload.insert(modulesRemoved[env].begin(), modulesRemoved[env].end());
3425 modulesToUnload.insert(modulesModified[env].begin(), modulesModified[env].end());
3426 modulesToUnload.insert(modulesDepOnModulesRemoved[env].begin(), modulesDepOnModulesRemoved[env].end());
3427 modulesToUnload.insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3429 actualModulesRemoved[env] = env->unloadCompiledModules(modulesToUnload);
3431 if (!env->isBuiltInOriginal() && !actualModulesRemoved[env].empty())
3433 set<string> actualModulesRemovedKeys;
3434 for (
auto m : actualModulesRemoved[env])
3435 actualModulesRemovedKeys.insert(m->getPseudoBase()->getModuleKey());
3448 map<Environment *, set<string> > modulesToLoad;
3449 map<Environment *, map<string, string> > modulesToLoadSourceCode;
3450 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3452 Environment *env = (*i).at(0);
3454 if (! modulesAdded[env].empty())
3455 modulesToLoad[env].insert(modulesAdded[env].begin(), modulesAdded[env].end());
3456 if (! modulesModified[env].empty())
3457 modulesToLoad[env].insert(modulesModified[env].begin(), modulesModified[env].end());
3458 if (! modulesDepOnModulesModified[env].empty())
3459 modulesToLoad[env].insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3461 if (env == currentEnvironment && moduleLoadedCallback)
3463 if (modulesAdded[env].size() == 1)
3464 modulesToLoadSourceCode[env][*modulesAdded[env].begin()] = moduleAddedOrModifiedSourceCode;
3465 else if (modulesModified[env].size() == 1)
3466 modulesToLoadSourceCode[env][*modulesModified[env].begin()] = moduleAddedOrModifiedSourceCode;
3470 map<Environment *, set<VuoCompilerModule *> > actualModulesAdded;
3471 while (! modulesToLoad.empty())
3473 set<string> dependenciesToLoad;
3474 map<Environment *, set<string> > potentialSpecializedDependencies;
3475 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3477 Environment *env = (*i).at(0);
3478 Environment *genEnv = (*i).at(1);
3480 set<VuoCompilerModule *> actualModulesLoaded = env->loadCompiledModules(modulesToLoad[env], modulesToLoadSourceCode[env]);
3482 actualModulesAdded[env].insert(actualModulesLoaded.begin(), actualModulesLoaded.end());
3483 modulesToLoad.erase(env);
3485 for (set<VuoCompilerModule *>::iterator j = actualModulesLoaded.begin(); j != actualModulesLoaded.end(); ++j)
3487 set<string> dependencies = (*j)->getDependencies();
3488 dependenciesToLoad.insert(dependencies.begin(), dependencies.end());
3489 potentialSpecializedDependencies[genEnv].insert(dependencies.begin(), dependencies.end());
3492 if (!env->isBuiltInOriginal() && !actualModulesLoaded.empty())
3494 map<string, string> actualFilesAndHashesLoaded;
3495 for (
auto module : actualModulesLoaded)
3503 if (cnc && !cnc->getSourcePath().empty())
3506 if (!cnc->getSourceCode().empty())
3521 actualFilesAndHashesLoaded[path] = hash;
3524 for (pair<string, string> item : actualFilesAndHashesLoaded)
3525 VUserLog(
"Loaded into %s environment: [%8.8s] %s", env->getName().c_str(), item.second.c_str(), item.first.c_str());
3529 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3531 Environment *env = (*i).at(0);
3533 ModuleInfoIterator dependenciesInEnv = env->listModules(dependenciesToLoad);
3534 ModuleInfo *moduleInfo;
3535 while ((moduleInfo = dependenciesInEnv.next()))
3537 modulesToLoad[env].insert( moduleInfo->getModuleKey() );
3539 for (map<Environment *, set<string> >::iterator j = potentialSpecializedDependencies.begin(); j != potentialSpecializedDependencies.end(); ++j)
3541 auto foundIter = j->second.find( moduleInfo->getModuleKey() );
3542 if (foundIter != j->second.end())
3543 j->second.erase(foundIter);
3548 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3550 Environment *genEnv = (*i).at(1);
3551 potentialSpecializedModules[genEnv].insert(potentialSpecializedDependencies[genEnv].begin(), potentialSpecializedDependencies[genEnv].end());
3558 set<dispatch_group_t> specializedModulesLoading;
3559 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3561 Environment *genEnv = (*i).at(1);
3562 set<dispatch_group_t> s = genEnv->loadSpecializedModules(potentialSpecializedModules[genEnv],
this,
llvmQueue);
3563 specializedModulesLoading.insert(s.begin(), s.end());
3568 if (moduleLoadedCallback)
3569 moduleLoadedCallback();
3573 map<Environment *, set< pair<VuoCompilerModule *, VuoCompilerModule *> > > actualModulesModified;
3574 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3576 Environment *env = (*i).at(0);
3578 for (set<VuoCompilerModule *>::iterator
add = actualModulesAdded[env].begin();
add != actualModulesAdded[env].end(); )
3580 set<VuoCompilerModule *>::iterator rem;
3581 for (rem = actualModulesRemoved[env].begin(); rem != actualModulesRemoved[env].end(); ++rem)
3582 if ((*rem)->getPseudoBase()->getModuleKey() == (*add)->getPseudoBase()->getModuleKey())
3585 if (rem != actualModulesRemoved[env].end())
3587 actualModulesModified[env].insert( make_pair(*rem, *
add) );
3588 actualModulesRemoved[env].erase(rem);
3589 actualModulesAdded[env].erase(
add++);
3598 bool wereModulesAddedOrModified =
false;
3599 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3601 Environment *env = (*i).at(0);
3602 if (! (actualModulesAdded[env].empty() && actualModulesModified[env].empty()) )
3604 wereModulesAddedOrModified =
true;
3609 if (wereModulesAddedOrModified)
3611 map<string, VuoCompilerType *> inheritedTypes;
3612 for (
const vector<Environment *> &envs : environments)
3614 for (Environment *env : envs)
3616 env->reifyPortTypes(inheritedTypes);
3617 map<string, VuoCompilerType *> envTypes = env->getTypes();
3618 inheritedTypes.insert(envTypes.begin(), envTypes.end());
3627 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3629 Environment *env = (*i).at(0);
3631 set<string> sourcesToUnload;
3632 sourcesToUnload.insert(sourcesRemoved[env].begin(), sourcesRemoved[env].end());
3633 sourcesToUnload.insert(sourcesDepOnModulesRemoved[env].begin(), sourcesDepOnModulesRemoved[env].end());
3634 if (! sourcesToUnload.empty())
3636 string moduleSearchPath = env->getModuleSearchPaths().front();
3638 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3641 dispatch_sync(environmentQueue, ^{
3642 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), sourcesToUnload,
3643 set<string>(), set<string>(), set<string>(),
3644 false,
false, env,
nullptr,
nullptr,
"");
3647 delete otherCompiler;
3651 if (!env->isBuiltInOriginal() && !sourcesToUnload.empty())
3654 env->deleteModulesCompiledFromSourceCode(sourcesToUnload);
3662 map<Environment *, set<string> > sourcesDepOnModulesAdded;
3664 map<Environment *, set<string> > modulesDepOnModulesAdded;
3665 __block map<Environment *, set<string> > modulesDepOnModulesAdded_otherCompiler;
3666 __block map<Environment *, set<string> > sourcesDepOnModulesAdded_otherCompiler;
3668 map<Environment *, set<string> > actualModuleKeysAdded;
3669 for (
const vector<Environment *> &envs : environments)
3671 Environment *env = envs.at(0);
3676 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3677 searchDependencyGraphs.push_back(compositionDependencyGraph);
3678 for (map<
string, vector<Environment *> >::iterator ii = environmentsForCompositionFamily[target].begin(); ii != environmentsForCompositionFamily[target].end(); ++ii)
3680 vector< vector<Environment *> > otherEnvs = sharedEnvironments[target];
3681 otherEnvs.push_back(ii->second);
3683 searchDependencyGraphs.push_back(other);
3686 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getCompositionDependencyGraph() :
nullptr);
3688 findDependentModulesAndSources(actualModuleKeysAdded, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3689 modulesDepOnModulesAdded, modulesDepOnModulesAdded_otherCompiler,
3690 sourcesDepOnModulesAdded, sourcesDepOnModulesAdded_otherCompiler);
3692 set<Environment *> otherEnvironments;
3693 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesAdded_otherCompiler.begin(); i != sourcesDepOnModulesAdded_otherCompiler.end(); ++i)
3694 otherEnvironments.insert(i->first);
3696 for (Environment *env : otherEnvironments)
3698 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3699 string moduleSearchPath = env->getModuleSearchPaths().front();
3702 dispatch_sync(environmentQueue, ^{
3703 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), set<string>(),
3704 sourcesDepOnModulesAdded_otherCompiler[env], set<string>(), set<string>(),
3705 false,
true, env,
nullptr,
nullptr,
"");
3708 delete otherCompiler;
3713 set<dispatch_group_t> sourcesLoading;
3714 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3716 Environment *env = (*i).at(0);
3718 set<string> sourcesToCompile;
3719 sourcesToCompile.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3720 sourcesToCompile.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3722 if (sourcesToCompile.size() == 0)
3725 set<dispatch_group_t> s = env->compileModulesFromSourceCode(sourcesToCompile, shouldRecompileSourcesIfUnchanged);
3726 sourcesLoading.insert(s.begin(), s.end());
3729 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3731 Environment *env = (*i).at(0);
3733 set<string> sourcesToCompile;
3734 sourcesToCompile.insert(sourcesDepOnModulesAdded[env].begin(), sourcesDepOnModulesAdded[env].end());
3735 sourcesToCompile.insert(sourcesDepOnModulesModified[env].begin(), sourcesDepOnModulesModified[env].end());
3737 if (sourcesToCompile.size() == 0)
3740 env->compileModulesFromSourceCode(sourcesToCompile,
true);
3745 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3747 Environment *env = (*i).at(0);
3748 env->notifyCompilers(actualModulesAdded[env], actualModulesModified[env], actualModulesRemoved[env], issues[env]);
3755 for (
const dispatch_group_t &group : sourcesLoading)
3756 dispatch_retain(group);
3758 set<dispatch_group_t> loadingGroups;
3759 loadingGroups.insert(specializedModulesLoading.begin(), specializedModulesLoading.end());
3760 loadingGroups.insert(sourcesLoading.begin(), sourcesLoading.end());
3761 return loadingGroups;
3775void VuoCompiler::findDependentModulesAndSources(map<Environment *, set<string> > &changedModules,
3776 const vector<VuoDirectedAcyclicNetwork *> &searchDependencyGraphs,
3778 map<Environment *, set<string> > &modulesDepOnChangedModules_this,
3779 map<Environment *, set<string> > &modulesDepOnChangedModules_other,
3780 map<Environment *, set<string> > &sourcesDepOnChangedModules_this,
3781 map<Environment *, set<string> > &sourcesDepOnChangedModules_other)
3783 for (
const vector<Environment *> &envs : environments)
3785 Environment *env = envs.at(0);
3787 for (
const string &module : changedModules[env])
3789 set<VuoDirectedAcyclicGraph::Vertex *> dependents;
3792 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices;
3793 if (currentEnvironmentDependencyGraph)
3799 moduleVertices.push_back(mv);
3802 moduleVertices = searchDependencyGraph->findVertex(module);
3806 DependencyGraphVertex *moduleVertex =
static_cast<DependencyGraphVertex *
>(moduleVertexRaw);
3807 if (moduleVertex->getEnvironment())
3809 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = searchDependencyGraph->getUpstreamVertices(moduleVertex);
3810 dependents.insert(upstream.begin(), upstream.end());
3815 set< pair<Environment *, string> > dependentsMap;
3818 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(dependentVertexRaw);
3819 Environment *dependentEnv = v->getEnvironment();
3823 string dependent = v->getDependency();
3825 dependentsMap.insert({dependentEnv, dependent});
3831 for (
auto i : envs.at(1)->getNodeClasses())
3835 dependentsMap.insert({envs.at(1), i.first});
3838 for (
auto i : dependentsMap)
3840 Environment *dependentEnv = i.first;
3841 string dependent = i.second;
3845 if (changedModules[dependentEnv].find(dependent) != changedModules[dependentEnv].end())
3848 ModuleInfo *foundSourceInfo = dependentEnv->listSourceFile(dependent);
3849 ModuleInfo *foundModuleInfo = dependentEnv->listModule(dependent);
3851 bool belongsToCurrentCompiler =
false;
3852 for (
const vector<Environment *> &envs2 : environments)
3854 if (find(envs2.begin(), envs2.end(), dependentEnv) != envs2.end())
3856 belongsToCurrentCompiler =
true;
3861 map<Environment *, set<string> > *whicheverDependents =
nullptr;
3862 ModuleInfo *moduleInfo =
nullptr;
3863 if (foundSourceInfo)
3865 moduleInfo = foundSourceInfo;
3866 whicheverDependents = (belongsToCurrentCompiler ? &sourcesDepOnChangedModules_this : &sourcesDepOnChangedModules_other);
3868 else if (foundModuleInfo)
3870 moduleInfo = foundModuleInfo;
3871 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3875 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3878 (*whicheverDependents)[dependentEnv].insert(dependent);
3880 moduleInfo->setAttempted(
false);
3889void VuoCompiler::loadedModules(map<string, VuoCompilerModule *> modulesAdded,
3890 map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified,
3891 map<string, VuoCompilerModule *> modulesRemoved,
3892 VuoCompilerIssues *issues,
void *delegateDataV, Environment *currentEnvironment)
3904 auto findVersionsOfModule = [
this, currentEnvironment] (
const string &moduleKey)
3906 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions;
3907 for (
const vector<Environment *> &envs : environments)
3909 Environment *env = envs.at(0);
3911 if (module || env == currentEnvironment)
3912 moduleVersions.push_back( make_pair(env, module) );
3914 return moduleVersions;
3917 for (map<string, VuoCompilerModule *>::iterator i = modulesAdded.begin(); i != modulesAdded.end(); )
3919 string moduleKey = i->first;
3922 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3924 if (moduleVersions.size() > 1)
3926 modulesAdded.erase(i++);
3928 if (moduleVersions.back().second == moduleAdded)
3930 VuoCompilerModule *moduleSuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3931 modulesModified[moduleKey] = make_pair(moduleSuperseded, moduleAdded);
3938 for (map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); )
3940 string moduleKey = i->first;
3943 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3945 if (moduleVersions.size() > 1 && moduleVersions.back().second != moduleModified)
3946 modulesModified.erase(i++);
3951 for (map<string, VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); )
3953 string moduleKey = i->first;
3956 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3958 if (moduleVersions.size() > 1)
3960 modulesRemoved.erase(i++);
3962 if (moduleVersions.back().first == currentEnvironment)
3964 VuoCompilerModule *moduleUnsuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3965 modulesModified[moduleKey] = make_pair(moduleRemoved, moduleUnsuperseded);
3972 dispatch_async(delegateQueue, ^{
3973 VuoCompilerDelegate::LoadedModulesData *delegateData =
static_cast<VuoCompilerDelegate::LoadedModulesData *
>(delegateDataV);
3975 if (delegate && ! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()))
3977 delegate->enqueueData(delegateData);
3978 delegate->
loadedModules(modulesAdded, modulesModified, modulesRemoved, issues);
3982 delegateData->release();
3992void VuoCompiler::loadNodeClassGeneratedAtRuntime(
VuoCompilerNodeClass *nodeClass, Environment *env)
3994 Module *module = nodeClass->
getModule();
3998 setTargetForModule(nodeClass->
getModule(), env->getTarget());
4002 dispatch_sync(environmentQueue, ^{
4003 env->replaceNodeClass(nodeClass);
4006 __block map<string, VuoCompilerType *> inheritedTypes;
4007 void (^envReifyPortTypes)(Environment *) = ^
void (Environment *env) {
4008 env->reifyPortTypes(inheritedTypes);
4009 map<string, VuoCompilerType *> currentTypes = env->getTypes();
4010 inheritedTypes.insert(currentTypes.begin(), currentTypes.end());
4012 applyToAllEnvironments(envReifyPortTypes);
4021 reifyGenericPortTypes(node->getBase());
4029void VuoCompiler::reifyGenericPortTypes(
VuoNode *node)
4039 vector<VuoPort *> ports;
4040 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
4041 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
4043 for (vector<VuoPort *>::iterator j = ports.begin(); j != ports.end(); ++j)
4090 vector<string> allIncludePaths = includePaths;
4091 string preprocessedInputPath = inputPath;
4093 string tmpPreprocessedInputDir;
4094 string dir, file, ext;
4099 string preprocessedInputContents = inputContents;
4101 if (inputContents != preprocessedInputContents)
4104 allIncludePaths.push_back(dir.empty() ?
"." : dir);
4106 preprocessedInputPath = tmpPreprocessedInputDir +
"/" + file +
"." + ext;
4111 else if (ext ==
"fs")
4117 auto getType = [
this] (
const string &moduleKey) {
return this->
getType(moduleKey); };
4122 setTargetForModule(module, target);
4123 writeModuleToBitcode(module, outputPath);
4125 string dependencyOutputPath = _dependencyOutput();
4126 if (!dependencyOutputPath.empty())
4128 string outputObjectPath = dependencyOutputPath.substr(0, dependencyOutputPath.length() - 2);
4141 vector<string> extraArgs;
4142 for (vector<string>::iterator i = allIncludePaths.begin(); i != allIncludePaths.end(); ++i)
4144 extraArgs.push_back(
"-I");
4145 extraArgs.push_back(*i);
4151 string buildTimeMacOSSDKFolder = MACOS_SDK_ROOT;
4154 extraArgs.push_back(
"-isysroot");
4155 extraArgs.push_back(buildTimeMacOSSDKFolder);
4159 __block vector<string> headerSearchPaths;
4160 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
4161 vector<string> result = env->getHeaderSearchPaths();
4162 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
4164 applyToInstalledEnvironments(envGetHeaderSearchPaths);
4167 __block Module *module;
4169 module = readModuleFromC(preprocessedInputPath, headerSearchPaths, extraArgs, issues);
4172 if (! tmpPreprocessedInputDir.empty())
4174 remove(tmpPreprocessedInputDir.c_str());
4183 if (! compilerModule)
4185 VUserLog(
"Error: Didn't recognize '%s' as a node class, type, or library.", inputPath.c_str());
4189 setTargetForModule(module, target);
4190 writeModuleToBitcode(module, outputPath);
4199Module * VuoCompiler::compileCompositionToModule(
VuoCompilerComposition *composition,
const string &moduleKey,
bool isTopLevelComposition,
4202 composition->
check(issues);
4204 reifyGenericPortTypes(composition);
4207 isTopLevelComposition,
4210 __block Module *module =
nullptr;
4215 setTargetForModule(module, target);
4245 Module *module = compileCompositionToModule(composition, moduleKey, isTopLevelComposition, issues);
4250 writeModuleToBitcode(module, outputPath);
4269 VUserLog(
"Compiling '%s' (%s)…", inputPath.c_str(), target.c_str());
4279 "",
"The composition file couldn't be read or was empty.");
4318 delete baseComposition;
4338 vector<string> rPaths = ! rPath.empty() ? vector<string>(1, rPath) : getRunPathSearchPaths(environments.back().front());
4339 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
false, rPaths, shouldAdHocCodeSign);
4361 vector<string> rPaths = getRunPathSearchPaths(environments.back().front());
4362 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
true, rPaths, shouldAdHocCodeSign);
4379void VuoCompiler::linkCompositionToCreateExecutableOrDynamicLibrary(
string compiledCompositionPath,
string linkedCompositionPath,
4380 Optimization optimization,
bool isDylib,
const vector<string> &rPaths,
4381 bool shouldAdHocCodeSign)
4387 shouldLoadAllModules =
false;
4389 set<string> dependencies = getDependenciesForComposition(compiledCompositionPath);
4390 dependencies.insert(getRuntimeDependency());
4392 dependencies.insert(getRuntimeMainDependency());
4394 set<Module *> modules;
4395 set<string> libraries;
4396 set<string> frameworks;
4397 getLinkerInputs(dependencies, optimization, modules, libraries, frameworks);
4399 libraries.insert(compiledCompositionPath);
4401 link(linkedCompositionPath, modules, libraries, frameworks, isDylib, rPaths, shouldAdHocCodeSign);
4424 bool shouldAdHocCodeSign =
false;
4426 shouldAdHocCodeSign =
true;
4432 set<string> allDependencies = getDependenciesForComposition(compiledCompositionPath);
4433 set<string> addedDependencies;
4434 std::set_difference(allDependencies.begin(), allDependencies.end(),
4435 carriedOverDependencies.begin(), carriedOverDependencies.end(),
4436 std::inserter(addedDependencies, addedDependencies.end()));
4442 set<string> carriedOverExternalLibraries = runningCompositionLibraries->
getExternalLibraries();
4447 string nonUnloadableResourcePath;
4448 string unloadableResourcePath;
4449 set<string> nonUnloadableDependencies;
4450 set<string> unloadableDependencies;
4451 map<string, set<string> > builtInCacheDependencies;
4452 map<string, set<string> > userCacheDependencies;
4453 set<string> builtInLibraries;
4454 set<string> userLibraries;
4455 set<string> addedExternalLibraries;
4456 set<string> addedFrameworks;
4457 set<string> allFrameworks;
4458 if (! addedDependencies.empty())
4462 set<string> builtInModuleAndLibraryDependencies;
4463 set<string> userModuleAndLibraryDependencies;
4464 set<Module *> builtInModules;
4465 set<Module *> userModules;
4468 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4469 builtInModules, userModules, builtInLibraries, userLibraries, addedExternalLibraries, addedFrameworks);
4471 allFrameworks.insert(carriedOverFrameworks.begin(), carriedOverFrameworks.end());
4472 allFrameworks.insert(addedFrameworks.begin(), addedFrameworks.end());
4474 string dir, linkedCompositionFile, ext;
4481 __block vector<string> currentCacheLibraries;
4482 applyToAllEnvironments(^
void (Environment *env) {
4483 currentCacheLibraries.push_back( env->getCurrentModuleCacheDylib() );
4486 for (
string cachePath : carriedOverUserCacheLibraries)
4488 for (
string currentCachePath : currentCacheLibraries)
4494 userCacheDependencies[currentCachePath].insert(dependenciesInCache.begin(), dependenciesInCache.end());
4496 auto cacheDependenciesIter = userCacheDependencies.find(cachePath);
4497 if (cacheDependenciesIter != userCacheDependencies.end())
4499 userCacheDependencies[currentCachePath].insert(cacheDependenciesIter->second.begin(), cacheDependenciesIter->second.end());
4500 userCacheDependencies.erase(cacheDependenciesIter);
4503 auto carriedOverIter = find(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(), cachePath);
4504 if (carriedOverIter != carriedOverUnloadableLibraries.end())
4505 *carriedOverIter = currentCachePath;
4513 if (wasModuleCacheRebuilt)
4517 vector<string> carriedOverUnloadableMinusResourceLibraries;
4518 std::set_difference(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(),
4519 carriedOverResourceLibraries.begin(), carriedOverResourceLibraries.end(),
4520 std::back_inserter(carriedOverUnloadableMinusResourceLibraries));
4522 carriedOverUnloadableLibraries = carriedOverUnloadableMinusResourceLibraries;
4525 userModuleAndLibraryDependencies.insert(dependenciesInResourceLibraries.begin(), dependenciesInResourceLibraries.end());
4527 set<string> builtInModuleAndLibraryDependencies_tmp;
4528 set<string> userModuleAndLibraryDependencies_tmp;
4529 map<string, set<string> > builtInCacheDependencies_tmp;
4530 set<Module *> builtInModules_tmp;
4531 set<string> builtInLibraries_tmp;
4532 set<string> externalLibraries_tmp;
4533 set<string> externalFrameworks_tmp;
4536 builtInModuleAndLibraryDependencies_tmp, userModuleAndLibraryDependencies_tmp, builtInCacheDependencies_tmp, userCacheDependencies,
4537 builtInModules_tmp, userModules, builtInLibraries_tmp, userLibraries, externalLibraries_tmp, externalFrameworks_tmp);
4542 if (! builtInModules.empty() || builtInLibraries.size() > builtInCacheDependencies.size())
4545 nonUnloadableDependencies = builtInModuleAndLibraryDependencies;
4547 set<string> librariesForNonUnloadableResource = builtInLibraries;
4548 librariesForNonUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4549 librariesForNonUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4550 librariesForNonUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4552 vector<string> rPaths = getRunPathSearchPaths(environments.front().front());
4554 link(nonUnloadableResourcePath, builtInModules, librariesForNonUnloadableResource, allFrameworks,
true, rPaths, shouldAdHocCodeSign);
4556 for (set<string>::iterator i = builtInLibraries.begin(); i != builtInLibraries.end(); )
4559 builtInLibraries.erase(i++);
4564 for (set<string>::iterator i = addedExternalLibraries.begin(); i != addedExternalLibraries.end(); )
4567 addedExternalLibraries.erase(i++);
4575 if (! userModules.empty() || userLibraries.size() > userCacheDependencies.size() || wasModuleCacheRebuilt)
4578 unloadableDependencies = userModuleAndLibraryDependencies;
4580 set<string> librariesForUnloadableResource = userLibraries;
4581 librariesForUnloadableResource.insert(builtInLibraries.begin(), builtInLibraries.end());
4582 librariesForUnloadableResource.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4583 librariesForUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4584 librariesForUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4585 librariesForUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4586 if (! nonUnloadableResourcePath.empty())
4587 librariesForUnloadableResource.insert(nonUnloadableResourcePath);
4592 vector<string> rPaths = getRunPathSearchPaths(environments.back().front());
4594 link(unloadableResourcePath, userModules, librariesForUnloadableResource, allFrameworks,
true, rPaths, shouldAdHocCodeSign);
4596 for (set<string>::iterator i = userLibraries.begin(); i != userLibraries.end(); )
4599 userLibraries.erase(i++);
4608 set<string> vuoRuntimePaths;
4610 set<Module *> modules;
4611 set<string> libraries;
4612 set<string> frameworks;
4614 set<string> dependencies;
4615 dependencies.insert(getRuntimeDependency());
4617 vuoRuntimePaths = libraries;
4623 set<Module *> modules;
4624 set<string> libraries;
4626 libraries.insert(compiledCompositionPath);
4627 libraries.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4628 libraries.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4629 libraries.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4630 libraries.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4631 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4632 libraries.insert(userLibraries.begin(), userLibraries.end());
4633 if (! nonUnloadableResourcePath.empty())
4634 libraries.insert(nonUnloadableResourcePath);
4635 if (! unloadableResourcePath.empty())
4636 libraries.insert(unloadableResourcePath);
4637 libraries.insert(vuoRuntimePaths.begin(), vuoRuntimePaths.end());
4638 vector<string> rPaths = getRunPathSearchPaths(environments.front().front());
4639 link(linkedCompositionPath, modules, libraries, allFrameworks,
true, rPaths, shouldAdHocCodeSign);
4644 if (! nonUnloadableResourcePath.empty())
4647 if (! unloadableResourcePath.empty())
4650 for (map<
string, set<string> >::iterator i = builtInCacheDependencies.begin(); i != builtInCacheDependencies.end(); ++i)
4653 for (map<
string, set<string> >::iterator i = userCacheDependencies.begin(); i != userCacheDependencies.end(); ++i)
4666set<string> VuoCompiler::getDependenciesForComposition(
const string &compiledCompositionPath)
4671 __block set<string> directDependencies;
4673 Module *module = readModuleFromBitcode(compiledCompositionPath, getTargetArch(target));
4677 delete compilerModule;
4683 auto deps = getDependenciesForComposition(directDependencies,
true);
4684 VUserLog(
"Gathering dependencies for '%s' took %5.2fs", compiledCompositionPath.c_str(),
VuoLogGetTime() - t0);
4702 set<string> directDependencies;
4711 vector<VuoPublishedPort *> publishedPorts;
4712 publishedPorts.insert(publishedPorts.end(), publishedInputPorts.begin(), publishedInputPorts.end());
4713 publishedPorts.insert(publishedPorts.end(), publishedOutputPorts.begin(), publishedOutputPorts.end());
4716 if (publishedPort->getClass()->hasCompiler())
4732 directDependencies.insert(dependency);
4737 return directDependencies;
4749 return getDependenciesForComposition(directDependencies,
false);
4759 __block vector<string> librarySearchPaths;
4760 applyToInstalledEnvironments(^
void (Environment *env) {
4761 vector<string> result = env->getLibrarySearchPaths();
4762 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
4765 set<string> dylibDeps;
4766 for (
string dep : getDependenciesForComposition(composition))
4768 string path = getLibraryPath(dep, librarySearchPaths);
4770 dylibDeps.insert(path);
4789set<string> VuoCompiler::getDependenciesForComposition(
const set<string> &directDependencies,
bool checkCompatibility)
4792 for (set<string>::const_iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4795 set<string> dependencies;
4796 for (set<string>::iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4798 string moduleKey = *i;
4800 dependencies.insert(moduleKey);
4803 vector<VuoDirectedAcyclicGraph::Vertex *> firstPassVertices = dependencyGraph->
findVertex(moduleKey);
4804 set<VuoDirectedAcyclicGraph::Vertex *> firstPassDependencies(firstPassVertices.begin(), firstPassVertices.end());
4805 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassVertices.begin(); j != firstPassVertices.end(); ++j)
4808 firstPassDependencies.insert(downstream.begin(), downstream.end());
4812 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassDependencies.begin(); j != firstPassDependencies.end(); ++j)
4814 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(*j);
4819 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
4820 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = moduleVertices.begin(); j != moduleVertices.end(); ++j)
4824 dependencies.insert(
static_cast<DependencyGraphVertex *
>(v)->getDependency() );
4829 if (checkCompatibility)
4837 set<VuoCompilerNodeClass *> nodeClassesReported;
4839 for (
string moduleKey : dependencies)
4844 vector<VuoCompilerNodeClass *> incompatibleNodeClasses;
4847 if (moduleAsNodeClass)
4848 incompatibleNodeClasses.push_back(moduleAsNodeClass);
4851 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
4854 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = dependencyGraph->
getUpstreamVertices(v);
4856 vector<string> upstreamModuleKeys;
4857 std::transform(upstream.begin(), upstream.end(),
4858 std::back_inserter(upstreamModuleKeys),
4861 vector<string> potentialNodeClassNames;
4862 std::set_intersection(directDependencies.begin(), directDependencies.end(),
4863 upstreamModuleKeys.begin(), upstreamModuleKeys.end(),
4864 std::back_inserter(potentialNodeClassNames));
4866 for (
string nodeClassName : potentialNodeClassNames)
4869 if (upstreamNodeClass)
4870 incompatibleNodeClasses.push_back(upstreamNodeClass);
4875 if (incompatibleNodeClasses.empty())
4878 "Dependencies incompatible with system",
4880 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4888 if (nodeClassesReported.find(nodeClass) != nodeClassesReported.end())
4891 nodeClassesReported.insert(nodeClass);
4894 "Nodes incompatible with system",
4896 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4907 "Dependencies incompatible with system",
4908 "Some dependencies of this composition are only compatible with " + actualCompatibility.
toString() +
4909 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4918 vector<string> coreDependencies = getCoreVuoDependencies();
4919 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
4921 return dependencies;
4931 for (
string dependency : dependencies)
4938 return compatibility;
4945void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4946 set<Module *> &modules, set<string> &libraries, set<string> &frameworks)
4948 set<string> builtInModuleAndLibraryDependencies;
4949 set<string> userModuleAndLibraryDependencies;
4950 map<string, set<string> > builtInCacheDependencies;
4951 map<string, set<string> > userCacheDependencies;
4952 set<Module *> builtInModules;
4953 set<Module *> userModules;
4954 set<string> builtInLibraries;
4955 set<string> userLibraries;
4956 set<string> externalLibraries;
4958 getLinkerInputs(dependencies, optimization,
4959 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4960 builtInModules, userModules, builtInLibraries, userLibraries, externalLibraries, frameworks);
4962 modules.insert(builtInModules.begin(), builtInModules.end());
4963 modules.insert(userModules.begin(), userModules.end());
4964 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4965 libraries.insert(userLibraries.begin(), userLibraries.end());
4966 libraries.insert(externalLibraries.begin(), externalLibraries.end());
4982void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4983 set<string> &builtInModuleAndLibraryDependencies, set<string> &userModuleAndLibraryDependencies,
4984 map<
string, set<string> > &builtInCacheDependencies, map<
string, set<string> > &userCacheDependencies,
4985 set<Module *> &builtInModules, set<Module *> &userModules,
4986 set<string> &builtInLibraries, set<string> &userLibraries,
4987 set<string> &externalLibraries, set<string> &externalFrameworks)
4990 if (shouldUseModuleCache)
4993 __block vector<string> librarySearchPaths;
4994 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
4995 vector<string> result = env->getLibrarySearchPaths();
4996 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
4998 applyToInstalledEnvironments(envGetLibrarySearchPaths);
5000 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
5002 string dependency = *i;
5004 bool foundInCache =
false;
5005 string moduleCachePath;
5006 bool isInBuiltInModuleCache =
false;
5007 if (shouldUseModuleCache)
5008 foundInCache = findInModuleCache(dependency, moduleCachePath, isInBuiltInModuleCache);
5012 if (isInBuiltInModuleCache)
5014 builtInLibraries.insert(moduleCachePath);
5015 builtInCacheDependencies[moduleCachePath].insert(dependency);
5019 userLibraries.insert(moduleCachePath);
5020 userCacheDependencies[moduleCachePath].insert(dependency);
5026 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
5031 applyToAllEnvironments(envFindModule);
5041 if (module->isBuiltIn())
5042 builtInLibraries.insert(modulePath);
5044 userLibraries.insert(modulePath);
5048 if (module->isBuiltIn())
5049 builtInModules.insert(module->getModule());
5051 userModules.insert(module->getModule());
5054 if (module->isBuiltIn())
5055 builtInModuleAndLibraryDependencies.insert(dependency);
5057 userModuleAndLibraryDependencies.insert(dependency);
5063 externalFrameworks.insert(dependency);
5066 string dependencyPath = getLibraryPath(dependency, librarySearchPaths);
5067 if (! dependencyPath.empty())
5068 externalLibraries.insert(dependencyPath);
5072 else if (dependency !=
"c"
5073 && dependency !=
"objc")
5074 VUserLog(
"Warning: Could not locate dependency '%s'.", dependency.c_str());
5086string VuoCompiler::getLibraryPath(
const string &dependency, vector<string> librarySearchPaths)
5093 if (dependency !=
"crypto"
5094 && dependency !=
"ssl")
5095 librarySearchPaths.push_back(
"/usr/lib");
5097 for (
auto &path : librarySearchPaths)
5099 vector<string> variations;
5100 variations.push_back(path +
"/" + dependency);
5101 variations.push_back(path +
"/lib" + dependency);
5102 variations.push_back(path +
"/lib" + dependency +
".dylib");
5103 variations.push_back(path +
"/lib" + dependency +
".a");
5104 for (
auto &variation : variations)
5119void VuoCompiler::useModuleCache(
bool shouldUseExistingBuiltInCaches,
bool shouldUseExistingOtherCaches)
5121 loadModulesIfNeeded();
5122 dispatch_group_wait(moduleSourceCompilersExist, DISPATCH_TIME_FOREVER);
5126 dispatch_sync(environmentQueue, ^{
5127 set<string> dylibsForCachesOfInstalledModules;
5128 set<string> frameworksForCachesOfInstalledModules;
5129 unsigned long lastPrerequisiteModuleCacheRebuild = 0;
5130 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
5132 set<string> dylibsForCacheOfGeneratedModules;
5133 set<string> frameworksForCacheOfGeneratedModules;
5135 for (int j = i->size() - 1; j >= 0; --j)
5137 Environment *env = i->at(j);
5138 bool installed = (j == 0);
5140 set<string> cacheableModulesAndDependencies;
5141 set<string> dylibsNeededToLinkToThisCache;
5142 set<string> frameworksNeededToLinkToThisCache;
5143 env->getCacheableModulesAndDependencies(cacheableModulesAndDependencies,
5144 dylibsNeededToLinkToThisCache, frameworksNeededToLinkToThisCache);
5146 set<string> accumulatedDylibs;
5147 accumulatedDylibs.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5148 accumulatedDylibs.insert(dylibsForCachesOfInstalledModules.begin(), dylibsForCachesOfInstalledModules.end());
5149 accumulatedDylibs.insert(dylibsForCacheOfGeneratedModules.begin(), dylibsForCacheOfGeneratedModules.end());
5151 set<string> accumulatedFrameworks;
5152 accumulatedFrameworks.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5153 accumulatedFrameworks.insert(frameworksForCachesOfInstalledModules.begin(), frameworksForCachesOfInstalledModules.end());
5154 accumulatedFrameworks.insert(frameworksForCacheOfGeneratedModules.begin(), frameworksForCacheOfGeneratedModules.end());
5156 bool shouldUseExistingCache = (env->isBuiltIn() ? shouldUseExistingBuiltInCaches : shouldUseExistingOtherCaches);
5157 env->useModuleCache(shouldUseExistingCache, this, cacheableModulesAndDependencies,
5158 accumulatedDylibs, accumulatedFrameworks, lastPrerequisiteModuleCacheRebuild);
5160 string cacheDylib = env->getCurrentModuleCacheDylib();
5161 accumulatedDylibs.insert(cacheDylib);
5162 dylibsForCachesOfInstalledModules.insert(cacheDylib);
5164 lastPrerequisiteModuleCacheRebuild = max(lastPrerequisiteModuleCacheRebuild, env->getLastModuleCacheRebuild());
5168 dylibsForCachesOfInstalledModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5169 frameworksForCachesOfInstalledModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5173 dylibsForCacheOfGeneratedModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5174 frameworksForCacheOfGeneratedModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5180 Environment::waitForModuleCachesToBuild();
5191bool VuoCompiler::findInModuleCache(
const string &moduleOrDependency,
string &cachePath,
bool &isBuiltinCache)
5193 __block
bool found =
false;
5194 __block
string outPath;
5195 __block
bool outBuiltin;
5196 dispatch_sync(environmentQueue, ^{
5197 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
5199 bool builtin = (i == environments.begin());
5201 for (int j = i->size() - 1; j >= 0; --j)
5203 Environment *env = i->at(j);
5206 bool resultFound = env->findInModuleCache(moduleOrDependency, resultPath);
5210 outPath = resultPath;
5211 outBuiltin = builtin;
5217 cachePath = outPath;
5218 isBuiltinCache = outBuiltin;
5231 dispatch_group_async(moduleCacheBuilding, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
5232 useModuleCache(
true,
false);
5251 return getTargetArch(target);
5269 vuoFrameworkInProgressPath = vuoFrameworkPath;
5272 compiler.useModuleCache(
false,
true);
5284 unsigned long maxSeconds = 30 * 24 * 60 * 60;
5287 for (set<VuoFileUtilities::File *>::iterator i = cacheDirs.begin(); i != cacheDirs.end(); ++i)
5289 string path = (*i)->path();
5291 string file = (*i)->basename();
5292 if (file !=
"Builtin" && file !=
"System" && file !=
"User")
5295 if (fileSeconds > maxSeconds)
5301 string pidAsString = file.substr(Environment::pidCacheDirPrefix.length());
5302 int pid = atoi(pidAsString.c_str());
5303 if (kill(pid, 0) != 0)
5317 dispatch_sync(modulesToLoadQueue, ^{
5318 this->shouldLoadAllModules = shouldLoadAllModules;
5334void VuoCompiler::link(
string outputPath,
const set<Module *> &modules,
const set<string> &libraries,
const set<string> &frameworks,
bool isDylib,
const vector<string> &rPaths,
bool shouldAdHocCodeSign,
VuoCompilerIssues *issues)
5336 VUserLog(
"Linking '%s' (%s)…", outputPath.c_str(), getTargetArch(target).c_str());
5339 bool ownsIssues =
false;
5351 unique_ptr<Module> compositeModule(
new Module(
"composite", *
globalLLVMContext));
5352 Linker linker(*compositeModule);
5353 setTargetForModule(compositeModule.get(), target);
5355 for (
auto i : modules)
5357 unique_ptr<Module> upi = llvm::CloneModule(i);
5358 if (linker.linkInModule(std::move(upi)))
5360 VuoCompilerIssue issue(VuoCompilerIssue::IssueType::Error,
"linking composite module",
"",
5361 "",
"Failed to link in the module with ID '" + i->getModuleIdentifier() +
"'");
5366 writeModuleToBitcode(compositeModule.get(), compositeModulePath);
5375 string clangPath(getClangPath() +
"++");
5377 vector<const char *> args;
5378 vector<char *> argsToFree;
5379 args.push_back(clangPath.c_str());
5382 char *outputPathZ = strdup((
"-o" + outputPath).c_str());
5383 args.push_back(outputPathZ);
5384 argsToFree.push_back(outputPathZ);
5387 args.push_back(compositeModulePath.c_str());
5389 vector<string> coreDependencies = getCoreVuoDependencies();
5390 for (set<string>::const_iterator i = libraries.begin(); i != libraries.end(); ++i)
5392 string library = *i;
5394 for (vector<string>::iterator j = coreDependencies.begin(); j != coreDependencies.end(); ++j)
5396 string coreDependency = *j;
5398 args.push_back(
"-force_load");
5406 library = libraryObject;
5409 char *libraryZ = strdup(library.c_str());
5410 args.push_back(libraryZ);
5411 argsToFree.push_back(libraryZ);
5415 vector<string> frameworkArguments;
5417 __block vector<string> frameworkSearchPaths;
5418 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
5419 vector<string> result = env->getFrameworkSearchPaths();
5420 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
5422 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
5424 for (vector<string>::const_iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
5428 frameworkArguments.push_back(a);
5429 char *frameworkArgument = strdup(a.c_str());
5430 args.push_back(frameworkArgument);
5431 argsToFree.push_back(frameworkArgument);
5434 for (set<string>::const_iterator i = frameworks.begin(); i != frameworks.end(); ++i)
5436 args.push_back(
"-framework");
5438 string frameworkName = *i;
5439 frameworkName = frameworkName.substr(0, frameworkName.length() -
string(
".framework").length());
5440 char *frameworkNameZ = strdup(frameworkName.c_str());
5441 args.push_back(frameworkNameZ);
5442 argsToFree.push_back(frameworkNameZ);
5448 string frameworkMacOSSDKFolder = vuoFrameworkPath +
"/SDKs/MacOSX.sdk";
5452 args.push_back(
"-Xlinker");
5453 args.push_back(
"-syslibroot");
5454 args.push_back(
"-Xlinker");
5455 char *frameworkMacOSSDKFolderZ = strdup(frameworkMacOSSDKFolder.c_str());
5456 args.push_back(frameworkMacOSSDKFolderZ);
5457 argsToFree.push_back(frameworkMacOSSDKFolderZ);
5459 args.push_back(
"-Xlinker");
5460 args.push_back(
"-platform_version");
5461 args.push_back(
"-Xlinker");
5462 args.push_back(
"macos");
5463 args.push_back(
"-Xlinker");
5464 char *deploymentTargetZ = strdup(MACOS_DEPLOYMENT_TARGET);
5465 args.push_back(deploymentTargetZ);
5466 argsToFree.push_back(deploymentTargetZ);
5467 args.push_back(
"-Xlinker");
5468 char *sdkVersionZ = strdup(MACOS_SDK_VERSION);
5469 args.push_back(sdkVersionZ);
5470 argsToFree.push_back(sdkVersionZ);
5473 args.push_back(
"-Xlinker");
5474 args.push_back(
"--no-demangle");
5477 args.push_back(
"-v");
5480 args.push_back(
"-dynamiclib");
5482 args.push_back(
"-Xlinker");
5483 args.push_back(
"-headerpad_max_install_names");
5486 for (
const string &rPath : rPaths)
5488 args.push_back(
"-rpath");
5489 args.push_back(rPath.c_str());
5493 args.push_back(
"-rpath");
5494 args.push_back(LLVM_ROOT
"/lib");
5497 args.push_back(
"-target");
5498 args.push_back(target.c_str());
5500 args.push_back(
"-std=c++14");
5501 args.push_back(
"-stdlib=libc++");
5502 args.push_back(
"-mmacosx-version-min=10.10");
5506 clang::DiagnosticOptions *diagOptions =
new clang::DiagnosticOptions();
5507 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5508 clang::DiagnosticsEngine Diags(DiagID, diagOptions, diagnosticConsumer);
5513 for (vector<const char *>::iterator i = args.begin(); i != args.end(); ++i)
5520 const StringRef stdoutPath(stdoutFile);
5521 const StringRef *redirects[] = {
5528 const char **argsz = (
const char **)malloc(
sizeof(
char *) * args.size() + 1);
5529 for (
int i = 0; i < args.size(); ++i)
5531 argsz[args.size()] =
nullptr;
5534 bool executionFailed;
5536 int ret = llvm::sys::ExecuteAndWait(args[0], argsz,
nullptr, redirects, 0, 0, &errMsg, &executionFailed);
5538 for (
auto i : argsToFree)
5542 remove(compositeModulePath.c_str());
5548 chmod(outputPath.c_str(), 0755);
5553 if (!errMsg.empty())
5556 details +=
"\n" + errMsg +
"\n";
5559 if (!stdoutFileContents.empty())
5561 VUserLog(
"%s", stdoutFileContents.c_str());
5562 details +=
"\n" + stdoutFileContents +
"\n";
5574 if (shouldAdHocCodeSign)
5575 adHocCodeSign(outputPath);
5581void VuoCompiler::adHocCodeSign(
string path)
5585 "CODESIGN_ALLOCATE=" + getCodesignAllocatePath(),
5595Module *VuoCompiler::readModuleFromC(
string inputPath,
const vector<string> &headerSearchPaths,
const vector<string> &extraArgs,
VuoCompilerIssues *issues)
5599 vector<const char *> args;
5600 vector<char *> argsToFree;
5602 args.push_back(inputPath.c_str());
5603 args.push_back(
"-DVUO_COMPILER");
5604 args.push_back(
"-fblocks");
5610 args.push_back(
"-mdisable-fp-elim");
5613 args.push_back(
"-Wall");
5614 args.push_back(
"-Wextra");
5615 args.push_back(
"-Wimplicit-fallthrough");
5616 args.push_back(
"-Wno-unused-parameter");
5617 args.push_back(
"-Wno-sign-compare");
5618 args.push_back(
"-Werror=implicit");
5622 args.push_back(
"-std=c++14");
5623 args.push_back(
"-stdlib=libc++");
5624 args.push_back(
"-fexceptions");
5625 args.push_back(
"-fcxx-exceptions");
5628 for (vector<string>::const_iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
5630 args.push_back(
"-I");
5631 args.push_back(i->c_str());
5635 string dependencyOutputPath = _dependencyOutput();
5636 if (!dependencyOutputPath.empty())
5638 char *outputObjectPath = strdup(dependencyOutputPath.substr(0, dependencyOutputPath.length() - 2).c_str());
5639 argsToFree.push_back(outputObjectPath);
5643 args.push_back(
"-MT");
5644 args.push_back(outputObjectPath);
5645 args.push_back(
"-dependency-file");
5646 args.push_back(dependencyOutputPath.c_str());
5651 args.push_back(
"-v");
5653 for (vector<string>::const_iterator i = extraArgs.begin(); i != extraArgs.end(); ++i)
5654 args.push_back(i->c_str());
5657 clang::DiagnosticOptions * diagOptions =
new clang::DiagnosticOptions();
5658 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5659 clang::DiagnosticsEngine *diags =
new clang::DiagnosticsEngine(DiagID, diagOptions, diagnosticConsumer);
5662 shared_ptr<clang::CompilerInvocation> compilerInvocation(
new clang::CompilerInvocation);
5663 clang::CompilerInvocation::CreateFromArgs(*compilerInvocation, &args[0], &args[0] + args.size(), *diags);
5664 compilerInvocation->TargetOpts->Triple = target;
5666 clang::CompilerInstance Clang;
5667 Clang.setInvocation(compilerInvocation);
5669 Clang.setDiagnostics(diags);
5670 if (!Clang.hasDiagnostics())
5674 string builtinHeaderSearchPath;
5676 if (vuoFrameworkPath.empty())
5678 builtinHeaderSearchPath = getClangPath();
5683 builtinHeaderSearchPath +=
"lib/clang/" CLANG_VERSION_STRING;
5686 builtinHeaderSearchPath = vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/lib/clang/" CLANG_VERSION_STRING;
5687 Clang.getHeaderSearchOpts().ResourceDir = builtinHeaderSearchPath;
5690 clang::CodeGenAction *Act =
new clang::EmitLLVMOnlyAction();
5691 if (!Clang.ExecuteAction(*Act))
5694 for (
auto i : argsToFree)
5697 unique_ptr<Module> module = Act->takeModule();
5699 VUserLog(
"Error compiling %s: module is null.", inputPath.c_str());
5700 return module.release();
5708Module *VuoCompiler::readModuleFromBitcode(
string inputPath,
string arch)
5710 string dir, file, ext;
5713 return readModuleFromBitcode(&inputFile, arch);
5725 size_t inputDataBytes;
5729 set<string> availableArchs;
5731 Module *module = readModuleFromBitcodeData(inputData, inputDataBytes, arch, availableArchs, error);
5734 VUserLog(
"Error: Couldn't parse module '%s' (%s): %s.", inputFile->
getRelativePath().c_str(), arch.c_str(), error.c_str());
5746Module *VuoCompiler::readModuleFromBitcodeData(
char *inputData,
size_t inputDataBytes,
string arch,
5747 set<string> &availableArchs,
string &error)
5749 if (inputDataBytes <
sizeof(
unsigned int))
5752 __block Module *module =
nullptr;
5754 StringRef inputDataAsStringRef(inputData, inputDataBytes);
5755 auto mb = MemoryBuffer::getMemBuffer(inputDataAsStringRef,
"",
false);
5758 error =
"Couldn't create MemoryBuffer";
5762 MemoryBufferRef bitcodeBuffer;
5764 unsigned int fileID = *(
unsigned int *)inputData;
5765 if (fileID == 0x0b17c0de)
5767 bitcodeBuffer = mb.get()->getMemBufferRef();
5769 else if (fileID == 0xdec04342)
5772 bitcodeBuffer = mb.get()->getMemBufferRef();
5773 moduleArch =
"x86_64";
5774 availableArchs.insert(moduleArch);
5777 else if (fileID == 0xbebafeca)
5781 error =
"It's a Mach-O universal binary, but this compiler instance's LLVM target isn't set";
5787 auto binary = llvm::object::MachOUniversalBinary::create(mb.get()->getMemBufferRef());
5790 error =
"Couldn't read Mach-O universal binary:";
5791 handleAllErrors(binary.takeError(), [&error](
const ErrorInfoBase &ei) {
5792 error +=
" " + ei.message();
5797 for (
auto &o : binary.get()->objects())
5799 if (o.getArchFlagName() == arch)
5800 bitcodeBuffer = MemoryBufferRef(mb.get()->getMemBufferRef().getBuffer().slice(o.getOffset(), o.getOffset() + o.getSize()),
"");
5802 availableArchs.insert(o.getArchFlagName());
5805 if (!bitcodeBuffer.getBufferSize())
5807 error =
"The Mach-O universal binary doesn't have an \"" + arch +
"\" slice";
5815 error =
"Couldn't parse bitcode file:";
5816 handleAllErrors(wrappedModule.takeError(), [&error](
const ErrorInfoBase &ei) {
5817 error +=
" " + ei.message();
5822 module = wrappedModule.get().release();
5824 if (moduleArch.empty())
5825 moduleArch = getTargetArch(module->getTargetTriple());
5827 if (availableArchs.empty())
5828 availableArchs.insert(moduleArch);
5830 if (moduleArch != arch)
5832 error =
"The module's CPU architecture \"" + moduleArch +
"\" doesn't match the compiler's CPU architecture \"" + arch +
"\"";
5848bool VuoCompiler::writeModuleToBitcode(Module *module,
string outputPath)
5851 raw_string_ostream verifyOut(str);
5852 if (llvm::verifyModule(*module, &verifyOut))
5854 VUserLog(
"Error: Module verification failed:\n%s", verifyOut.str().c_str());
5859 if (module->getTargetTriple().empty())
5860 setTargetForModule(module, getProcessTarget());
5862 std::error_code err;
5863 raw_fd_ostream out(outputPath.c_str(), err, sys::fs::F_None);
5866 VUserLog(
"Error: Couldn't open file '%s' for writing: %s", outputPath.c_str(), err.message().c_str());
5869 llvm::WriteBitcodeToFile(module, out);
5880void VuoCompiler::setTargetForModule(Module *module,
string targetTriple)
5883 llvm::Triple triple(targetTriple);
5884 if (triple.isMacOSX())
5885 triple.setOSName(
"macosx10.10.0");
5887 module->setTargetTriple(triple.str());
5890 auto target = TargetRegistry::lookupTarget(module->getTargetTriple(), error);
5893 VUserLog(
"Error: Couldn't look up target: %s", error.c_str());
5897 auto targetMachine = target->createTargetMachine(module->getTargetTriple(),
"",
"", TargetOptions(), Optional<Reloc::Model>());
5900 VUserLog(
"Error: Couldn't create targetMachine.");
5904 module->setDataLayout(targetMachine->createDataLayout());
5906 delete targetMachine;
5913string VuoCompiler::getTargetArch(
string target)
5915 auto hyphen = target.find(
'-');
5916 if (hyphen == string::npos)
5919 return target.substr(0, hyphen);
5925string VuoCompiler::getProcessTarget(
void)
5931 llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
5934 if (triple.isMacOSX())
5936 unsigned int major, minor, micro;
5937 if (triple.getMacOSXVersion(major, minor, micro))
5939 ostringstream osVersion;
5940 osVersion <<
"macosx" << major <<
"." << minor <<
"." << micro;
5941 triple.setOSName(osVersion.str());
5945 return triple.str();
5956 Module *llvmModule = module->
getModule();
5985 delete baseNodeClass;
6018 if (nodeClassForNode)
6019 return nodeClassForNode->
newNode(title, x, y);
6033 if (nodeClassForNode)
6034 return nodeClassForNode->
newNode(nodeToCopyMetadataFrom);
6045 return createPublishedNode(nodeClassName, publishedInputPorts);
6054 return createPublishedNode(nodeClassName, publishedOutputPorts);
6060VuoNode * VuoCompiler::createPublishedNode(
const string &nodeClassName,
const vector<VuoPublishedPort *> &publishedPorts)
6068 for (
size_t i = 0; i < publishedPorts.size(); ++i)
6070 VuoType *publishedPortType =
static_cast<VuoCompilerPort *
>(publishedPorts[i]->getCompiler())->getDataVuoType();
6074 set<VuoPort *> nodePorts;
6078 nodePorts.insert(inputPort);
6081 nodePorts.insert(outputPort);
6086 nodePorts.insert(inputPort);
6089 for (
VuoPort *port : nodePorts)
6096 reifyGenericPortTypes(node);
6107 dispatch_sync(environmentQueue, ^{
6108 if (environments.size() >= 5)
6109 environments.at(3).at(0)->addExpatriateSourceFile(sourcePath);
6119 dispatch_sync(environmentQueue, ^{
6120 if (environments.size() >= 5)
6122 environments.at(3).at(0)->removeExpatriateSourceFile(sourcePath);
6124 set<string> sourcesRemoved;
6125 sourcesRemoved.insert(getModuleKeyForPath(sourcePath));
6126 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), set<string>(), sourcesRemoved,
6127 false, false, environments.at(3).at(0), nullptr, nullptr,
"");
6150 string sourcePathCopy = sourcePath;
6151 string sourceCodeCopy = sourceCode;
6153 dispatch_async(environmentQueue, ^{
6155 ModuleInfo *sourceInfo = NULL;
6157 for (
const vector<Environment *> &envs : environments)
6159 for (Environment *env : envs)
6161 ModuleInfo *potentialSourceInfo = env->listSourceFile(nodeClassName);
6164 sourceInfo = potentialSourceInfo;
6173 bool shouldRecompileSourcesIfUnchanged;
6174 if (! sourceCodeCopy.empty())
6176 sourceInfo->setSourceCode(sourceCodeCopy);
6177 sourceInfo->setSourceCodeOverridden(
true);
6179 shouldRecompileSourcesIfUnchanged =
false;
6183 sourceInfo->revertSourceCode();
6184 sourceInfo->setSourceCodeOverridden(
false);
6186 shouldRecompileSourcesIfUnchanged =
true;
6188 sourceInfo->setAttempted(
false);
6189 sourceInfo->setLastModifiedToNow();
6191 set<string> sourcesModified;
6192 sourcesModified.insert(nodeClassName);
6194 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), sourcesModified, set<string>(),
6195 false, shouldRecompileSourcesIfUnchanged,
nullptr,
nullptr,
nullptr,
"");
6234 set<string> nodeClassNameSet;
6235 nodeClassNameSet.insert(nodeClassName);
6236 loadModulesIfNeeded(nodeClassNameSet);
6241 void (^envGetNodeClass)(Environment *) = ^
void (Environment *env) {
6246 applyToAllEnvironments(envGetNodeClass);
6257 loadModulesIfNeeded();
6259 __block map<string, VuoCompilerNodeClass *> nodeClasses;
6260 void (^envGetNodeClasses)(Environment *) = ^
void (Environment *env) {
6261 map<string, VuoCompilerNodeClass *> result = env->getNodeClasses();
6262 nodeClasses.insert(result.begin(), result.end());
6264 applyToInstalledEnvironments(envGetNodeClasses);
6275 set<string> typeNameSet;
6276 typeNameSet.insert(typeName);
6277 loadModulesIfNeeded(typeNameSet);
6280 void (^envGetType)(Environment *) = ^
void (Environment *env) {
6285 applyToInstalledEnvironments(envGetType);
6307 loadModulesIfNeeded();
6309 __block map<string, VuoCompilerType *> types;
6310 void (^envGetTypes)(Environment *) = ^
void (Environment *env) {
6311 map<string, VuoCompilerType *> result = env->getTypes();
6312 types.insert(result.begin(), result.end());
6314 applyToInstalledEnvironments(envGetTypes);
6325 set<string> libraryNameSet;
6326 libraryNameSet.insert(libraryModuleName);
6327 loadModulesIfNeeded(libraryNameSet);
6330 void (^envGetLibraryModule)(Environment *) = ^
void (Environment *env) {
6335 applyToInstalledEnvironments(envGetLibraryModule);
6347 loadModulesIfNeeded();
6349 __block map<string, VuoCompilerModule *> libraryModules;
6350 void (^envGetLibraryModules)(Environment *) = ^
void (Environment *env) {
6351 map<string, VuoCompilerModule *> result = env->getLibraryModules();
6352 libraryModules.insert(result.begin(), result.end());
6354 applyToInstalledEnvironments(envGetLibraryModules);
6355 return libraryModules;
6365 loadModulesIfNeeded();
6367 __block map<string, VuoNodeSet *> nodeSets;
6368 void (^envGetNodeSets)(Environment *) = ^
void (Environment *env) {
6369 map<string, VuoNodeSet *> result = env->getNodeSets();
6370 nodeSets.insert(result.begin(), result.end());
6372 applyToInstalledEnvironments(envGetNodeSets);
6383 loadModulesIfNeeded();
6386 void (^envFindNodeSet)(Environment *) = ^
void (Environment *env) {
6391 applyToInstalledEnvironments(envFindNodeSet);
6401 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
6406 applyToAllEnvironments(envFindModule);
6423 map<string, VuoCompilerNodeClass *> nodeClasses =
getNodeClasses();
6424 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
6431 else if (format ==
"path")
6435 else if (format ==
"dot")
6457vector<string> VuoCompiler::getRunPathSearchPaths(Environment *narrowestScope)
6459 vector<string> rPaths;
6460 for (
size_t i = 0; i < environments.size(); ++i)
6465 if (! vuoFrameworkPath.empty())
6466 rPaths.push_back(vuoFrameworkPath +
"/..");
6475 if (! localModulesPath.empty())
6476 rPaths.push_back(localModulesPath);
6479 if (std::find(environments[i].begin(), environments[i].end(), narrowestScope) != environments[i].end())
6483 std::reverse(rPaths.begin(), rPaths.end());
6493vector<string> VuoCompiler::getCoreVuoDependencies(
void)
6495 vector<string> dependencies;
6497 dependencies.push_back(
"VuoHeap");
6498 dependencies.push_back(
"VuoApp");
6500 dependencies.push_back(
"zmq");
6501 dependencies.push_back(
"json-c");
6502 dependencies.push_back(
"objc");
6503 dependencies.push_back(
"c");
6504 dependencies.push_back(
"AppKit.framework");
6507 dependencies.push_back(LLVM_ROOT
"/lib/libprofile_rt.dylib");
6509 return dependencies;
6515string VuoCompiler::getRuntimeMainDependency(
void)
6517 return "VuoRuntimeMain.o";
6527string VuoCompiler::getRuntimeDependency(
void)
6529 return "VuoRuntime.o";
6540 if (! vuoFrameworkInProgressPath.empty())
6541 return vuoFrameworkInProgressPath;
6549string VuoCompiler::getClangPath(
void)
6560 string dir, moduleKey, ext;
6568 while (nodeClassNameParts.size() > 1 && nodeClassNameParts.back() == ext)
6569 nodeClassNameParts.pop_back();
6572 for (
string &part : nodeClassNameParts)
6576 if (nodeClassNameParts.size() == 1)
6577 nodeClassNameParts.insert(nodeClassNameParts.begin(),
"isf");
6591 __block
bool isLocal =
false;
6593 dispatch_sync(environmentQueue, ^{
6594 if (environments.size() >= 5)
6595 isLocal = environments.at(3).at(0)->findModule(moduleKey);
6609 return lastCompositionBaseDir.empty() ?
"" : lastCompositionBaseDir +
"/Modules";
6624 return lastCompositionBaseDir;
6630void VuoCompiler::addModuleSearchPath(
string path)
6632 dispatch_sync(environmentQueue, ^{
6633 environments.back().at(0)->addModuleSearchPath(path);
6643 dispatch_sync(environmentQueue, ^{
6653 dispatch_sync(environmentQueue, ^{
6663 dispatch_sync(environmentQueue, ^{
6673 this->isVerbose = isVerbose;
6683 if (VuoPro::getProAccess())
6685 _shouldShowSplashWindow =
false;
6690 _shouldShowSplashWindow = potentiallyShow;
6701 _setDependencyOutput(path);
6710 return _shouldShowSplashWindow;
6716void VuoCompiler::setClangPath(
const string &clangPath)
6718 this->clangPath = clangPath;
6727 return (vuoFrameworkPath.empty() ?
6728 VUO_BUILD_DIR
"/bin/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader" :
6729 vuoFrameworkPath +
"/Helpers/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader");
6735string VuoCompiler::getCompositionStubPath(
void)
6738 return (vuoFrameworkPath.empty() ?
6739 VUO_BUILD_DIR
"/lib/libVuoCompositionStub.dylib" :
6740 vuoFrameworkPath +
"/Modules/libVuoCompositionStub.dylib");
6746string VuoCompiler::getCachePathForComposition(
const string compositionDir)
6748 string modifierLetterColon(
"꞉");
6749 string cachedModulesName = compositionDir;
6759 __block vector<string> moduleSearchPaths;
6760 void (^envGetModuleSearchPaths)(Environment *) = ^
void (Environment *env) {
6761 vector<string> result = env->getModuleSearchPaths();
6762 moduleSearchPaths.insert(moduleSearchPaths.end(), result.begin(), result.end());
6764 applyToInstalledEnvironments(envGetModuleSearchPaths);
6766 __block vector<string> headerSearchPaths;
6767 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
6768 vector<string> result = env->getHeaderSearchPaths();
6769 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
6771 applyToInstalledEnvironments(envGetHeaderSearchPaths);
6773 __block vector<string> librarySearchPaths;
6774 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
6775 vector<string> result = env->getLibrarySearchPaths();
6776 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
6778 applyToInstalledEnvironments(envGetLibrarySearchPaths);
6780 __block vector<string> frameworkSearchPaths;
6781 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
6782 vector<string> result = env->getFrameworkSearchPaths();
6783 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
6785 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
6787 fprintf(stderr,
"Module (node class, type, library) search paths:\n");
6788 for (vector<string>::iterator i = moduleSearchPaths.begin(); i != moduleSearchPaths.end(); ++i)
6789 fprintf(stderr,
" %s\n", (*i).c_str());
6790 fprintf(stderr,
"Header search paths:\n");
6791 for (vector<string>::iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
6792 fprintf(stderr,
" %s\n", (*i).c_str());
6793 fprintf(stderr,
"Other library search paths:\n");
6794 for (vector<string>::iterator i = librarySearchPaths.begin(); i != librarySearchPaths.end(); ++i)
6795 fprintf(stderr,
" %s\n", (*i).c_str());
6796 fprintf(stderr,
"Other framework search paths:\n");
6797 for (vector<string>::iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
6798 fprintf(stderr,
" %s\n", (*i).c_str());
6799 fprintf(stderr,
"Framework path:\n");
6802 fprintf(stderr,
"Clang path:\n");
6803 if (! getClangPath().empty())
6804 fprintf(stderr,
" %s\n", getClangPath().c_str());
6820 string directory, file, extension;
6824 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6826 remove(compiledCompositionPath.c_str());
6855 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/" + processName +
".vuo";
6861 remove(compiledCompositionPath.c_str());
6885 string directory, file, extension;
6888 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6891 remove(compiledCompositionPath.c_str());
6920 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/UntitledComposition.vuo";
6926 remove(compiledCompositionPath.c_str());
6939 pendingDataQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.pending", 0);
6944 LoadedModulesData *data = dequeueData();
6951void VuoCompilerDelegate::enqueueData(LoadedModulesData *data)
6953 dispatch_sync(pendingDataQueue, ^{
6954 pendingData.push_back(data);
6961VuoCompilerDelegate::LoadedModulesData * VuoCompilerDelegate::dequeueData(
void)
6963 __block LoadedModulesData *ret;
6964 dispatch_sync(pendingDataQueue, ^{
6965 ret = pendingData.front();
6966 pendingData.pop_front();
6975VuoCompilerDelegate::LoadedModulesData::LoadedModulesData(
const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
6978 referenceCountQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.reference", 0);
6981 this->modulesModified = modulesModified;
6982 this->modulesRemoved = modulesRemoved;
6983 this->issues = issues;
6989VuoCompilerDelegate::LoadedModulesData::~LoadedModulesData(
void)
6993 for (set< pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); ++i)
6996 for (set<VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); ++i)
7003void VuoCompilerDelegate::LoadedModulesData::retain(
void)
7005 dispatch_sync(referenceCountQueue, ^{
7013void VuoCompilerDelegate::LoadedModulesData::release(
void)
7015 dispatch_sync(referenceCountQueue, ^{
7017 if (referenceCount == 0) {