11 #include <sys/param.h>
15 #include <CoreFoundation/CoreFoundation.h>
49 map<string, VuoFileUtilities::File *> VuoCompiler::Environment::moduleCacheFileForLocking;
50 dispatch_queue_t VuoCompiler::Environment::moduleCacheBuildingQueue = dispatch_queue_create(
"org.vuo.compiler.cache", NULL);
51 const string VuoCompiler::Environment::pidCacheDirPrefix =
"pid-";
52 set<VuoCompiler *> VuoCompiler::allCompilers;
53 dispatch_queue_t VuoCompiler::environmentQueue = dispatch_queue_create(
"org.vuo.compiler.environment", NULL);
54 map<string, vector< vector<VuoCompiler::Environment *> > > VuoCompiler::sharedEnvironments;
55 map<string, vector<VuoCompiler::Environment *> > VuoCompiler::environmentsForCompositionFamily;
56 dispatch_group_t VuoCompiler::moduleSourceCompilersExistGlobally = dispatch_group_create();
57 string VuoCompiler::vuoFrameworkInProgressPath;
66 static void __attribute__((constructor)) VuoCompiler_init(
void)
69 struct rlimit rl{OPEN_MAX, OPEN_MAX};
70 getrlimit(RLIMIT_NOFILE, &rl);
71 rl.rlim_cur =
MIN(OPEN_MAX, rl.rlim_max);
72 if (setrlimit(RLIMIT_NOFILE, &rl))
73 VUserLog(
"Warning: Couldn't set open-files limit: %s", strerror(errno));
76 llvmQueue = dispatch_queue_create(
"org.vuo.compiler.llvm", NULL);
80 llvm::InitializeAllTargetMCs();
81 llvm::InitializeAllTargets();
116 VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
const string &relativePath,
117 bool isSourceFile,
bool isSubcomposition)
120 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
126 VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
127 bool isSourceFile,
bool isSubcomposition)
129 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
135 void VuoCompiler::ModuleInfo::initialize(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
136 bool isSourceFile,
bool isSubcomposition)
138 this->environment = environment;
139 this->searchPath = searchPath;
142 sourceCodeOverridden =
false;
144 longestDownstreamPath = 0;
154 loading = dispatch_group_create();
157 if (isSubcomposition)
171 VuoCompiler::ModuleInfo::~ModuleInfo(
void)
180 dispatch_release(loading);
183 VuoCompiler::Environment * VuoCompiler::ModuleInfo::getEnvironment(
void)
const
188 string VuoCompiler::ModuleInfo::getSearchPath(
void)
const
193 string VuoCompiler::ModuleInfo::getModuleKey(
void)
const
203 string VuoCompiler::ModuleInfo::getSourceCode(
void)
const
208 void VuoCompiler::ModuleInfo::setSourceCode(
const string &sourceCode)
210 this->sourceCode = sourceCode;
213 void VuoCompiler::ModuleInfo::revertSourceCode(
void)
218 bool VuoCompiler::ModuleInfo::isSourceCodeOverridden(
void)
const
220 return sourceCodeOverridden;
223 void VuoCompiler::ModuleInfo::setSourceCodeOverridden(
bool overridden)
225 sourceCodeOverridden = overridden;
228 bool VuoCompiler::ModuleInfo::isNewerThan(ModuleInfo *other)
const
230 return lastModified > other->lastModified;
233 bool VuoCompiler::ModuleInfo::isNewerThan(
unsigned long ageInSeconds)
const
235 return lastModified > ageInSeconds;
238 bool VuoCompiler::ModuleInfo::isOlderThan(
unsigned long ageInSeconds)
const
240 return lastModified < ageInSeconds;
243 void VuoCompiler::ModuleInfo::setLastModifiedToNow(
void)
246 gettimeofday(&t, NULL);
247 lastModified = t.tv_sec;
250 set<string> VuoCompiler::ModuleInfo::getContainedNodeClasses(
void)
const
252 return containedNodeClasses;
255 int VuoCompiler::ModuleInfo::getLongestDownstreamPath(
void)
const
257 return longestDownstreamPath;
260 void VuoCompiler::ModuleInfo::setLongestDownstreamPath(
int pathLength)
262 longestDownstreamPath = pathLength;
265 bool VuoCompiler::ModuleInfo::getAttempted(
void)
const
270 void VuoCompiler::ModuleInfo::setAttempted(
bool attempted)
272 this->attempted = attempted;
275 dispatch_group_t VuoCompiler::ModuleInfo::getLoadingGroup(
void)
const
280 void VuoCompiler::ModuleInfo::dump()
const
282 fprintf(stderr,
"module %s:\n"
283 "\tloadingGroup=%p\n"
288 "\tsourceCodeOverridden=%d\n"
290 "\tcontainedNodeClasses:\n",
295 environment->getCompiledModuleCachePath().c_str(),
299 sourceCodeOverridden,
301 for (
auto i: containedNodeClasses)
302 fprintf(stderr,
"\t\t%s\n", i.c_str());
305 VuoCompiler::DependencyGraphVertex * VuoCompiler::DependencyGraphVertex::vertexForDependency(
const string &dependency,
VuoDirectedAcyclicGraph *graph)
309 return dynamic_cast<DependencyGraphVertex *
>(v);
311 DependencyGraphVertex *vv =
new DependencyGraphVertex();
312 vv->dependency = dependency;
313 vv->environment = NULL;
314 vv->compatible =
true;
318 string VuoCompiler::DependencyGraphVertex::getDependency(
void)
323 VuoCompiler::Environment * VuoCompiler::DependencyGraphVertex::getEnvironment(
void)
328 void VuoCompiler::DependencyGraphVertex::setEnvironment(Environment *environment)
330 this->environment = environment;
333 bool VuoCompiler::DependencyGraphVertex::isCompatible(
void)
338 void VuoCompiler::DependencyGraphVertex::setCompatible(
bool compatible)
340 this->compatible = compatible;
343 string VuoCompiler::DependencyGraphVertex::key(
void)
353 VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos)
355 this->allModuleInfos = allModuleInfos;
356 hasSearchModuleKeys =
false;
365 VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos,
const set<string> &searchModuleKeys)
367 this->allModuleInfos = allModuleInfos;
368 this->searchModuleKeys = searchModuleKeys;
369 hasSearchModuleKeys =
true;
378 void VuoCompiler::ModuleInfoIterator::initialize(
void)
380 currSearchPath = allModuleInfos->begin();
381 hasCurrModuleKey =
false;
389 VuoCompiler::ModuleInfo * VuoCompiler::ModuleInfoIterator::next(
void)
391 for ( ; currSearchPath != allModuleInfos->end(); ++currSearchPath)
393 if (! hasCurrModuleKey)
395 currModuleKey = currSearchPath->second.begin();
396 hasCurrModuleKey =
true;
399 for ( ; currModuleKey != currSearchPath->second.end(); ++currModuleKey)
401 if (! hasSearchModuleKeys || searchModuleKeys.find(currModuleKey->first) != searchModuleKeys.end())
403 ModuleInfo *moduleInfo = currModuleKey->second;
409 hasCurrModuleKey =
false;
418 VuoCompiler::Environment::Environment(
string target,
bool builtIn,
bool generated)
419 : target(target), builtIn(builtIn), generated(generated)
421 compilersToNotifyQueue = dispatch_queue_create(
"org.vuo.compiler.notify", 0);
422 moduleSearchPathContentsChangedQueue = dispatch_queue_create(
"org.vuo.compiler.watch", 0);
423 lastModuleCacheRebuild = 0;
424 isModuleCacheableDataDirty =
false;
425 isModuleCacheInitialized =
false;
426 isModuleCacheAvailable =
false;
435 VuoCompiler::Environment::~Environment(
void)
437 stopWatchingModuleSearchPaths();
438 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{});
440 dispatch_release(moduleSearchPathContentsChangedQueue);
441 dispatch_release(compilersToNotifyQueue);
443 for (map<string, VuoCompilerNodeClass *>::iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
444 destroyModule(i->second);
446 for (map<string, VuoCompilerType *>::iterator i = types.begin(); i != types.end(); ++i)
447 destroyModule(i->second);
449 for (map<string, VuoCompilerModule *>::iterator i = libraryModules.begin(); i != libraryModules.end(); ++i)
450 destroyModule(i->second);
452 for (set<VuoCompilerGenericType *>::iterator i = genericTypes.begin(); i != genericTypes.end(); ++i)
454 VuoType *base = (*i)->getBase();
459 for (map<string, VuoNodeSet *>::iterator i = nodeSetForName.begin(); i != nodeSetForName.end(); ++i)
462 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
463 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
466 for (map<
string, map<string, ModuleInfo *> >::iterator i = sourceFilesAtSearchPath.begin(); i != sourceFilesAtSearchPath.end(); ++i)
467 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
470 delete dependencyGraph;
471 delete compositionDependencyGraph;
477 string VuoCompiler::Environment::getTarget()
485 void VuoCompiler::Environment::addCompilerToNotify(
VuoCompiler *compiler)
487 dispatch_sync(compilersToNotifyQueue, ^{
488 compilersToNotify.insert(compiler);
495 void VuoCompiler::Environment::removeCompilerToNotify(
VuoCompiler *compiler)
497 dispatch_sync(compilersToNotifyQueue, ^{
498 compilersToNotify.erase(compiler);
507 map<string, VuoCompilerNodeClass *> VuoCompiler::Environment::getNodeClasses(
void)
519 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
520 if (nodeClassIter != nodeClasses.end())
521 return nodeClassIter->second;
534 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
535 if (nodeClassIter != nodeClasses.end())
537 nodeClass = nodeClassIter->second;
539 nodeClasses.erase(nodeClassIter);
540 removeFromDependencyGraph(nodeClass);
552 map<string, VuoCompilerType *> VuoCompiler::Environment::getTypes(
void)
562 VuoCompilerType * VuoCompiler::Environment::getType(
const string &moduleKey)
564 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
565 if (typeIter != types.end())
566 return typeIter->second;
576 map<string, VuoNodeSet *> VuoCompiler::Environment::getNodeSets(
void)
578 return nodeSetForName;
586 VuoCompilerModule *VuoCompiler::Environment::getLibraryModule(
const string &libraryModuleName)
588 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(libraryModuleName);
589 if (libraryIter != libraryModules.end())
590 return libraryIter->second;
600 map<string, VuoCompilerModule *> VuoCompiler::Environment::getLibraryModules(
void)
602 return libraryModules;
611 VuoCompilerModule * VuoCompiler::Environment::findModule(
const string &moduleKey)
613 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
614 if (nodeClassIter != nodeClasses.end())
615 return nodeClassIter->second;
617 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
618 if (typeIter != types.end())
619 return typeIter->second;
621 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(moduleKey);
622 if (libraryIter != libraryModules.end())
623 return libraryIter->second;
633 VuoNodeSet * VuoCompiler::Environment::findNodeSet(
const string &name)
636 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(name);
637 if (nodeSetIter != nodeSetForName.end())
638 return nodeSetIter->second;
649 void VuoCompiler::Environment::addModuleSearchPath(
const string &path,
bool shouldWatch)
651 moduleSearchPaths.push_back(path);
653 updateModulesAtSearchPath(path);
654 updateSourceFilesAtSearchPath(path);
657 startWatchingModuleSearchPath(path);
665 vector<string> VuoCompiler::Environment::getModuleSearchPaths(
void)
667 return moduleSearchPaths;
675 void VuoCompiler::Environment::addHeaderSearchPath(
const string &path)
677 headerSearchPaths.push_back(path);
685 vector<string> VuoCompiler::Environment::getHeaderSearchPaths(
void)
687 return headerSearchPaths;
695 void VuoCompiler::Environment::addLibrarySearchPath(
const string &path)
697 librarySearchPaths.push_back(path);
705 vector<string> VuoCompiler::Environment::getLibrarySearchPaths(
void)
707 return librarySearchPaths;
715 void VuoCompiler::Environment::addFrameworkSearchPath(
const string &path)
717 frameworkSearchPaths.push_back(path);
725 vector<string> VuoCompiler::Environment::getFrameworkSearchPaths(
void)
727 return frameworkSearchPaths;
732 return dependencyGraph;
737 return compositionDependencyGraph;
745 void VuoCompiler::Environment::setModuleCachePath(
const string &path)
747 moduleCachePath = path;
755 string VuoCompiler::Environment::getCompiledModuleCachePath(
void)
757 return (moduleCachePath.empty() ?
"" : moduleCachePath +
"/Modules");
765 string VuoCompiler::Environment::getOverriddenCompiledModuleCachePath(
void)
767 if (moduleCachePath.empty())
773 string dir, moduleCacheDirName, ext;
786 void VuoCompiler::Environment::addExpatriateSourceFile(
const string &sourcePath)
788 expatriateSourceFiles.push_back(sourcePath);
790 if (find(moduleSearchPaths.begin(), moduleSearchPaths.end(),
"") == moduleSearchPaths.end())
791 moduleSearchPaths.push_back(
"");
793 auto iter = sourceFilesAtSearchPath.find(
"");
794 if (iter != sourceFilesAtSearchPath.end())
795 sourceFilesAtSearchPath.erase(iter);
803 void VuoCompiler::Environment::removeExpatriateSourceFile(
const string &sourcePath)
805 for (
auto i = expatriateSourceFiles.begin(); i != expatriateSourceFiles.end(); ++i)
809 expatriateSourceFiles.erase(i);
811 auto iter = sourceFilesAtSearchPath.find(
"");
812 if (iter != sourceFilesAtSearchPath.end())
813 sourceFilesAtSearchPath.erase(iter);
832 void VuoCompiler::Environment::updateModulesAtSearchPath(
const string &path)
834 if (moduleFilesAtSearchPath.find(path) != moduleFilesAtSearchPath.end())
837 set<string> moduleExtensions;
838 moduleExtensions.insert(
"vuonode");
839 moduleExtensions.insert(
"vuonode+");
840 moduleExtensions.insert(
"bc");
841 moduleExtensions.insert(
"bc+");
842 set<string> archiveExtensions;
843 archiveExtensions.insert(
"vuonode");
846 map<string, ModuleInfo *> fileForModuleKey;
847 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
855 ModuleInfo *m =
new ModuleInfo(
this, path, moduleFile,
false,
false);
856 fileForModuleKey[m->getModuleKey()] = m;
859 if (path == getCompiledModuleCachePath())
861 for (map<string, ModuleInfo *>::iterator i = fileForModuleKey.begin(); i != fileForModuleKey.end(); )
863 ModuleInfo *sourceInfo = listSourceFile(i->first);
864 if (! sourceInfo || sourceInfo->isNewerThan(i->second))
866 ModuleInfo *m = i->second;
869 fileForModuleKey.erase(i++);
876 moduleFilesAtSearchPath[path] = fileForModuleKey;
884 void VuoCompiler::Environment::updateModuleAtSearchPath(
const string &moduleSearchPath,
const string &moduleRelativePath)
886 string dir, file, ext;
889 set<string> moduleExtensions;
890 moduleExtensions.insert(ext);
891 set<string> archiveExtensions;
892 archiveExtensions.insert(
"vuonode");
896 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
900 ModuleInfo *m =
new ModuleInfo(
this, moduleSearchPath, moduleFile,
false,
false);
901 moduleFilesAtSearchPath[moduleSearchPath][m->getModuleKey()] = m;
912 void VuoCompiler::Environment::updateSourceFilesAtSearchPath(
const string &path)
914 map<string, map<string, ModuleInfo *> >::iterator sourceFilesIter = sourceFilesAtSearchPath.find(path);
915 if (sourceFilesIter != sourceFilesAtSearchPath.end())
918 set<VuoFileUtilities::File *> sourceFiles;
921 set<string> sourceExtensions;
922 sourceExtensions.insert(
"vuo");
923 sourceExtensions.insert(
"fs");
925 sourceExtensions.insert(cext.begin(), cext.end());
930 for (
const string &sourcePath : expatriateSourceFiles)
932 string dir, file, ext;
935 sourceFiles.insert(sourceFile);
939 map<string, ModuleInfo *> fileForModuleKey;
940 for (set<VuoFileUtilities::File *>::iterator i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
944 string dir, moduleKey, ext;
946 bool isSubcomposition = (ext ==
"vuo");
949 if (path.empty() && !sourceFile->
exists())
952 ModuleInfo *m =
new ModuleInfo(
this, path, sourceFile,
true, isSubcomposition);
953 if (fileForModuleKey.find(m->getModuleKey()) != fileForModuleKey.end())
954 VUserLog(
"Warning: Conflicting source files for module %s are installed at %s", m->getModuleKey().c_str(), path.c_str());
955 fileForModuleKey[m->getModuleKey()] = m;
957 if (isSubcomposition)
959 DependencyGraphVertex *compositionVertex = DependencyGraphVertex::vertexForDependency(moduleKey, compositionDependencyGraph);
960 compositionDependencyGraph->addVertex(compositionVertex);
962 compositionVertex->setEnvironment(
this);
964 set<string> dependencies = m->getContainedNodeClasses();
965 for (set<string>::iterator j = dependencies.begin(); j != dependencies.end(); ++j)
967 DependencyGraphVertex *dependencyVertex = DependencyGraphVertex::vertexForDependency(*j, compositionDependencyGraph);
968 compositionDependencyGraph->addEdge(compositionVertex, dependencyVertex);
973 sourceFilesAtSearchPath[path] = fileForModuleKey;
981 VuoCompiler::ModuleInfo * VuoCompiler::Environment::listModule(
const string &moduleKey)
983 for (
const auto &moduleFiles : moduleFilesAtSearchPath)
985 map<string, ModuleInfo *>::const_iterator foundIter = moduleFiles.second.find(moduleKey);
986 if (foundIter != moduleFiles.second.end())
987 return foundIter->second;
998 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listModules(
const set<string> &moduleKeys)
1000 for (
const string &path : moduleSearchPaths)
1001 updateModulesAtSearchPath(path);
1003 return ModuleInfoIterator(&moduleFilesAtSearchPath, moduleKeys);
1011 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllModules(
void)
1013 for (
const string &path : moduleSearchPaths)
1014 updateModulesAtSearchPath(path);
1016 return ModuleInfoIterator(&moduleFilesAtSearchPath);
1024 VuoCompiler::ModuleInfo * VuoCompiler::Environment::listSourceFile(
const string &moduleKey)
1026 for (
const auto &sourceFiles : sourceFilesAtSearchPath)
1028 map<string, ModuleInfo *>::const_iterator foundIter = sourceFiles.second.find(moduleKey);
1029 if (foundIter != sourceFiles.second.end())
1030 return foundIter->second;
1041 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listSourceFiles(
const set<string> &moduleKeys)
1043 for (
const string &path : moduleSearchPaths)
1044 updateSourceFilesAtSearchPath(path);
1046 return ModuleInfoIterator(&sourceFilesAtSearchPath, moduleKeys);
1054 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllSourceFiles(
void)
1056 for (
const string &path : moduleSearchPaths)
1057 updateSourceFilesAtSearchPath(path);
1059 return ModuleInfoIterator(&sourceFilesAtSearchPath);
1065 vector<string> VuoCompiler::Environment::getBuiltInModuleSearchPaths(
void)
1067 vector<string> builtInModuleSearchPaths;
1069 string vuoFrameworkPath = getVuoFrameworkPath();
1070 if (! vuoFrameworkPath.empty())
1072 builtInModuleSearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1076 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/library");
1077 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/node");
1078 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type");
1079 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1082 return builtInModuleSearchPaths;
1088 vector<string> VuoCompiler::Environment::getBuiltInHeaderSearchPaths(
void)
1090 vector<string> builtInHeaderSearchPaths;
1092 string vuoFrameworkPath = getVuoFrameworkPath();
1093 if (! vuoFrameworkPath.empty())
1095 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers");
1096 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos");
1097 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos/pthread");
1098 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/Headers/lib/c++/v1");
1102 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/library");
1103 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/node");
1104 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type");
1105 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type/list");
1106 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/runtime");
1107 builtInHeaderSearchPaths.push_back(JSONC_ROOT
"/include");
1108 builtInHeaderSearchPaths.push_back(LLVM_ROOT
"/include/c++/v1");
1111 return builtInHeaderSearchPaths;
1117 vector<string> VuoCompiler::Environment::getBuiltInLibrarySearchPaths(
void)
1119 vector<string> builtInLibrarySearchPaths;
1121 string vuoFrameworkPath = getVuoFrameworkPath();
1122 if (! vuoFrameworkPath.empty())
1124 builtInLibrarySearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1127 builtInLibrarySearchPaths.push_back(OPENSSL_ROOT
"/lib");
1131 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/library");
1132 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/node");
1133 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type");
1134 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1135 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/runtime");
1138 builtInLibrarySearchPaths.insert(builtInLibrarySearchPaths.end(), conanLibDirs.begin(), conanLibDirs.end());
1141 return builtInLibrarySearchPaths;
1147 vector<string> VuoCompiler::Environment::getBuiltInFrameworkSearchPaths(
void)
1149 vector<string> builtInFrameworkSearchPaths;
1151 string vuoFrameworkPath = getVuoFrameworkPath();
1152 if (! vuoFrameworkPath.empty())
1154 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Modules/");
1155 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/");
1158 return builtInFrameworkSearchPaths;
1167 void VuoCompiler::Environment::startWatchingModuleSearchPath(
const string &moduleSearchPath)
1170 moduleSearchPathWatchers.insert(watcher);
1178 void VuoCompiler::Environment::stopWatchingModuleSearchPaths(
void)
1180 for (set<VuoFileWatcher *>::iterator i = moduleSearchPathWatchers.begin(); i != moduleSearchPathWatchers.end(); ++i)
1183 moduleSearchPathWatchers.clear();
1190 void VuoCompiler::Environment::fileChanged(
const string &moduleSearchPath)
1192 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{
1193 moduleSearchPathContentsChanged(moduleSearchPath);
1204 void VuoCompiler::Environment::moduleSearchPathContentsChanged(
const string &moduleSearchPath)
1209 __block set<string> modulesAdded;
1210 __block set<string> modulesModifed;
1211 __block set<string> modulesRemoved;
1212 __block set<string> compositionsAdded;
1213 __block set<string> compositionsModifed;
1214 __block set<string> compositionsRemoved;
1216 dispatch_sync(environmentQueue, ^{
1220 map<string, ModuleInfo *> oldModules;
1221 map<string, ModuleInfo *> oldCompositions;
1223 map<string, map<string, ModuleInfo *> >::iterator mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1224 if (mf != moduleFilesAtSearchPath.end())
1226 for (map<string, ModuleInfo *>::iterator j = mf->second.begin(); j != mf->second.end(); ++j)
1228 oldModules[j->first] = j->second;
1231 moduleFilesAtSearchPath.erase(mf);
1234 map<string, map<string, ModuleInfo *> >::iterator cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1235 if (cf != sourceFilesAtSearchPath.end())
1237 for (map<string, ModuleInfo *>::iterator j = cf->second.begin(); j != cf->second.end(); ++j)
1239 oldCompositions[j->first] = j->second;
1241 VuoDirectedAcyclicGraph::Vertex *vertex = compositionDependencyGraph->findVertex(j->first);
1242 compositionDependencyGraph->removeVertex(vertex);
1245 sourceFilesAtSearchPath.erase(cf);
1250 updateModulesAtSearchPath(moduleSearchPath);
1251 updateSourceFilesAtSearchPath(moduleSearchPath);
1255 mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1256 if (mf != moduleFilesAtSearchPath.end())
1258 for (map<string, ModuleInfo *>::iterator n = mf->second.begin(); n != mf->second.end(); ++n)
1260 string moduleKey = n->first;
1262 map<string, ModuleInfo *>::iterator o = oldModules.find(moduleKey);
1263 if (o != oldModules.end())
1265 if (n->second->isNewerThan(o->second))
1267 modulesModifed.insert(moduleKey);
1271 n->second->setAttempted(o->second->getAttempted());
1275 oldModules.erase(o);
1279 modulesAdded.insert(moduleKey);
1284 cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1285 if (cf != sourceFilesAtSearchPath.end())
1287 for (map<string, ModuleInfo *>::iterator n = cf->second.begin(); n != cf->second.end(); ++n)
1289 string moduleKey = n->first;
1291 map<string, ModuleInfo *>::iterator o = oldCompositions.find(moduleKey);
1292 if (o != oldCompositions.end())
1294 if (n->second->isNewerThan(o->second))
1296 compositionsModifed.insert(moduleKey);
1300 n->second->setAttempted(o->second->getAttempted());
1301 n->second->setSourceCode(o->second->getSourceCode());
1305 oldCompositions.erase(o);
1309 compositionsAdded.insert(moduleKey);
1314 for (map<string, ModuleInfo *>::iterator o = oldModules.begin(); o != oldModules.end(); ++o)
1317 modulesRemoved.insert(o->first);
1320 for (map<string, ModuleInfo *>::iterator o = oldCompositions.begin(); o != oldCompositions.end(); ++o)
1323 compositionsRemoved.insert(o->first);
1326 compilerForLoading->loadModulesAndSources(modulesAdded, modulesModifed, modulesRemoved,
1327 compositionsAdded, compositionsModifed, compositionsRemoved,
1328 false,
false,
this,
nullptr,
nullptr,
"");
1331 delete compilerForLoading;
1340 void VuoCompiler::Environment::moduleFileChanged(
const string &modulePath,
const string &moduleSourceCode,
1341 std::function<
void(
void)> moduleLoadedCallback,
1345 dispatch_sync(environmentQueue, ^{
1347 string moduleDir, moduleKey, ext;
1353 bool foundOldModule =
false;
1354 auto moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1355 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1357 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1358 if (moduleIter != moduleSearchPathIter->second.end())
1360 delete moduleIter->second;
1361 moduleSearchPathIter->second.erase(moduleIter);
1362 foundOldModule =
true;
1368 updateModuleAtSearchPath(moduleDir, moduleKey +
"." + ext);
1372 bool foundNewModule =
false;
1373 moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1374 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1376 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1377 if (moduleIter != moduleSearchPathIter->second.end())
1379 foundNewModule =
true;
1383 set<string> modulesAdded;
1384 set<string> modulesModified;
1385 set<string> modulesRemoved;
1389 modulesModified.insert(moduleKey);
1391 else if (! foundOldModule && foundNewModule)
1393 modulesAdded.insert(moduleKey);
1395 else if (foundOldModule && ! foundNewModule)
1397 modulesRemoved.insert(moduleKey);
1400 compiler->loadModulesAndSources(modulesAdded, modulesModified, modulesRemoved,
1401 set<string>(), set<string>(), set<string>(),
1402 false,
false,
this, issues, moduleLoadedCallback, moduleSourceCode);
1410 void VuoCompiler::Environment::notifyCompilers(
const set<VuoCompilerModule *> &modulesAdded,
1411 const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
1413 bool oldModulesInvalidated)
1415 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()) )
1417 set< pair<VuoCompilerModule *, VuoCompilerModule *> > invalidatedModulesModified;
1418 set<VuoCompilerModule *> invalidatedModulesRemoved;
1419 if (oldModulesInvalidated)
1421 invalidatedModulesModified = modulesModified;
1422 invalidatedModulesRemoved = modulesRemoved;
1425 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(invalidatedModulesModified, invalidatedModulesRemoved, issues);
1427 map<string, VuoCompilerModule *> modulesAddedMap;
1428 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModifiedMap;
1429 map<string, VuoCompilerModule *> modulesRemovedMap;
1431 modulesAddedMap[m->getPseudoBase()->getModuleKey()] = m;
1432 for (pair<VuoCompilerModule *, VuoCompilerModule *> m : modulesModified)
1433 modulesModifiedMap[m.first->getPseudoBase()->getModuleKey()] = m;
1435 modulesRemovedMap[m->getPseudoBase()->getModuleKey()] = m;
1437 dispatch_sync(compilersToNotifyQueue, ^{
1438 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1439 delegateData->retain();
1441 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1442 (*i)->loadedModules(modulesAddedMap, modulesModifiedMap, modulesRemovedMap, issues, delegateData, this);
1462 set<VuoCompilerModule *> VuoCompiler::Environment::loadCompiledModules(
const set<string> &moduleKeys,
const map<string, string> &sourceCodeForModule)
1464 ModuleInfoIterator modulesToLoadIter = listModules(moduleKeys);
1465 set<VuoCompilerModule *> modulesLoaded;
1467 ModuleInfo *moduleInfo;
1468 while ((moduleInfo = modulesToLoadIter.next()))
1470 string moduleKey = moduleInfo->getModuleKey();
1474 if (moduleInfo->getEnvironment() !=
this || findModule(moduleKey) || moduleInfo->getAttempted())
1477 moduleInfo->setAttempted(
true);
1484 modulesLoaded.insert(module);
1485 addToDependencyGraph(module);
1489 string searchPath = moduleInfo->getSearchPath();
1496 ModuleInfo *sourceInfo = listSourceFile(moduleKey);
1500 auto sourceCodeIter = sourceCodeForModule.find(moduleKey);
1501 if (sourceCodeIter != sourceCodeForModule.end())
1508 return modulesLoaded;
1522 set<dispatch_group_t> VuoCompiler::Environment::loadSpecializedModules(
const set<string> &moduleKeys,
1525 set<dispatch_group_t > loadingGroups;
1527 for (
string moduleKey : moduleKeys)
1536 if (findModule(moduleKey))
1541 map<string, dispatch_group_t>::iterator iter = specializedModulesLoading.find(moduleKey);
1542 if (iter != specializedModulesLoading.end())
1544 loadingGroups.insert(iter->second);
1545 dispatch_retain(iter->second);
1549 dispatch_group_t loadingGroup = dispatch_group_create();
1550 specializedModulesLoading[moduleKey] = loadingGroup;
1551 loadingGroups.insert(loadingGroup);
1557 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1558 dispatch_group_async(loadingGroup, queue, ^{
1572 compiler->loadNodeClassGeneratedAtRuntime(specNodeClass,
this);
1575 if (!dependencies.empty())
1576 compiler->loadModulesIfNeeded(dependencies);
1579 dispatch_sync(environmentQueue, ^{
1580 specializedModulesLoading.erase(moduleKey);
1585 return loadingGroups;
1600 set<dispatch_group_t> VuoCompiler::Environment::compileModulesFromSourceCode(
const set<string> &moduleKeys,
bool shouldRecompileIfUnchanged)
1602 ModuleInfoIterator modulesToLoadIter = listSourceFiles(moduleKeys);
1604 int environmentIndex = sharedEnvironments[target].size();
1605 for (
int i = 0; i < sharedEnvironments[target].size(); ++i)
1606 if (
this == sharedEnvironments[target].at(i).at(0))
1607 environmentIndex = i;
1609 set<dispatch_group_t> sourcesLoading;
1610 int sourcesEnqueued = 0;
1611 ModuleInfo *sourceInfo;
1612 while ((sourceInfo = modulesToLoadIter.next()))
1614 string moduleKey = sourceInfo->getModuleKey();
1616 dispatch_group_t loadingGroup = sourceInfo->getLoadingGroup();
1617 sourcesLoading.insert(loadingGroup);
1622 if (sourceInfo->getAttempted())
1627 string sourceCode = sourceInfo->getSourceCode();
1629 if (! shouldRecompileIfUnchanged)
1632 if (existingNodeClass && existingNodeClass->
getSourceCode() == sourceCode)
1638 sourceInfo->setAttempted(
true);
1640 dispatch_group_enter(loadingGroup);
1641 dispatch_group_enter(moduleSourceCompilersExistGlobally);
1645 queueItem->
sourcePath = sourceInfo->getFile()->path();
1647 queueItem->
sourceFile = sourceInfo->getFile();
1648 queueItem->
cachedModulesPath = sourceInfo->isSourceCodeOverridden() ? getOverriddenCompiledModuleCachePath() : getCompiledModuleCachePath();
1651 queueItem->
priority = { environmentIndex, sourceInfo->getLongestDownstreamPath() };
1652 moduleCompilationQueue->enqueue(queueItem);
1661 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1662 dispatch_async(queue, ^{
1663 for (
int i = 0; i < sourcesEnqueued; ++i)
1666 VUserLog(
"Compiling %s", queueItem->moduleKey.c_str());
1668 dispatch_async(queue, ^{
1677 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1683 auto moduleLoadedCallback = [=](){
1684 dispatch_group_leave(queueItemForCallback->
loadingGroup);
1685 moduleCompilationQueue->completed(queueItemForCallback);
1688 string ext = queueItem->sourceFile->extension();
1699 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1706 auto getType = [&compiler] (
const string &moduleKey) {
return compiler->
getType(moduleKey); };
1714 writeModuleToBitcode(module, queueItem->compiledModulePath);
1722 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1725 moduleLoadedCallback();
1731 compiler->
compileModule(queueItem->sourcePath, queueItem->compiledModulePath, vector<string>());
1732 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler,
nullptr);
1739 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1740 moduleLoadedCallback();
1746 compiler->compileSubcompositionString(queueItem->sourceCode, queueItem->compiledModulePath, moduleLoadedCallback,
this, NULL, queueItem->sourcePath);
1750 dispatch_group_leave(moduleSourceCompilersExistGlobally);
1755 return sourcesLoading;
1766 set<VuoCompilerModule *> VuoCompiler::Environment::unloadCompiledModules(
const set<string> &moduleKeys)
1768 set<VuoCompilerModule *> modulesUnloaded;
1770 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1772 string moduleKey = *i;
1775 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
1776 if (nodeClassIter != nodeClasses.end())
1778 module = nodeClassIter->second;
1779 nodeClasses.erase(nodeClassIter);
1783 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
1784 if (typeIter != types.end())
1786 module = typeIter->second;
1787 types.erase(typeIter);
1791 map<string, VuoCompilerModule *>::iterator libraryModuleIter = libraryModules.find(moduleKey);
1792 if (libraryModuleIter != libraryModules.end())
1794 module = libraryModuleIter->second;
1795 libraryModules.erase(libraryModuleIter);
1802 modulesUnloaded.insert(module);
1803 removeFromDependencyGraph(module);
1808 return modulesUnloaded;
1816 void VuoCompiler::Environment::deleteModulesCompiledFromSourceCode(
const set<string> &moduleKeys)
1818 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1820 string moduleKey = *i;
1822 map<string, ModuleInfo *>::iterator iter = moduleFilesAtSearchPath[getCompiledModuleCachePath()].find(moduleKey);
1823 if (iter != moduleFilesAtSearchPath[getCompiledModuleCachePath()].end())
1835 VuoCompilerModule * VuoCompiler::Environment::loadModule(ModuleInfo *moduleInfo)
1837 string moduleKey = moduleInfo->getModuleKey();
1851 __block
size_t inputDataBytes;
1852 __block
char *rawInputData;
1856 rawInputData = moduleInfo->getFile()->getContentsAsRawData(inputDataBytes);
1860 rawInputData = NULL;
1861 VUserLog(
"Warning: Couldn't load module '%s'. Its file may have been deleted. (%s)", moduleKey.c_str(), e.
what());
1867 char *processedInputData;
1869 processedInputData = loadModule_Pro0(moduleInfo, moduleKey, inputDataBytes, rawInputData);
1871 processedInputData = rawInputData;
1874 Module *module = NULL;
1875 bool moduleParseError = !processedInputData;
1876 if (!moduleParseError)
1878 string moduleReadError;
1879 string arch = VuoCompiler::getTargetArch(target);
1880 VuoLog_status(
"Loading module \"%s\" (%s)", moduleKey.c_str(), arch.c_str());
1881 module = readModuleFromBitcodeData(processedInputData, inputDataBytes, arch, moduleReadError);
1883 free(processedInputData);
1887 moduleParseError =
true;
1889 string dir, file, ext;
1890 VuoFileUtilities::splitPath(moduleInfo->getFile()->isInArchive() ? moduleInfo->getFile()->getRelativePath() : moduleInfo->getFile()->path(), dir, file, ext);
1892 if (dir == getCompiledModuleCachePath())
1895 VUserLog(
"Error: Couldn't load module '%s' into %s environment: %s.", moduleInfo->getFile()->getRelativePath().c_str(), arch.c_str(), moduleReadError.c_str());
1899 if (!moduleParseError)
1902 if (! moduleInfo->getFile()->isInArchive())
1903 modulePath = moduleInfo->getFile()->path();
1917 libraryModules[moduleKey] = compilerModule;
1922 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(nodeSet->
getName());
1923 if (nodeSetIter == nodeSetForName.end())
1925 nodeSetForName[nodeSet->
getName()] = nodeSet;
1930 nodeSet = nodeSetIter->second;
1932 compilerModule->getPseudoBase()->setNodeSet(nodeSet);
1936 loadModule_Pro1(rawInputData, processedInputData, compilerModule);
1939 compilerModule->setBuiltIn( isBuiltInOriginal() );
1941 return compilerModule;
1945 destroyLlvmModule(module);
1964 removeFromDependencyGraph(oldNodeClass);
1965 destroyModule(oldNodeClass);
1968 nodeClasses[moduleKey] = newNodeClass;
1969 addToDependencyGraph(newNodeClass);
1975 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
1976 dependencyGraph->addVertex(vertex);
1978 vertex->setEnvironment(
this);
1984 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
1986 DependencyGraphVertex *depVertex = DependencyGraphVertex::vertexForDependency(*i, dependencyGraph);
1987 dependencyGraph->addEdge(vertex, depVertex);
1991 void VuoCompiler::Environment::removeFromDependencyGraph(
VuoCompilerModule *module)
1993 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
1994 dependencyGraph->removeVertex(vertex);
2007 void VuoCompiler::Environment::reifyPortTypes(
const map<string, VuoCompilerType *> &inheritedTypes)
2009 map<string, VuoCompilerType *> availableTypes = inheritedTypes;
2010 availableTypes.insert(types.begin(), types.end());
2012 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
2018 vector<VuoPortClass *> portClasses;
2019 portClasses.insert(portClasses.end(), inputPortClasses.begin(), inputPortClasses.end());
2020 portClasses.insert(portClasses.end(), outputPortClasses.begin(), outputPortClasses.end());
2022 for (vector<VuoPortClass *>::iterator j = portClasses.begin(); j != portClasses.end(); ++j)
2042 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2043 if (reifiedTypeIter != availableTypes.end())
2046 reifiedType = reifiedTypeIter->second;
2057 for (vector<VuoCompilerTriggerDescription *>::iterator j = triggers.begin(); j != triggers.end(); ++j)
2065 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2066 if (reifiedTypeIter != availableTypes.end())
2087 void VuoCompiler::Environment::getCacheableModulesAndDependencies(set<string> &cacheableModulesAndDependencies,
2088 set<string> &dylibsNeededToLinkToThisCache,
2089 set<string> &frameworksNeededToLinkToThisCache)
2091 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty)
2093 cacheableModulesAndDependencies = moduleCacheContents;
2094 dylibsNeededToLinkToThisCache = moduleCacheDylibs;
2095 frameworksNeededToLinkToThisCache = moduleCacheFrameworks;
2102 map<string, VuoCompilerModule *> allModules;
2103 allModules.insert(nodeClasses.begin(), nodeClasses.end());
2104 allModules.insert(types.begin(), types.end());
2105 allModules.insert(libraryModules.begin(), libraryModules.end());
2107 set<string> dependencies;
2108 for (map<string, VuoCompilerModule *>::iterator i = allModules.begin(); i != allModules.end(); ++i)
2110 string moduleKey = i->first;
2115 if (module->requiresPro())
2123 cacheableModulesAndDependencies.insert(moduleKey);
2126 dependencies.insert(moduleDependencies.begin(), moduleDependencies.end());
2130 if (builtIn && ! generated)
2132 vector<string> coreDependencies = getCoreVuoDependencies();
2133 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
2138 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
2140 string dependency = *i;
2141 if (allModules.find(dependency) == allModules.end())
2144 frameworksNeededToLinkToThisCache.insert(dependency);
2147 string dependencyPath = VuoCompiler::getLibraryPath(dependency, librarySearchPaths);
2148 if (! dependencyPath.empty())
2151 dylibsNeededToLinkToThisCache.insert(dependencyPath);
2153 cacheableModulesAndDependencies.insert(dependency);
2159 moduleCacheDylibs = dylibsNeededToLinkToThisCache;
2160 moduleCacheFrameworks = frameworksNeededToLinkToThisCache;
2186 void VuoCompiler::Environment::useModuleCache(
bool shouldUseExistingCache,
VuoCompiler *compiler,
2187 set<string> cacheableModulesAndDependencies,
2188 set<string> dylibsNeededToLinkToCaches, set<string> frameworksNeededToLinkToCaches,
2189 unsigned long lastPrerequisiteModuleCacheRebuild)
2193 static dispatch_once_t checked = 0;
2194 static bool prelinkCache =
true;
2195 dispatch_once(&checked, ^{
2197 bool result = CFPreferencesGetAppBooleanValue(CFSTR(
"prelinkCache"), CFSTR(
"org.vuo.Editor"), &valid);
2199 prelinkCache = result;
2203 VDebugLog(
"Ignoring the module cache since the 'prelinkCache' preference is false.");
2209 if (moduleCachePath.empty())
2215 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty &&
2216 (builtIn || lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild))
2218 VDebugLog(
"No need to recheck %s.", cacheDescription.c_str());
2224 VDebugLog(
"Checking if %s is up-to-date…", cacheDescription.c_str());
2226 bool isCacheUpToDate =
true;
2228 if (isModuleCacheInitialized && isModuleCacheableDataDirty)
2229 isCacheUpToDate =
false;
2231 isModuleCacheInitialized =
true;
2232 isModuleCacheableDataDirty =
false;
2235 string dir, file, ext;
2237 string indexFileName = file +
"." + ext;
2244 if (shouldUseExistingCache)
2245 throw VuoException(
"Trying to use the existing cache, but the cache directory doesn't exist.",
false);
2248 isCacheUpToDate =
false;
2252 if (! indexFileExists)
2254 if (shouldUseExistingCache)
2255 throw VuoException(
"Trying to use the existing cache, but the cache index doesn't exist.",
false);
2258 isCacheUpToDate =
false;
2265 fileForLocking = moduleCacheFileForLocking[indexPath];
2266 if (! fileForLocking)
2269 moduleCacheFileForLocking[indexPath] = fileForLocking;
2273 VDebugLog(
"\tWarning: Couldn't lock for reading.");
2278 if (currentModuleCacheDylib.empty())
2281 if (shouldUseExistingCache && currentModuleCacheDylib.empty())
2282 throw VuoException(
"Trying to use the existing cache, but the cache dylib doesn't exist.",
false);
2286 if (isCacheUpToDate)
2287 isCacheUpToDate = lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild;
2291 if (isCacheUpToDate)
2296 if (shouldUseExistingCache)
2297 throw VuoException(
"Trying to use the existing cache, but the cache doesn't contain readable data.",
false);
2299 isCacheUpToDate =
false;
2305 const char separator =
'\n';
2306 if (isCacheUpToDate || shouldUseExistingCache)
2309 string index = indexFile.getContentsAsString();
2312 moduleCacheContents.clear();
2313 moduleCacheContents.insert(actualIndex.begin(), actualIndex.end());
2315 if (shouldUseExistingCache)
2317 isModuleCacheAvailable =
true;
2324 if (isCacheUpToDate)
2326 if (moduleCacheContents.size() != cacheableModulesAndDependencies.size())
2327 isCacheUpToDate =
false;
2330 set<string> contentsInBoth;
2331 std::set_intersection(moduleCacheContents.begin(), moduleCacheContents.end(),
2332 cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end(),
2333 std::inserter(contentsInBoth, contentsInBoth.begin()));
2335 if (contentsInBoth.size() != cacheableModulesAndDependencies.size())
2336 isCacheUpToDate =
false;
2342 if (isCacheUpToDate)
2346 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
2348 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2350 if (! j->second->isOlderThan(cacheLastModified))
2352 isCacheUpToDate =
false;
2361 if (isCacheUpToDate)
2365 isModuleCacheAvailable =
true;
2376 gettimeofday(&t, NULL);
2377 lastModuleCacheRebuild = t.tv_sec;
2380 dispatch_async(moduleCacheBuildingQueue, ^{
2381 VDebugLog(
"Rebuilding %s…", cacheDescription.c_str());
2383 set<Module *> modulesToLink;
2384 set<string> librariesToLink;
2385 set<string> frameworksToLink;
2387 compiler->getLinkerInputs(cacheableModulesAndDependencies, Optimization_SmallBinary, modulesToLink, librariesToLink, frameworksToLink);
2389 librariesToLink.insert(dylibsNeededToLinkToCaches.begin(), dylibsNeededToLinkToCaches.end());
2390 frameworksToLink.insert(frameworksNeededToLinkToCaches.begin(), frameworksNeededToLinkToCaches.end());
2393 bool gotLockForWriting =
false;
2398 if (! gotLockForWriting)
2399 throw VuoException(
"The cache file is being used by another process. "
2400 "If any composition windows are open from previous Vuo sessions, quit them. "
2401 "If any processes whose names start with \"VuoComposition\" or one of your composition file names appear in Activity Monitor, force-quit them.",
2405 string dir, file, ext;
2408 compiler->link(tmpPath, modulesToLink, librariesToLink, frameworksToLink,
true,
"",
false);
2415 getVuoFrameworkPath() +
"/Helpers/install_name_tool",
2417 currentModuleCacheDylib,
2418 currentModuleCacheDylib,
2424 if (vuoFrameworkInProgressPath.empty())
2425 adHocCodeSign(currentModuleCacheDylib);
2428 vector<string> expectedContents(cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end());
2437 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2439 dispatch_sync(environmentQueue, ^{
2440 moduleCacheContents = cacheableModulesAndDependencies;
2441 isModuleCacheAvailable =
true;
2447 if (gotLockForWriting)
2449 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2451 VUserLog(
"Warning: Couldn't rebuild %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2459 VUserLog(
"Warning: Couldn't use %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2466 void VuoCompiler::Environment::waitForModuleCachesToBuild(
void)
2468 dispatch_sync(moduleCacheBuildingQueue, ^{});
2480 bool VuoCompiler::Environment::findInModuleCache(
const string &moduleOrDependency,
string &cachePath)
2482 if (isModuleCacheAvailable && moduleCacheContents.find(moduleOrDependency) != moduleCacheContents.end())
2484 cachePath = currentModuleCacheDylib;
2494 string VuoCompiler::Environment::getCurrentModuleCacheDylib(
void)
2496 return currentModuleCacheDylib;
2503 unsigned long VuoCompiler::Environment::getLastModuleCacheRebuild(
void)
2505 return lastModuleCacheRebuild;
2514 void VuoCompiler::Environment::modulesChanged(
void)
2516 isModuleCacheableDataDirty =
true;
2517 isModuleCacheAvailable =
false;
2523 bool VuoCompiler::Environment::isBuiltInOriginal()
2525 return builtIn && ! generated;
2531 bool VuoCompiler::Environment::isBuiltIn()
2539 bool VuoCompiler::Environment::isGenerated()
2547 string VuoCompiler::Environment::getName()
2549 if (isBuiltInOriginal())
2551 else if (
this == sharedEnvironments[target][0][1])
2552 return "builtin (generated)";
2553 else if (
this == sharedEnvironments[target][1][0])
2555 else if (
this == sharedEnvironments[target][1][1])
2556 return "system (generated)";
2557 else if (
this == sharedEnvironments[target][2][0])
2559 else if (
this == sharedEnvironments[target][2][1])
2560 return "user (generated)";
2561 return "composition-local";
2567 void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *))
2569 dispatch_sync(environmentQueue, ^{
2570 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2571 doForEnvironment((*i)[0]);
2579 void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *,
bool *,
string),
bool *result,
string arg)
2581 dispatch_sync(environmentQueue, ^{
2582 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2583 doForEnvironment((*i)[0], result, arg);
2591 void VuoCompiler::applyToAllEnvironments(
void (^doForEnvironment)(Environment *environment))
2593 dispatch_sync(environmentQueue, ^{
2594 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2595 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j) {
2596 doForEnvironment(*j);
2619 this->target = target = getProcessTarget();
2620 VDebugLog(
"%p target=%s (from current process)",
this, this->target.c_str());
2624 this->target = target;
2625 VDebugLog(
"%p target=%s",
this, this->target.c_str());
2632 shouldLoadAllModules =
true;
2633 hasLoadedAllModules =
false;
2634 modulesToLoadQueue = dispatch_queue_create(
"org.vuo.compiler.modules", NULL);
2635 moduleSourceCompilersExist = dispatch_group_create();
2636 moduleCacheBuilding = dispatch_group_create();
2637 dependencyGraph = NULL;
2638 compositionDependencyGraph = NULL;
2640 _shouldShowSplashWindow =
false;
2642 delegateQueue = dispatch_queue_create(
"org.vuo.compiler.delegate", NULL);
2644 string vuoFrameworkPath = getVuoFrameworkPath();
2645 if (! vuoFrameworkPath.empty())
2646 clangPath = vuoFrameworkPath +
"/Helpers/clang";
2648 clangPath = LLVM_ROOT
"/bin/clang";
2650 dispatch_sync(environmentQueue, ^{
2651 allCompilers.insert(
this);
2653 if (sharedEnvironments[target].empty())
2655 sharedEnvironments[target] = vector< vector<Environment *> >(3, vector<Environment *>(2, NULL));
2656 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2657 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2658 *j =
new Environment(this->target, i == sharedEnvironments[target].begin(), j != i->begin());
2660 vector<string> builtInModuleSearchPaths = Environment::getBuiltInModuleSearchPaths();
2661 for (vector<string>::iterator i = builtInModuleSearchPaths.begin(); i != builtInModuleSearchPaths.end(); ++i)
2662 sharedEnvironments[target][0][0]->addModuleSearchPath(*i,
false);
2664 vector<string> builtInHeaderSearchPaths = Environment::getBuiltInHeaderSearchPaths();
2665 for (vector<string>::iterator i = builtInHeaderSearchPaths.begin(); i != builtInHeaderSearchPaths.end(); ++i)
2666 sharedEnvironments[target][0][0]->addHeaderSearchPath(*i);
2668 vector<string> builtInLibrarySearchPaths = Environment::getBuiltInLibrarySearchPaths();
2669 for (vector<string>::iterator i = builtInLibrarySearchPaths.begin(); i != builtInLibrarySearchPaths.end(); ++i)
2670 sharedEnvironments[target][0][0]->addLibrarySearchPath(*i);
2672 vector<string> builtInFrameworkSearchPaths = Environment::getBuiltInFrameworkSearchPaths();
2673 for (vector<string>::iterator i = builtInFrameworkSearchPaths.begin(); i != builtInFrameworkSearchPaths.end(); ++i)
2674 sharedEnvironments[target][0][0]->addFrameworkSearchPath(*i);
2687 string vuoFrameworkPath = getVuoFrameworkPath();
2688 if (! vuoFrameworkPath.empty())
2690 vector<string> moduleCachePaths(3);
2691 moduleCachePaths[0] = vuoFrameworkPath +
"/Modules/Builtin";
2695 for (
size_t i = 0; i < moduleCachePaths.size(); ++i)
2697 string moduleCachePath = moduleCachePaths[i];
2699 sharedEnvironments[target][i][0]->setModuleCachePath(moduleCachePath);
2700 sharedEnvironments[target][i][0]->addModuleSearchPath(moduleCachePath +
"/Modules",
false);
2702 sharedEnvironments[target][i][1]->setModuleCachePath(moduleCachePath);
2720 dispatch_sync(environmentQueue, ^{
2721 allCompilers.erase(
this);
2724 dispatch_group_wait(moduleCacheBuilding, DISPATCH_TIME_FOREVER);
2725 dispatch_release(moduleCacheBuilding);
2727 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
2728 (*i)[0]->removeCompilerToNotify(
this);
2730 dispatch_sync(delegateQueue, ^{});
2732 dispatch_release(modulesToLoadQueue);
2733 dispatch_release(delegateQueue);
2735 delete dependencyGraph;
2736 delete compositionDependencyGraph;
2742 void VuoCompiler::reset(
void)
2744 dispatch_group_wait(moduleSourceCompilersExistGlobally, DISPATCH_TIME_FOREVER);
2746 dispatch_sync(environmentQueue, ^{
2747 for (
auto e : sharedEnvironments)
2748 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2750 (*i)[0]->stopWatchingModuleSearchPaths();
2751 dispatch_sync((*i)[0]->moduleSearchPathContentsChangedQueue, ^{});
2754 for (map<
string, vector<Environment *> >::iterator i = environmentsForCompositionFamily.begin(); i != environmentsForCompositionFamily.end(); ++i)
2756 (i->second)[0]->stopWatchingModuleSearchPaths();
2757 dispatch_sync((i->second)[0]->moduleSearchPathContentsChangedQueue, ^{});
2760 for (
auto e : sharedEnvironments)
2761 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2762 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2765 for (map<
string, vector<Environment *> >::iterator i = environmentsForCompositionFamily.begin(); i != environmentsForCompositionFamily.end(); ++i)
2766 for (vector<Environment *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2769 allCompilers.clear();
2770 sharedEnvironments.clear();
2771 environmentsForCompositionFamily.clear();
2782 dispatch_async(delegateQueue, ^{
2783 this->delegate = delegate;
2798 string compositionModulesDir;
2799 string compositionBaseDir;
2800 lastCompositionIsSubcomposition =
false;
2801 if (! compositionPath.empty())
2809 string compositionDir;
2812 lastCompositionIsSubcomposition = (compositionDir == compositionModulesDir);
2817 dispatch_sync(environmentQueue, ^{
2818 if (! environments.empty() && compositionBaseDir == lastCompositionBaseDir) {
2821 lastCompositionBaseDir = compositionBaseDir;
2825 Environment *oldCompositionFamilyInstalledEnvironment =
nullptr;
2826 vector<Environment *> compositionEnvironments;
2827 if (! environments.empty())
2829 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2830 (*i)[0]->removeCompilerToNotify(this);
2833 if (environments.size() >= 5) {
2834 oldCompositionFamilyInstalledEnvironment = environments[3][0];
2837 compositionEnvironments = environments.back();
2839 environments.clear();
2846 bool isCompositionInSharedEnvironment =
false;
2847 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2849 environments.push_back(*i);
2851 vector<string> moduleSearchPaths = (*i)[0]->getModuleSearchPaths();
2852 for (vector<string>::iterator j = moduleSearchPaths.begin(); j != moduleSearchPaths.end(); ++j)
2854 string moduleSearchPath = *j;
2855 VuoFileUtilities::canonicalizePath(moduleSearchPath);
2856 if (moduleSearchPath == compositionModulesDir)
2858 isCompositionInSharedEnvironment = true;
2863 if (isCompositionInSharedEnvironment) {
2870 Environment *newCompositionFamilyInstalledEnvironment =
nullptr;
2871 if (! isCompositionInSharedEnvironment && ! compositionPath.empty())
2873 vector<Environment *> compositionFamilyEnvironments = environmentsForCompositionFamily[compositionBaseDir];
2874 if (compositionFamilyEnvironments.empty())
2876 compositionFamilyEnvironments = vector<Environment *>(2, NULL);
2877 compositionFamilyEnvironments[0] = new Environment(this->target, false, false);
2878 compositionFamilyEnvironments[1] = new Environment(this->target, false, true);
2879 environmentsForCompositionFamily[compositionBaseDir] = compositionFamilyEnvironments;
2883 compositionFamilyEnvironments[0]->addModuleSearchPath(compositionModulesDir);
2887 string moduleCachePath = getCachePathForComposition(compositionBaseDir);
2889 compositionFamilyEnvironments[0]->setModuleCachePath(moduleCachePath);
2890 compositionFamilyEnvironments[0]->addModuleSearchPath(moduleCachePath +
"/Modules", false);
2892 compositionFamilyEnvironments[1]->setModuleCachePath(moduleCachePath);
2894 environments.push_back(compositionFamilyEnvironments);
2896 newCompositionFamilyInstalledEnvironment = compositionFamilyEnvironments[0];
2901 if (compositionEnvironments.empty())
2903 compositionEnvironments = vector<Environment *>(2, NULL);
2904 compositionEnvironments[0] = new Environment(this->target, false, false);
2905 compositionEnvironments[1] = new Environment(this->target, false, true);
2907 environments.push_back(compositionEnvironments);
2909 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2910 (*i)[0]->addCompilerToNotify(this);
2913 delete dependencyGraph;
2914 delete compositionDependencyGraph;
2915 dependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getDependencyGraph(); });
2916 compositionDependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getCompositionDependencyGraph(); });
2921 if (oldCompositionFamilyInstalledEnvironment != newCompositionFamilyInstalledEnvironment)
2923 auto getModules = [] (Environment *env)
2925 map<string, VuoCompilerModule *> modules;
2928 for (
auto i : env->getNodeClasses()) {
2931 for (
auto i : env->getTypes()) {
2934 for (
auto i : env->getLibraryModules()) {
2941 map<string, VuoCompilerModule *> modulesAdded = getModules(newCompositionFamilyInstalledEnvironment);
2942 map<string, VuoCompilerModule *> modulesRemoved = getModules(oldCompositionFamilyInstalledEnvironment);
2944 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified;
2945 for (map<string, VuoCompilerModule *>::iterator
add = modulesAdded.begin();
add != modulesAdded.end(); )
2947 map<string, VuoCompilerModule *>::iterator rem = modulesRemoved.find(
add->first);
2948 if (rem != modulesRemoved.end())
2950 modulesModified[
add->first] = make_pair(rem->second,
add->second);
2951 modulesAdded.erase(
add++);
2952 modulesRemoved.erase(rem);
2960 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty()) )
2963 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues);
2964 delegateData->retain();
2966 Environment *scopeEnvironment = newCompositionFamilyInstalledEnvironment;
2967 if (! scopeEnvironment) {
2968 scopeEnvironment = compositionEnvironments.at(0);
2971 loadedModules(modulesAdded, modulesModified, modulesRemoved, issues, delegateData, scopeEnvironment);
2985 if (!graphForEnvironment)
2990 for (vector< vector<Environment *> >::const_iterator i = environments.begin(); i != environments.end(); ++i)
2994 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(i->at(1)));
2998 for (vector< vector<Environment *> >::const_iterator ii = environments.begin(); ii != i; ++ii)
3000 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(ii->at(0)));
3001 network->
addEdge(graphForEnvironment(i->at(1)), graphForEnvironment(ii->at(0)));
3028 void VuoCompiler::loadModulesIfNeeded(
const set<string> &moduleKeys)
3030 __block
bool willLoadAllModules =
false;
3031 if (moduleKeys.empty())
3033 dispatch_sync(modulesToLoadQueue, ^{
3034 if (shouldLoadAllModules && ! hasLoadedAllModules) {
3035 willLoadAllModules =
true;
3036 hasLoadedAllModules =
true;
3041 if (! willLoadAllModules && moduleKeys.empty())
3046 dispatch_group_enter(moduleSourceCompilersExist);
3047 __block set<dispatch_group_t> sourcesLoading;
3048 dispatch_sync(environmentQueue, ^{
3049 sourcesLoading = loadModulesAndSources(moduleKeys, set<string>(), set<string>(),
3050 moduleKeys, set<string>(), set<string>(),
3051 willLoadAllModules,
false,
nullptr,
nullptr,
nullptr,
"");
3057 for (set<dispatch_group_t>::iterator i = sourcesLoading.begin(); i != sourcesLoading.end(); ++i)
3059 dispatch_group_wait(*i, DISPATCH_TIME_FOREVER);
3060 dispatch_release(*i);
3062 dispatch_group_leave(moduleSourceCompilersExist);
3073 set<dispatch_group_t> VuoCompiler::loadModulesAndSources(
const set<string> &modulesAddedKeys,
const set<string> &modulesModifiedKeys,
const set<string> &modulesRemovedKeys,
3074 const set<string> &sourcesAddedKeys,
const set<string> &sourcesModifiedKeys,
const set<string> &sourcesRemovedKeys,
3075 bool willLoadAllModules,
bool shouldRecompileSourcesIfUnchanged,
3076 Environment *currentEnvironment,
VuoCompilerIssues *issuesForCurrentEnvironment,
3077 std::function<
void(
void)> moduleLoadedCallback,
const string &moduleAddedOrModifiedSourceCode)
3089 map<Environment *, set<string> > modulesAdded;
3090 map<Environment *, set<string> > modulesModified;
3091 map<Environment *, set<string> > modulesRemoved;
3092 map<Environment *, set<string> > sourcesAdded;
3093 map<Environment *, set<string> > sourcesModified;
3094 map<Environment *, set<string> > sourcesRemoved;
3095 map<Environment *, set<string> > potentialSpecializedModules;
3097 if (currentEnvironment)
3099 modulesAdded[currentEnvironment] = modulesAddedKeys;
3100 modulesModified[currentEnvironment] = modulesModifiedKeys;
3101 modulesRemoved[currentEnvironment] = modulesRemovedKeys;
3102 sourcesAdded[currentEnvironment] = sourcesAddedKeys;
3103 sourcesModified[currentEnvironment] = sourcesModifiedKeys;
3104 sourcesRemoved[currentEnvironment] = sourcesRemovedKeys;
3108 Environment *genEnv =
nullptr;
3109 if (! willLoadAllModules)
3115 int scope = environments.size() - (lastCompositionIsSubcomposition ? 2 : 1);
3116 genEnv = environments.at(scope).at(1);
3117 potentialSpecializedModules[genEnv] = modulesAddedKeys;
3120 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3122 Environment *env = (*i).at(0);
3124 ModuleInfoIterator modulesAddedIter = (willLoadAllModules ? env->listAllModules() : env->listModules(modulesAddedKeys));
3125 ModuleInfoIterator sourcesAddedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesAddedKeys));
3126 ModuleInfoIterator sourcesModifiedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesModifiedKeys));
3128 ModuleInfo *moduleInfo;
3129 while ((moduleInfo = modulesAddedIter.next()))
3131 string moduleKey = moduleInfo->getModuleKey();
3133 modulesAdded[env].insert(moduleKey);
3135 if (! willLoadAllModules)
3137 auto foundIter = potentialSpecializedModules[genEnv].find(moduleKey);
3138 if (foundIter != potentialSpecializedModules[genEnv].end())
3139 potentialSpecializedModules[genEnv].erase(foundIter);
3145 auto isCompiledModuleAtSameSearchPath = [&env] (ModuleInfo *sourceInfo)
3147 ModuleInfo *compiledModuleInfo = env->listModule(sourceInfo->getModuleKey());
3148 return (compiledModuleInfo && compiledModuleInfo->getSearchPath() == sourceInfo->getSearchPath());
3151 while ((moduleInfo = sourcesAddedIter.next()))
3153 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3156 sourcesAdded[env].insert( moduleInfo->getModuleKey() );
3159 while ((moduleInfo = sourcesModifiedIter.next()))
3161 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3164 sourcesModified[env].insert( moduleInfo->getModuleKey() );
3169 map<Environment *, VuoCompilerIssues *> issues;
3170 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3172 Environment *env = (*i).at(0);
3173 issues[env] = (env == currentEnvironment && issuesForCurrentEnvironment ? issuesForCurrentEnvironment :
new VuoCompilerIssues());
3178 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3180 Environment *env = (*i).at(0);
3185 set<VuoDirectedAcyclicGraph::Vertex *> circularDependencies = env->getCompositionDependencyGraph()->getCycleVertices();
3187 set<string> sourcesAddedModified;
3188 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3189 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3191 for (set<string>::iterator j = sourcesAddedModified.begin(); j != sourcesAddedModified.end(); ++j)
3193 string moduleKey = *j;
3196 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator k = circularDependencies.begin(); k != circularDependencies.end(); ++k)
3198 DependencyGraphVertex *vertex =
static_cast<DependencyGraphVertex *
>(*k);
3199 if (vertex->getDependency() == moduleKey)
3208 sourcesAdded[env].erase(moduleKey);
3209 sourcesModified[env].erase(moduleKey);
3212 "Subcomposition contains itself",
3213 "%moduleKey contains an instance of itself, "
3214 "or contains another subcomposition that contains an instance of %moduleKey.");
3215 issue.setModuleKey(moduleKey);
3217 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3219 issue.setFilePath(sourceInfo->getFile()->path());
3221 issues[env]->append(issue);
3228 for (
const vector<Environment *> &envs : environments)
3230 Environment *env = envs.at(0);
3232 set<string> sourcesAddedModified;
3233 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3234 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3236 for (
const string &moduleKey : sourcesAddedModified)
3239 int pathLength = env->getCompositionDependencyGraph()->getLongestDownstreamPath(vertex);
3241 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3242 sourceInfo->setLongestDownstreamPath(pathLength);
3250 map<Environment *, set<string> > modulesDepOnModulesModified;
3251 map<Environment *, set<string> > sourcesDepOnModulesModified;
3252 map<Environment *, set<string> > modulesDepOnModulesRemoved;
3253 map<Environment *, set<string> > sourcesDepOnModulesRemoved;
3256 __block map<Environment *, set<string> > modulesDepOnModulesModified_otherCompiler;
3257 __block map<Environment *, set<string> > sourcesDepOnModulesModified_otherCompiler;
3258 __block map<Environment *, set<string> > modulesDepOnModulesRemoved_otherCompiler;
3259 __block map<Environment *, set<string> > sourcesDepOnModulesRemoved_otherCompiler;
3261 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3263 searchDependencyGraphs.push_back(compiler->dependencyGraph);
3265 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getDependencyGraph() :
nullptr);
3267 findDependentModulesAndSources(modulesModified, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3268 modulesDepOnModulesModified, modulesDepOnModulesModified_otherCompiler,
3269 sourcesDepOnModulesModified, sourcesDepOnModulesModified_otherCompiler);
3271 findDependentModulesAndSources(modulesRemoved, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3272 modulesDepOnModulesRemoved, modulesDepOnModulesRemoved_otherCompiler,
3273 sourcesDepOnModulesRemoved, sourcesDepOnModulesRemoved_otherCompiler);
3275 set<Environment *> otherEnvironments;
3276 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesModified_otherCompiler.begin(); i != modulesDepOnModulesModified_otherCompiler.end(); ++i)
3277 otherEnvironments.insert(i->first);
3278 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesModified_otherCompiler.begin(); i != sourcesDepOnModulesModified_otherCompiler.end(); ++i)
3279 otherEnvironments.insert(i->first);
3280 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesRemoved_otherCompiler.begin(); i != modulesDepOnModulesRemoved_otherCompiler.end(); ++i)
3281 otherEnvironments.insert(i->first);
3282 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesRemoved_otherCompiler.begin(); i != sourcesDepOnModulesRemoved_otherCompiler.end(); ++i)
3283 otherEnvironments.insert(i->first);
3285 for (Environment *env : otherEnvironments)
3289 for (
const vector<Environment *> &ee : c->environments)
3290 for (Environment *e : ee)
3294 goto foundOtherCompiler;
3298 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3299 dispatch_sync(environmentQueue, ^{
3300 otherCompiler->loadModulesAndSources(set<string>(), modulesDepOnModulesModified_otherCompiler[env], modulesDepOnModulesRemoved_otherCompiler[env],
3301 set<string>(), sourcesDepOnModulesModified_otherCompiler[env], sourcesDepOnModulesRemoved_otherCompiler[env],
3302 false,
true, env,
nullptr,
nullptr,
"");
3312 map<Environment *, set<VuoCompilerModule *> > actualModulesRemoved;
3313 for (
const vector<Environment *> &envs : environments)
3315 for (Environment *env : envs)
3317 set<string> modulesToUnload;
3318 modulesToUnload.insert(modulesRemoved[env].begin(), modulesRemoved[env].end());
3319 modulesToUnload.insert(modulesModified[env].begin(), modulesModified[env].end());
3320 modulesToUnload.insert(modulesDepOnModulesRemoved[env].begin(), modulesDepOnModulesRemoved[env].end());
3321 modulesToUnload.insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3323 actualModulesRemoved[env] = env->unloadCompiledModules(modulesToUnload);
3325 if (!env->isBuiltInOriginal() && !actualModulesRemoved[env].empty())
3327 set<string> actualModulesRemovedKeys;
3328 for (
auto m : actualModulesRemoved[env])
3329 actualModulesRemovedKeys.insert(m->getPseudoBase()->getModuleKey());
3342 map<Environment *, set<string> > modulesToLoad;
3343 map<Environment *, map<string, string> > modulesToLoadSourceCode;
3344 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3346 Environment *env = (*i).at(0);
3348 if (! modulesAdded[env].empty())
3349 modulesToLoad[env].insert(modulesAdded[env].begin(), modulesAdded[env].end());
3350 if (! modulesModified[env].empty())
3351 modulesToLoad[env].insert(modulesModified[env].begin(), modulesModified[env].end());
3352 if (! modulesDepOnModulesModified[env].empty())
3353 modulesToLoad[env].insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3355 if (env == currentEnvironment && moduleLoadedCallback)
3357 if (modulesAdded[env].size() == 1)
3358 modulesToLoadSourceCode[env][*modulesAdded[env].begin()] = moduleAddedOrModifiedSourceCode;
3359 else if (modulesModified[env].size() == 1)
3360 modulesToLoadSourceCode[env][*modulesModified[env].begin()] = moduleAddedOrModifiedSourceCode;
3364 map<Environment *, set<VuoCompilerModule *> > actualModulesAdded;
3365 while (! modulesToLoad.empty())
3367 set<string> dependenciesToLoad;
3368 map<Environment *, set<string> > potentialSpecializedDependencies;
3369 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3371 Environment *env = (*i).at(0);
3372 Environment *genEnv = (*i).at(1);
3374 set<VuoCompilerModule *> actualModulesLoaded = env->loadCompiledModules(modulesToLoad[env], modulesToLoadSourceCode[env]);
3376 actualModulesAdded[env].insert(actualModulesLoaded.begin(), actualModulesLoaded.end());
3377 modulesToLoad.erase(env);
3379 for (set<VuoCompilerModule *>::iterator j = actualModulesLoaded.begin(); j != actualModulesLoaded.end(); ++j)
3381 set<string> dependencies = (*j)->getDependencies();
3382 dependenciesToLoad.insert(dependencies.begin(), dependencies.end());
3383 potentialSpecializedDependencies[genEnv].insert(dependencies.begin(), dependencies.end());
3386 if (!env->isBuiltInOriginal() && !actualModulesLoaded.empty())
3388 map<string, string> actualFilesAndHashesLoaded;
3389 for (
auto module : actualModulesLoaded)
3397 if (cnc && !cnc->getSourcePath().empty())
3400 if (!cnc->getSourceCode().empty())
3415 actualFilesAndHashesLoaded[path] = hash;
3418 for (pair<string, string> item : actualFilesAndHashesLoaded)
3419 VUserLog(
"Loaded into %s environment: [%8.8s] %s", env->getName().c_str(), item.second.c_str(), item.first.c_str());
3423 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3425 Environment *env = (*i).at(0);
3427 ModuleInfoIterator dependenciesInEnv = env->listModules(dependenciesToLoad);
3428 ModuleInfo *moduleInfo;
3429 while ((moduleInfo = dependenciesInEnv.next()))
3431 modulesToLoad[env].insert( moduleInfo->getModuleKey() );
3433 for (map<Environment *, set<string> >::iterator j = potentialSpecializedDependencies.begin(); j != potentialSpecializedDependencies.end(); ++j)
3435 auto foundIter = j->second.find( moduleInfo->getModuleKey() );
3436 if (foundIter != j->second.end())
3437 j->second.erase(foundIter);
3442 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3444 Environment *genEnv = (*i).at(1);
3445 potentialSpecializedModules[genEnv].insert(potentialSpecializedDependencies[genEnv].begin(), potentialSpecializedDependencies[genEnv].end());
3452 set<dispatch_group_t> specializedModulesLoading;
3453 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3455 Environment *genEnv = (*i).at(1);
3456 set<dispatch_group_t> s = genEnv->loadSpecializedModules(potentialSpecializedModules[genEnv],
this,
llvmQueue);
3457 specializedModulesLoading.insert(s.begin(), s.end());
3462 if (moduleLoadedCallback)
3463 moduleLoadedCallback();
3467 map<Environment *, set< pair<VuoCompilerModule *, VuoCompilerModule *> > > actualModulesModified;
3468 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3470 Environment *env = (*i).at(0);
3472 for (set<VuoCompilerModule *>::iterator
add = actualModulesAdded[env].begin();
add != actualModulesAdded[env].end(); )
3474 set<VuoCompilerModule *>::iterator rem;
3475 for (rem = actualModulesRemoved[env].begin(); rem != actualModulesRemoved[env].end(); ++rem)
3476 if ((*rem)->getPseudoBase()->getModuleKey() == (*add)->getPseudoBase()->getModuleKey())
3479 if (rem != actualModulesRemoved[env].end())
3481 actualModulesModified[env].insert( make_pair(*rem, *
add) );
3482 actualModulesRemoved[env].erase(rem);
3483 actualModulesAdded[env].erase(
add++);
3492 bool wereModulesAddedOrModified =
false;
3493 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3495 Environment *env = (*i).at(0);
3496 if (! (actualModulesAdded[env].empty() && actualModulesModified[env].empty()) )
3498 wereModulesAddedOrModified =
true;
3503 if (wereModulesAddedOrModified)
3505 map<string, VuoCompilerType *> inheritedTypes;
3506 for (
const vector<Environment *> &envs : environments)
3508 for (Environment *env : envs)
3510 env->reifyPortTypes(inheritedTypes);
3511 map<string, VuoCompilerType *> envTypes = env->getTypes();
3512 inheritedTypes.insert(envTypes.begin(), envTypes.end());
3521 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3523 Environment *env = (*i).at(0);
3525 set<string> sourcesToUnload;
3526 sourcesToUnload.insert(sourcesRemoved[env].begin(), sourcesRemoved[env].end());
3527 sourcesToUnload.insert(sourcesDepOnModulesRemoved[env].begin(), sourcesDepOnModulesRemoved[env].end());
3528 if (! sourcesToUnload.empty())
3530 string moduleSearchPath = env->getModuleSearchPaths().front();
3532 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3535 dispatch_sync(environmentQueue, ^{
3536 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), sourcesToUnload,
3537 set<string>(), set<string>(), set<string>(),
3538 false,
false, env,
nullptr,
nullptr,
"");
3541 delete otherCompiler;
3545 if (!env->isBuiltInOriginal() && !sourcesToUnload.empty())
3548 env->deleteModulesCompiledFromSourceCode(sourcesToUnload);
3556 map<Environment *, set<string> > sourcesDepOnModulesAdded;
3558 map<Environment *, set<string> > modulesDepOnModulesAdded;
3559 __block map<Environment *, set<string> > modulesDepOnModulesAdded_otherCompiler;
3560 __block map<Environment *, set<string> > sourcesDepOnModulesAdded_otherCompiler;
3562 map<Environment *, set<string> > actualModuleKeysAdded;
3563 for (
const vector<Environment *> &envs : environments)
3565 Environment *env = envs.at(0);
3570 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3571 searchDependencyGraphs.push_back(compositionDependencyGraph);
3572 for (map<
string, vector<Environment *> >::iterator ii = environmentsForCompositionFamily.begin(); ii != environmentsForCompositionFamily.end(); ++ii)
3574 vector< vector<Environment *> > otherEnvs = sharedEnvironments[target];
3575 otherEnvs.push_back(ii->second);
3577 searchDependencyGraphs.push_back(other);
3580 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getCompositionDependencyGraph() :
nullptr);
3582 findDependentModulesAndSources(actualModuleKeysAdded, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3583 modulesDepOnModulesAdded, modulesDepOnModulesAdded_otherCompiler,
3584 sourcesDepOnModulesAdded, sourcesDepOnModulesAdded_otherCompiler);
3586 set<Environment *> otherEnvironments;
3587 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesAdded_otherCompiler.begin(); i != sourcesDepOnModulesAdded_otherCompiler.end(); ++i)
3588 otherEnvironments.insert(i->first);
3590 for (Environment *env : otherEnvironments)
3592 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3593 string moduleSearchPath = env->getModuleSearchPaths().front();
3596 dispatch_sync(environmentQueue, ^{
3597 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), set<string>(),
3598 sourcesDepOnModulesAdded_otherCompiler[env], set<string>(), set<string>(),
3599 false,
true, env,
nullptr,
nullptr,
"");
3602 delete otherCompiler;
3607 set<dispatch_group_t> sourcesLoading;
3608 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3610 Environment *env = (*i).at(0);
3612 set<string> sourcesToCompile;
3613 sourcesToCompile.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3614 sourcesToCompile.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3616 if (sourcesToCompile.size() == 0)
3619 set<dispatch_group_t> s = env->compileModulesFromSourceCode(sourcesToCompile, shouldRecompileSourcesIfUnchanged);
3620 sourcesLoading.insert(s.begin(), s.end());
3623 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3625 Environment *env = (*i).at(0);
3627 set<string> sourcesToCompile;
3628 sourcesToCompile.insert(sourcesDepOnModulesAdded[env].begin(), sourcesDepOnModulesAdded[env].end());
3629 sourcesToCompile.insert(sourcesDepOnModulesModified[env].begin(), sourcesDepOnModulesModified[env].end());
3631 if (sourcesToCompile.size() == 0)
3634 env->compileModulesFromSourceCode(sourcesToCompile,
true);
3639 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3641 Environment *env = (*i).at(0);
3642 env->notifyCompilers(actualModulesAdded[env], actualModulesModified[env], actualModulesRemoved[env], issues[env]);
3649 for (
const dispatch_group_t &group : sourcesLoading)
3650 dispatch_retain(group);
3652 set<dispatch_group_t> loadingGroups;
3653 loadingGroups.insert(specializedModulesLoading.begin(), specializedModulesLoading.end());
3654 loadingGroups.insert(sourcesLoading.begin(), sourcesLoading.end());
3655 return loadingGroups;
3669 void VuoCompiler::findDependentModulesAndSources(map<Environment *, set<string> > &changedModules,
3670 const vector<VuoDirectedAcyclicNetwork *> &searchDependencyGraphs,
3672 map<Environment *, set<string> > &modulesDepOnChangedModules_this,
3673 map<Environment *, set<string> > &modulesDepOnChangedModules_other,
3674 map<Environment *, set<string> > &sourcesDepOnChangedModules_this,
3675 map<Environment *, set<string> > &sourcesDepOnChangedModules_other)
3677 for (
const vector<Environment *> &envs : environments)
3679 Environment *env = envs.at(0);
3681 for (
const string &module : changedModules[env])
3683 set<VuoDirectedAcyclicGraph::Vertex *> dependents;
3686 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices;
3687 if (currentEnvironmentDependencyGraph)
3693 moduleVertices.push_back(mv);
3696 moduleVertices = searchDependencyGraph->findVertex(module);
3700 DependencyGraphVertex *moduleVertex =
static_cast<DependencyGraphVertex *
>(moduleVertexRaw);
3701 if (moduleVertex->getEnvironment())
3703 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = searchDependencyGraph->getUpstreamVertices(moduleVertex);
3704 dependents.insert(upstream.begin(), upstream.end());
3709 set< pair<Environment *, string> > dependentsMap;
3712 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(dependentVertexRaw);
3713 Environment *dependentEnv = v->getEnvironment();
3717 string dependent = v->getDependency();
3719 dependentsMap.insert({dependentEnv, dependent});
3725 for (
auto i : envs.at(1)->getNodeClasses())
3729 dependentsMap.insert({envs.at(1), i.first});
3732 for (
auto i : dependentsMap)
3734 Environment *dependentEnv = i.first;
3735 string dependent = i.second;
3739 if (changedModules[dependentEnv].find(dependent) != changedModules[dependentEnv].end())
3742 ModuleInfo *foundSourceInfo = dependentEnv->listSourceFile(dependent);
3743 ModuleInfo *foundModuleInfo = dependentEnv->listModule(dependent);
3745 bool belongsToCurrentCompiler =
false;
3746 for (
const vector<Environment *> &envs2 : environments)
3748 if (find(envs2.begin(), envs2.end(), dependentEnv) != envs2.end())
3750 belongsToCurrentCompiler =
true;
3755 map<Environment *, set<string> > *whicheverDependents =
nullptr;
3756 ModuleInfo *moduleInfo =
nullptr;
3757 if (foundSourceInfo)
3759 moduleInfo = foundSourceInfo;
3760 whicheverDependents = (belongsToCurrentCompiler ? &sourcesDepOnChangedModules_this : &sourcesDepOnChangedModules_other);
3762 else if (foundModuleInfo)
3764 moduleInfo = foundModuleInfo;
3765 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3769 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3772 (*whicheverDependents)[dependentEnv].insert(dependent);
3774 moduleInfo->setAttempted(
false);
3783 void VuoCompiler::loadedModules(map<string, VuoCompilerModule *> modulesAdded,
3784 map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified,
3785 map<string, VuoCompilerModule *> modulesRemoved,
3786 VuoCompilerIssues *issues,
void *delegateDataV, Environment *currentEnvironment)
3798 auto findVersionsOfModule = [
this, currentEnvironment] (
const string &moduleKey)
3800 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions;
3801 for (
const vector<Environment *> &envs : environments)
3803 Environment *env = envs.at(0);
3805 if (module || env == currentEnvironment)
3806 moduleVersions.push_back( make_pair(env, module) );
3808 return moduleVersions;
3811 for (map<string, VuoCompilerModule *>::iterator i = modulesAdded.begin(); i != modulesAdded.end(); )
3813 string moduleKey = i->first;
3816 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3818 if (moduleVersions.size() > 1)
3820 modulesAdded.erase(i++);
3822 if (moduleVersions.back().second == moduleAdded)
3824 VuoCompilerModule *moduleSuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3825 modulesModified[moduleKey] = make_pair(moduleSuperseded, moduleAdded);
3832 for (map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); )
3834 string moduleKey = i->first;
3837 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3839 if (moduleVersions.size() > 1 && moduleVersions.back().second != moduleModified)
3840 modulesModified.erase(i++);
3845 for (map<string, VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); )
3847 string moduleKey = i->first;
3850 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3852 if (moduleVersions.size() > 1)
3854 modulesRemoved.erase(i++);
3856 if (moduleVersions.back().first == currentEnvironment)
3858 VuoCompilerModule *moduleUnsuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3859 modulesModified[moduleKey] = make_pair(moduleRemoved, moduleUnsuperseded);
3866 dispatch_async(delegateQueue, ^{
3867 VuoCompilerDelegate::LoadedModulesData *delegateData =
static_cast<VuoCompilerDelegate::LoadedModulesData *
>(delegateDataV);
3869 if (delegate && ! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()))
3871 delegate->enqueueData(delegateData);
3872 delegate->
loadedModules(modulesAdded, modulesModified, modulesRemoved, issues);
3876 delegateData->release();
3886 void VuoCompiler::loadNodeClassGeneratedAtRuntime(
VuoCompilerNodeClass *nodeClass, Environment *env)
3888 Module *module = nodeClass->
getModule();
3892 setTargetForModule(nodeClass->
getModule(), env->getTarget());
3896 dispatch_sync(environmentQueue, ^{
3897 env->replaceNodeClass(nodeClass);
3900 __block map<string, VuoCompilerType *> inheritedTypes;
3901 void (^envReifyPortTypes)(Environment *) = ^
void (Environment *env) {
3902 env->reifyPortTypes(inheritedTypes);
3903 map<string, VuoCompilerType *> currentTypes = env->getTypes();
3904 inheritedTypes.insert(currentTypes.begin(), currentTypes.end());
3906 applyToAllEnvironments(envReifyPortTypes);
3915 reifyGenericPortTypes(node->getBase());
3923 void VuoCompiler::reifyGenericPortTypes(
VuoNode *node)
3933 vector<VuoPort *> ports;
3934 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
3935 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
3937 for (vector<VuoPort *>::iterator j = ports.begin(); j != ports.end(); ++j)
3984 vector<string> allIncludePaths = includePaths;
3985 string preprocessedInputPath = inputPath;
3987 string tmpPreprocessedInputDir;
3988 string dir, file, ext;
3993 string preprocessedInputContents = inputContents;
3995 if (inputContents != preprocessedInputContents)
3998 allIncludePaths.push_back(dir.empty() ?
"." : dir);
4000 preprocessedInputPath = tmpPreprocessedInputDir +
"/" + file +
"." + ext;
4005 else if (ext ==
"fs")
4011 auto getType = [
this] (
const string &moduleKey) {
return this->
getType(moduleKey); };
4016 setTargetForModule(module, target);
4017 writeModuleToBitcode(module, outputPath);
4027 vector<string> extraArgs;
4028 for (vector<string>::iterator i = allIncludePaths.begin(); i != allIncludePaths.end(); ++i)
4030 extraArgs.push_back(
"-I");
4031 extraArgs.push_back(*i);
4037 string buildTimeMacOSSDKFolder = MACOS_SDK_ROOT;
4040 extraArgs.push_back(
"-isysroot");
4041 extraArgs.push_back(buildTimeMacOSSDKFolder);
4045 __block vector<string> headerSearchPaths;
4046 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
4047 vector<string> result = env->getHeaderSearchPaths();
4048 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
4050 applyToInstalledEnvironments(envGetHeaderSearchPaths);
4053 __block Module *module;
4055 module = readModuleFromC(preprocessedInputPath, headerSearchPaths, extraArgs, issues);
4058 if (! tmpPreprocessedInputDir.empty())
4060 remove(tmpPreprocessedInputDir.c_str());
4069 if (! compilerModule)
4071 VUserLog(
"Error: Didn't recognize '%s' as a node class, type, or library.", inputPath.c_str());
4075 setTargetForModule(module, target);
4076 writeModuleToBitcode(module, outputPath);
4085 Module * VuoCompiler::compileCompositionToModule(
VuoCompilerComposition *composition,
const string &moduleKey,
bool isTopLevelComposition,
4088 composition->
check(issues);
4090 reifyGenericPortTypes(composition);
4093 isTopLevelComposition,
4095 if (telemetry ==
"console")
4098 __block Module *module =
nullptr;
4103 setTargetForModule(module, target);
4133 Module *module = compileCompositionToModule(composition, moduleKey, isTopLevelComposition, issues);
4138 writeModuleToBitcode(module, outputPath);
4157 VDebugLog(
"Compiling '%s' (%s)…", inputPath.c_str(), target.c_str());
4167 "",
"The composition file couldn't be read or was empty.");
4206 delete baseComposition;
4212 void VuoCompiler::compileSubcompositionString(
const string &compositionString,
const string &outputPath,
4213 std::function<
void(
void)> moduleLoadedCallback, Environment *environment,
4219 bool compilationSucceeded =
false;
4223 compilationSucceeded =
true;
4231 if (! compilationSucceeded)
4237 environment->moduleFileChanged(outputPath, compositionString, moduleLoadedCallback,
this, issues);
4256 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
false, rPath, shouldAdHocCodeSign);
4278 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
true,
"", shouldAdHocCodeSign);
4295 void VuoCompiler::linkCompositionToCreateExecutableOrDynamicLibrary(
string compiledCompositionPath,
string linkedCompositionPath,
4296 Optimization optimization,
bool isDylib,
string rPath,
bool shouldAdHocCodeSign)
4302 shouldLoadAllModules =
false;
4304 set<string> dependencies = getDependenciesForComposition(compiledCompositionPath);
4305 dependencies.insert(getRuntimeDependency());
4307 dependencies.insert(getRuntimeMainDependency());
4309 set<Module *> modules;
4310 set<string> libraries;
4311 set<string> frameworks;
4312 getLinkerInputs(dependencies, optimization, modules, libraries, frameworks);
4314 libraries.insert(compiledCompositionPath);
4316 link(linkedCompositionPath, modules, libraries, frameworks, isDylib, rPath, shouldAdHocCodeSign);
4339 bool shouldAdHocCodeSign =
false;
4341 shouldAdHocCodeSign =
true;
4347 set<string> allDependencies = getDependenciesForComposition(compiledCompositionPath);
4348 set<string> addedDependencies;
4349 std::set_difference(allDependencies.begin(), allDependencies.end(),
4350 carriedOverDependencies.begin(), carriedOverDependencies.end(),
4351 std::inserter(addedDependencies, addedDependencies.end()));
4357 set<string> carriedOverExternalLibraries = runningCompositionLibraries->
getExternalLibraries();
4362 string nonUnloadableResourcePath;
4363 string unloadableResourcePath;
4364 set<string> nonUnloadableDependencies;
4365 set<string> unloadableDependencies;
4366 map<string, set<string> > builtInCacheDependencies;
4367 map<string, set<string> > userCacheDependencies;
4368 set<string> builtInLibraries;
4369 set<string> userLibraries;
4370 set<string> addedExternalLibraries;
4371 set<string> addedFrameworks;
4372 set<string> allFrameworks;
4373 if (! addedDependencies.empty())
4377 set<string> builtInModuleAndLibraryDependencies;
4378 set<string> userModuleAndLibraryDependencies;
4379 set<Module *> builtInModules;
4380 set<Module *> userModules;
4383 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4384 builtInModules, userModules, builtInLibraries, userLibraries, addedExternalLibraries, addedFrameworks);
4386 allFrameworks.insert(carriedOverFrameworks.begin(), carriedOverFrameworks.end());
4387 allFrameworks.insert(addedFrameworks.begin(), addedFrameworks.end());
4389 string dir, linkedCompositionFile, ext;
4396 __block vector<string> currentCacheLibraries;
4397 applyToAllEnvironments(^
void (Environment *env) {
4398 currentCacheLibraries.push_back( env->getCurrentModuleCacheDylib() );
4401 for (
string cachePath : carriedOverUserCacheLibraries)
4403 for (
string currentCachePath : currentCacheLibraries)
4409 userCacheDependencies[currentCachePath].insert(dependenciesInCache.begin(), dependenciesInCache.end());
4411 auto cacheDependenciesIter = userCacheDependencies.find(cachePath);
4412 if (cacheDependenciesIter != userCacheDependencies.end())
4414 userCacheDependencies[currentCachePath].insert(cacheDependenciesIter->second.begin(), cacheDependenciesIter->second.end());
4415 userCacheDependencies.erase(cacheDependenciesIter);
4418 auto carriedOverIter = find(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(), cachePath);
4419 if (carriedOverIter != carriedOverUnloadableLibraries.end())
4420 *carriedOverIter = currentCachePath;
4428 if (wasModuleCacheRebuilt)
4432 vector<string> carriedOverUnloadableMinusResourceLibraries;
4433 std::set_difference(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(),
4434 carriedOverResourceLibraries.begin(), carriedOverResourceLibraries.end(),
4435 std::back_inserter(carriedOverUnloadableMinusResourceLibraries));
4437 carriedOverUnloadableLibraries = carriedOverUnloadableMinusResourceLibraries;
4440 userModuleAndLibraryDependencies.insert(dependenciesInResourceLibraries.begin(), dependenciesInResourceLibraries.end());
4442 set<string> builtInModuleAndLibraryDependencies_tmp;
4443 set<string> userModuleAndLibraryDependencies_tmp;
4444 map<string, set<string> > builtInCacheDependencies_tmp;
4445 set<Module *> builtInModules_tmp;
4446 set<string> builtInLibraries_tmp;
4447 set<string> externalLibraries_tmp;
4448 set<string> externalFrameworks_tmp;
4451 builtInModuleAndLibraryDependencies_tmp, userModuleAndLibraryDependencies_tmp, builtInCacheDependencies_tmp, userCacheDependencies,
4452 builtInModules_tmp, userModules, builtInLibraries_tmp, userLibraries, externalLibraries_tmp, externalFrameworks_tmp);
4457 if (! builtInModules.empty() || builtInLibraries.size() > builtInCacheDependencies.size())
4460 nonUnloadableDependencies = builtInModuleAndLibraryDependencies;
4462 set<string> librariesForNonUnloadableResource = builtInLibraries;
4463 librariesForNonUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4464 librariesForNonUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4465 librariesForNonUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4467 link(nonUnloadableResourcePath, builtInModules, librariesForNonUnloadableResource, allFrameworks,
true,
"", shouldAdHocCodeSign);
4469 for (set<string>::iterator i = builtInLibraries.begin(); i != builtInLibraries.end(); )
4472 builtInLibraries.erase(i++);
4477 for (set<string>::iterator i = addedExternalLibraries.begin(); i != addedExternalLibraries.end(); )
4480 addedExternalLibraries.erase(i++);
4488 if (! userModules.empty() || userLibraries.size() > userCacheDependencies.size() || wasModuleCacheRebuilt)
4491 unloadableDependencies = userModuleAndLibraryDependencies;
4493 set<string> librariesForUnloadableResource = userLibraries;
4494 librariesForUnloadableResource.insert(builtInLibraries.begin(), builtInLibraries.end());
4495 librariesForUnloadableResource.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4496 librariesForUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4497 librariesForUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4498 librariesForUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4499 if (! nonUnloadableResourcePath.empty())
4500 librariesForUnloadableResource.insert(nonUnloadableResourcePath);
4502 link(unloadableResourcePath, userModules, librariesForUnloadableResource, allFrameworks,
true,
"", shouldAdHocCodeSign);
4504 for (set<string>::iterator i = userLibraries.begin(); i != userLibraries.end(); )
4507 userLibraries.erase(i++);
4516 set<string> vuoRuntimePaths;
4518 set<Module *> modules;
4519 set<string> libraries;
4520 set<string> frameworks;
4522 set<string> dependencies;
4523 dependencies.insert(getRuntimeDependency());
4525 vuoRuntimePaths = libraries;
4531 set<Module *> modules;
4532 set<string> libraries;
4534 libraries.insert(compiledCompositionPath);
4535 libraries.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4536 libraries.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4537 libraries.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4538 libraries.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4539 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4540 libraries.insert(userLibraries.begin(), userLibraries.end());
4541 if (! nonUnloadableResourcePath.empty())
4542 libraries.insert(nonUnloadableResourcePath);
4543 if (! unloadableResourcePath.empty())
4544 libraries.insert(unloadableResourcePath);
4545 libraries.insert(vuoRuntimePaths.begin(), vuoRuntimePaths.end());
4546 link(linkedCompositionPath, modules, libraries, allFrameworks,
true,
"", shouldAdHocCodeSign);
4551 if (! nonUnloadableResourcePath.empty())
4554 if (! unloadableResourcePath.empty())
4557 for (map<
string, set<string> >::iterator i = builtInCacheDependencies.begin(); i != builtInCacheDependencies.end(); ++i)
4560 for (map<
string, set<string> >::iterator i = userCacheDependencies.begin(); i != userCacheDependencies.end(); ++i)
4573 set<string> VuoCompiler::getDependenciesForComposition(
const string &compiledCompositionPath)
4575 VDebugLog(
"Gathering dependencies for '%s'…", compiledCompositionPath.c_str());
4578 __block set<string> directDependencies;
4580 Module *module = readModuleFromBitcode(compiledCompositionPath, getTargetArch(target));
4584 delete compilerModule;
4590 auto deps = getDependenciesForComposition(directDependencies,
true);
4609 set<string> directDependencies;
4618 vector<VuoPublishedPort *> publishedPorts;
4619 publishedPorts.insert(publishedPorts.end(), publishedInputPorts.begin(), publishedInputPorts.end());
4620 publishedPorts.insert(publishedPorts.end(), publishedOutputPorts.begin(), publishedOutputPorts.end());
4623 if (publishedPort->getClass()->hasCompiler())
4639 directDependencies.insert(dependency);
4644 return directDependencies;
4656 return getDependenciesForComposition(directDependencies,
false);
4666 __block vector<string> librarySearchPaths;
4667 applyToInstalledEnvironments(^
void (Environment *env) {
4668 vector<string> result = env->getLibrarySearchPaths();
4669 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
4672 set<string> dylibDeps;
4673 for (
string dep : getDependenciesForComposition(composition))
4675 string path = getLibraryPath(dep, librarySearchPaths);
4677 dylibDeps.insert(path);
4696 set<string> VuoCompiler::getDependenciesForComposition(
const set<string> &directDependencies,
bool checkCompatibility)
4699 for (set<string>::const_iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4702 set<string> dependencies;
4703 for (set<string>::iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4705 string moduleKey = *i;
4707 dependencies.insert(moduleKey);
4710 vector<VuoDirectedAcyclicGraph::Vertex *> firstPassVertices = dependencyGraph->
findVertex(moduleKey);
4711 set<VuoDirectedAcyclicGraph::Vertex *> firstPassDependencies(firstPassVertices.begin(), firstPassVertices.end());
4712 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassVertices.begin(); j != firstPassVertices.end(); ++j)
4715 firstPassDependencies.insert(downstream.begin(), downstream.end());
4719 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassDependencies.begin(); j != firstPassDependencies.end(); ++j)
4721 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(*j);
4726 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
4727 set<VuoDirectedAcyclicGraph::Vertex *> moduleDependencies(moduleVertices.begin(), moduleVertices.end());
4728 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = moduleVertices.begin(); j != moduleVertices.end(); ++j)
4731 moduleDependencies.insert(downstream.begin(), downstream.end());
4735 set<string> dependenciesToAdd;
4736 set<string> incompatibleDependencies;
4737 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator j = moduleDependencies.begin(); j != moduleDependencies.end(); ++j)
4739 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(*j);
4740 if (! checkCompatibility || ! v->getEnvironment() || v->isCompatible())
4741 dependenciesToAdd.insert(v->getDependency());
4743 incompatibleDependencies.insert(v->getDependency());
4746 if (! checkCompatibility || incompatibleDependencies.empty())
4748 dependencies.insert(dependenciesToAdd.begin(), dependenciesToAdd.end());
4754 string dependencyTargetString;
4759 for (set<string>::iterator i = incompatibleDependencies.begin(); i != incompatibleDependencies.end(); ++i)
4765 dependencyTargets = dependencyTargets.
intersection(subDependencyTargets);
4768 dependencyTargetString = dependencyTargets.
toString();
4771 dependencyTargetString =
"(unknown systems)";
4773 string modulePlaceholder = (module ?
"%module" :
"%moduleKey");
4775 "Node incompatible with system",
4776 modulePlaceholder +
" is only compatible with " + dependencyTargetString +
4777 ", so this composition can't run on your system (" + compositionTargets.
toString() +
").");
4779 issue.setModuleKey(moduleKey);
4785 vector<string> coreDependencies = getCoreVuoDependencies();
4786 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
4788 return dependencies;
4795 void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4796 set<Module *> &modules, set<string> &libraries, set<string> &frameworks)
4798 set<string> builtInModuleAndLibraryDependencies;
4799 set<string> userModuleAndLibraryDependencies;
4800 map<string, set<string> > builtInCacheDependencies;
4801 map<string, set<string> > userCacheDependencies;
4802 set<Module *> builtInModules;
4803 set<Module *> userModules;
4804 set<string> builtInLibraries;
4805 set<string> userLibraries;
4806 set<string> externalLibraries;
4808 getLinkerInputs(dependencies, optimization,
4809 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4810 builtInModules, userModules, builtInLibraries, userLibraries, externalLibraries, frameworks);
4812 modules.insert(builtInModules.begin(), builtInModules.end());
4813 modules.insert(userModules.begin(), userModules.end());
4814 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4815 libraries.insert(userLibraries.begin(), userLibraries.end());
4816 libraries.insert(externalLibraries.begin(), externalLibraries.end());
4832 void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4833 set<string> &builtInModuleAndLibraryDependencies, set<string> &userModuleAndLibraryDependencies,
4834 map<
string, set<string> > &builtInCacheDependencies, map<
string, set<string> > &userCacheDependencies,
4835 set<Module *> &builtInModules, set<Module *> &userModules,
4836 set<string> &builtInLibraries, set<string> &userLibraries,
4837 set<string> &externalLibraries, set<string> &externalFrameworks)
4840 if (shouldUseModuleCache)
4843 __block vector<string> librarySearchPaths;
4844 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
4845 vector<string> result = env->getLibrarySearchPaths();
4846 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
4848 applyToInstalledEnvironments(envGetLibrarySearchPaths);
4850 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
4852 string dependency = *i;
4854 bool foundInCache =
false;
4855 string moduleCachePath;
4856 bool isInBuiltInModuleCache =
false;
4857 if (shouldUseModuleCache)
4858 foundInCache = findInModuleCache(dependency, moduleCachePath, isInBuiltInModuleCache);
4862 if (isInBuiltInModuleCache)
4864 builtInLibraries.insert(moduleCachePath);
4865 builtInCacheDependencies[moduleCachePath].insert(dependency);
4869 userLibraries.insert(moduleCachePath);
4870 userCacheDependencies[moduleCachePath].insert(dependency);
4876 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
4881 applyToAllEnvironments(envFindModule);
4891 if (module->isBuiltIn())
4892 builtInLibraries.insert(modulePath);
4894 userLibraries.insert(modulePath);
4898 if (module->isBuiltIn())
4899 builtInModules.insert(module->getModule());
4901 userModules.insert(module->getModule());
4904 if (module->isBuiltIn())
4905 builtInModuleAndLibraryDependencies.insert(dependency);
4907 userModuleAndLibraryDependencies.insert(dependency);
4913 externalFrameworks.insert(dependency);
4916 string dependencyPath = getLibraryPath(dependency, librarySearchPaths);
4917 if (! dependencyPath.empty())
4918 externalLibraries.insert(dependencyPath);
4922 else if (dependency !=
"c"
4923 && dependency !=
"objc")
4924 VUserLog(
"Warning: Could not locate dependency '%s'.", dependency.c_str());
4936 string VuoCompiler::getLibraryPath(
const string &dependency, vector<string> librarySearchPaths)
4943 if (dependency !=
"crypto"
4944 && dependency !=
"ssl")
4945 librarySearchPaths.push_back(
"/usr/lib");
4947 for (
auto &path : librarySearchPaths)
4949 vector<string> variations;
4950 variations.push_back(path +
"/" + dependency);
4951 variations.push_back(path +
"/lib" + dependency);
4952 variations.push_back(path +
"/lib" + dependency +
".dylib");
4953 variations.push_back(path +
"/lib" + dependency +
".a");
4954 for (
auto &variation : variations)
4969 void VuoCompiler::useModuleCache(
bool shouldUseExistingBuiltInCaches,
bool shouldUseExistingOtherCaches)
4971 loadModulesIfNeeded();
4972 dispatch_group_wait(moduleSourceCompilersExist, DISPATCH_TIME_FOREVER);
4976 dispatch_sync(environmentQueue, ^{
4977 set<string> dylibsForCachesOfInstalledModules;
4978 set<string> frameworksForCachesOfInstalledModules;
4979 unsigned long lastPrerequisiteModuleCacheRebuild = 0;
4980 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
4982 set<string> dylibsForCacheOfGeneratedModules;
4983 set<string> frameworksForCacheOfGeneratedModules;
4985 for (int j = i->size() - 1; j >= 0; --j)
4987 Environment *env = i->at(j);
4988 bool installed = (j == 0);
4990 set<string> cacheableModulesAndDependencies;
4991 set<string> dylibsNeededToLinkToThisCache;
4992 set<string> frameworksNeededToLinkToThisCache;
4993 env->getCacheableModulesAndDependencies(cacheableModulesAndDependencies,
4994 dylibsNeededToLinkToThisCache, frameworksNeededToLinkToThisCache);
4996 set<string> accumulatedDylibs;
4997 accumulatedDylibs.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
4998 accumulatedDylibs.insert(dylibsForCachesOfInstalledModules.begin(), dylibsForCachesOfInstalledModules.end());
4999 accumulatedDylibs.insert(dylibsForCacheOfGeneratedModules.begin(), dylibsForCacheOfGeneratedModules.end());
5001 set<string> accumulatedFrameworks;
5002 accumulatedFrameworks.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5003 accumulatedFrameworks.insert(frameworksForCachesOfInstalledModules.begin(), frameworksForCachesOfInstalledModules.end());
5004 accumulatedFrameworks.insert(frameworksForCacheOfGeneratedModules.begin(), frameworksForCacheOfGeneratedModules.end());
5006 bool shouldUseExistingCache = (env->isBuiltIn() ? shouldUseExistingBuiltInCaches : shouldUseExistingOtherCaches);
5007 env->useModuleCache(shouldUseExistingCache, this, cacheableModulesAndDependencies,
5008 accumulatedDylibs, accumulatedFrameworks, lastPrerequisiteModuleCacheRebuild);
5010 string cacheDylib = env->getCurrentModuleCacheDylib();
5011 accumulatedDylibs.insert(cacheDylib);
5012 dylibsForCachesOfInstalledModules.insert(cacheDylib);
5014 lastPrerequisiteModuleCacheRebuild = max(lastPrerequisiteModuleCacheRebuild, env->getLastModuleCacheRebuild());
5018 dylibsForCachesOfInstalledModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5019 frameworksForCachesOfInstalledModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5023 dylibsForCacheOfGeneratedModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5024 frameworksForCacheOfGeneratedModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5030 Environment::waitForModuleCachesToBuild();
5041 bool VuoCompiler::findInModuleCache(
const string &moduleOrDependency,
string &cachePath,
bool &isBuiltinCache)
5043 __block
bool found =
false;
5044 __block
string outPath;
5045 __block
bool outBuiltin;
5046 dispatch_sync(environmentQueue, ^{
5047 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
5049 bool builtin = (i == environments.begin());
5051 for (int j = i->size() - 1; j >= 0; --j)
5053 Environment *env = i->at(j);
5056 bool resultFound = env->findInModuleCache(moduleOrDependency, resultPath);
5060 outPath = resultPath;
5061 outBuiltin = builtin;
5067 cachePath = outPath;
5068 isBuiltinCache = outBuiltin;
5081 dispatch_group_async(moduleCacheBuilding, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
5082 useModuleCache(
true,
false);
5092 return getTargetArch(target);
5110 vuoFrameworkInProgressPath = vuoFrameworkPath;
5113 compiler.useModuleCache(
false,
true);
5125 unsigned long maxSeconds = 30 * 24 * 60 * 60;
5128 for (set<VuoFileUtilities::File *>::iterator i = cacheDirs.begin(); i != cacheDirs.end(); ++i)
5130 string path = (*i)->path();
5132 string file = (*i)->basename();
5133 if (file !=
"Builtin" && file !=
"System" && file !=
"User")
5136 if (fileSeconds > maxSeconds)
5142 string pidAsString = file.substr(Environment::pidCacheDirPrefix.length());
5143 int pid = atoi(pidAsString.c_str());
5144 if (kill(pid, 0) != 0)
5158 dispatch_sync(modulesToLoadQueue, ^{
5159 this->shouldLoadAllModules = shouldLoadAllModules;
5175 void VuoCompiler::link(
string outputPath,
const set<Module *> &modules,
const set<string> &libraries,
const set<string> &frameworks,
bool isDylib,
string rPath,
bool shouldAdHocCodeSign,
VuoCompilerIssues *issues)
5177 VDebugLog(
"Linking '%s' (%s)…", outputPath.c_str(), getTargetArch(target).c_str());
5185 unique_ptr<Module> compositeModule(
new Module(
"composite", *
globalLLVMContext));
5186 Linker linker(*compositeModule);
5187 setTargetForModule(compositeModule.get(), target);
5188 for (
auto i : modules)
5190 unique_ptr<Module> upi = llvm::CloneModule(i);
5191 if (linker.linkInModule(std::move(upi)))
5192 VUserLog(
"Error: Failed to link compositeModule.");
5194 writeModuleToBitcode(compositeModule.get(), compositeModulePath);
5202 string clangPath(getClangPath() +
"++");
5204 vector<const char *> args;
5205 vector<char *> argsToFree;
5206 args.push_back(clangPath.c_str());
5209 char *outputPathZ = strdup((
"-o" + outputPath).c_str());
5210 args.push_back(outputPathZ);
5211 argsToFree.push_back(outputPathZ);
5214 args.push_back(compositeModulePath.c_str());
5216 vector<string> coreDependencies = getCoreVuoDependencies();
5217 for (set<string>::const_iterator i = libraries.begin(); i != libraries.end(); ++i)
5219 string library = *i;
5221 for (vector<string>::iterator j = coreDependencies.begin(); j != coreDependencies.end(); ++j)
5223 string coreDependency = *j;
5225 args.push_back(
"-force_load");
5233 library = libraryObject;
5236 char *libraryZ = strdup(library.c_str());
5237 args.push_back(libraryZ);
5238 argsToFree.push_back(libraryZ);
5242 vector<string> frameworkArguments;
5244 __block vector<string> frameworkSearchPaths;
5245 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
5246 vector<string> result = env->getFrameworkSearchPaths();
5247 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
5249 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
5251 for (vector<string>::const_iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
5255 frameworkArguments.push_back(a);
5256 char *frameworkArgument = strdup(a.c_str());
5257 args.push_back(frameworkArgument);
5258 argsToFree.push_back(frameworkArgument);
5261 for (set<string>::const_iterator i = frameworks.begin(); i != frameworks.end(); ++i)
5263 args.push_back(
"-framework");
5265 string frameworkName = *i;
5266 frameworkName = frameworkName.substr(0, frameworkName.length() -
string(
".framework").length());
5267 char *frameworkNameZ = strdup(frameworkName.c_str());
5268 args.push_back(frameworkNameZ);
5269 argsToFree.push_back(frameworkNameZ);
5274 string vuoFrameworkPath = getVuoFrameworkPath();
5275 string vuoFrameworkContainingFolder = vuoFrameworkPath +
"/..";
5276 string frameworkMacOSSDKFolder = vuoFrameworkPath +
"/SDKs/MacOSX10.11.sdk";
5280 args.push_back(
"-Xlinker");
5281 args.push_back(
"-syslibroot");
5282 args.push_back(
"-Xlinker");
5283 char *frameworkMacOSSDKFolderZ = strdup(frameworkMacOSSDKFolder.c_str());
5284 args.push_back(frameworkMacOSSDKFolderZ);
5285 argsToFree.push_back(frameworkMacOSSDKFolderZ);
5289 args.push_back(
"-Xlinker");
5290 args.push_back(
"--no-demangle");
5293 args.push_back(
"-v");
5296 args.push_back(
"-dynamiclib");
5298 args.push_back(
"-Xlinker");
5299 args.push_back(
"-headerpad_max_install_names");
5302 args.push_back(
"-rpath");
5303 string rPathArg = (rPath.empty() ? vuoFrameworkContainingFolder : rPath);
5304 args.push_back(rPathArg.c_str());
5307 args.push_back(
"-rpath");
5308 args.push_back(LLVM_ROOT
"/lib");
5311 args.push_back(
"-target");
5312 args.push_back(target.c_str());
5314 args.push_back(
"-std=c++11");
5315 args.push_back(
"-stdlib=libc++");
5316 args.push_back(
"-mmacosx-version-min=10.10");
5320 clang::DiagnosticOptions *diagOptions =
new clang::DiagnosticOptions();
5321 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5322 clang::DiagnosticsEngine Diags(DiagID, diagOptions, diagnosticConsumer);
5327 for (vector<const char *>::iterator i = args.begin(); i != args.end(); ++i)
5334 const StringRef stdoutPath(stdoutFile);
5335 const StringRef *redirects[] = {
5342 const char **argsz = (
const char **)malloc(
sizeof(
char *) * args.size() + 1);
5343 for (
int i = 0; i < args.size(); ++i)
5345 argsz[args.size()] =
nullptr;
5348 bool executionFailed;
5350 int ret = llvm::sys::ExecuteAndWait(args[0], argsz,
nullptr, redirects, 0, 0, &errMsg, &executionFailed);
5352 for (
auto i : argsToFree)
5356 remove(compositeModulePath.c_str());
5362 chmod(outputPath.c_str(), 0755);
5367 if (!errMsg.empty())
5370 details +=
"\n" + errMsg +
"\n";
5373 if (!stdoutFileContents.empty())
5375 VUserLog(
"%s", stdoutFileContents.c_str());
5376 details +=
"\n" + stdoutFileContents +
"\n";
5381 "Node broken or outdated", details);
5388 if (shouldAdHocCodeSign)
5389 adHocCodeSign(outputPath);
5395 void VuoCompiler::adHocCodeSign(
string path)
5399 "/usr/bin/codesign",
5405 "CODESIGN_ALLOCATE=" + getCodesignAllocatePath(),
5417 Module *VuoCompiler::readModuleFromC(
string inputPath,
const vector<string> &headerSearchPaths,
const vector<string> &extraArgs,
VuoCompilerIssues *issues)
5421 vector<const char *> args;
5422 args.push_back(inputPath.c_str());
5423 args.push_back(
"-DVUO_COMPILER");
5424 args.push_back(
"-fblocks");
5427 args.push_back(
"-Wall");
5428 args.push_back(
"-Wextra");
5429 args.push_back(
"-Wimplicit-fallthrough");
5430 args.push_back(
"-Wno-unused-parameter");
5431 args.push_back(
"-Wno-c++11-extensions");
5432 args.push_back(
"-Wno-sign-compare");
5433 args.push_back(
"-Werror=implicit");
5437 args.push_back(
"-std=c++11");
5438 args.push_back(
"-stdlib=libc++");
5441 for (vector<string>::const_iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
5443 args.push_back(
"-I");
5444 args.push_back(i->c_str());
5448 args.push_back(
"-v");
5450 for (vector<string>::const_iterator i = extraArgs.begin(); i != extraArgs.end(); ++i)
5451 args.push_back(i->c_str());
5454 clang::DiagnosticOptions * diagOptions =
new clang::DiagnosticOptions();
5455 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5456 clang::DiagnosticsEngine *diags =
new clang::DiagnosticsEngine(DiagID, diagOptions, diagnosticConsumer);
5458 shared_ptr<clang::CompilerInvocation> compilerInvocation(
new clang::CompilerInvocation);
5459 clang::CompilerInvocation::CreateFromArgs(*compilerInvocation, &args[0], &args[0] + args.size(), *diags);
5460 compilerInvocation->TargetOpts->Triple = target;
5462 clang::CompilerInstance Clang;
5463 Clang.setInvocation(compilerInvocation);
5465 Clang.setDiagnostics(diags);
5466 if (!Clang.hasDiagnostics())
5470 string builtinHeaderSearchPath;
5471 string vuoFrameworkPath = getVuoFrameworkPath();
5472 if (vuoFrameworkPath.empty())
5474 builtinHeaderSearchPath = getClangPath();
5479 builtinHeaderSearchPath +=
"lib/clang/" CLANG_VERSION_STRING;
5482 builtinHeaderSearchPath = vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/lib/clang/" CLANG_VERSION_STRING;
5483 Clang.getHeaderSearchOpts().ResourceDir = builtinHeaderSearchPath;
5486 clang::CodeGenAction *Act =
new clang::EmitLLVMOnlyAction();
5487 if (!Clang.ExecuteAction(*Act))
5490 unique_ptr<Module> module = Act->takeModule();
5492 VUserLog(
"Error compiling %s: module is null.", inputPath.c_str());
5493 return module.release();
5501 Module *VuoCompiler::readModuleFromBitcode(
string inputPath,
string arch)
5503 string dir, file, ext;
5506 return readModuleFromBitcode(&inputFile, arch);
5518 size_t inputDataBytes;
5523 Module *module = readModuleFromBitcodeData(inputData, inputDataBytes, arch, error);
5526 VUserLog(
"Error: Couldn't parse module '%s' (%s): %s.", inputFile->
getRelativePath().c_str(), arch.c_str(), error.c_str());
5538 Module *VuoCompiler::readModuleFromBitcodeData(
char *inputData,
size_t inputDataBytes,
string arch,
string &error)
5540 if (inputDataBytes <
sizeof(
unsigned int))
5543 __block Module *module =
nullptr;
5545 StringRef inputDataAsStringRef(inputData, inputDataBytes);
5546 auto mb = MemoryBuffer::getMemBuffer(inputDataAsStringRef,
"",
false);
5549 error =
"Couldn't create MemoryBuffer";
5553 MemoryBufferRef bitcodeBuffer;
5555 unsigned int fileID = *(
unsigned int *)inputData;
5556 if (fileID == 0x0b17c0de)
5558 bitcodeBuffer = mb.get()->getMemBufferRef();
5560 else if (fileID == 0xdec04342)
5563 bitcodeBuffer = mb.get()->getMemBufferRef();
5564 moduleArch =
"x86_64";
5567 else if (fileID == 0xbebafeca)
5571 error =
"It's a Mach-O universal binary, but this compiler instance's LLVM target isn't set";
5577 auto binary = llvm::object::MachOUniversalBinary::create(mb.get()->getMemBufferRef());
5580 error =
"Couldn't read Mach-O universal binary:";
5581 handleAllErrors(binary.takeError(), [&error](
const ErrorInfoBase &ei) {
5582 error +=
" " + ei.message();
5587 for (
auto &o : binary.get()->objects())
5588 if (o.getArchFlagName() == arch)
5589 bitcodeBuffer = MemoryBufferRef(mb.get()->getMemBufferRef().getBuffer().slice(o.getOffset(), o.getOffset() + o.getSize()),
"");
5590 if (!bitcodeBuffer.getBufferSize())
5592 error =
"The Mach-O universal binary doesn't have an \"" + arch +
"\" slice";
5600 error =
"Couldn't parse bitcode file:";
5601 handleAllErrors(wrappedModule.takeError(), [&error](
const ErrorInfoBase &ei) {
5602 error +=
" " + ei.message();
5607 module = wrappedModule.get().release();
5609 if (moduleArch.empty())
5610 moduleArch = getTargetArch(module->getTargetTriple());
5611 if (moduleArch != arch)
5613 error =
"The module's CPU architecture \"" + moduleArch +
"\" doesn't match the compiler's CPU architecture \"" + arch +
"\"";
5629 bool VuoCompiler::writeModuleToBitcode(Module *module,
string outputPath)
5632 raw_string_ostream verifyOut(str);
5633 if (llvm::verifyModule(*module, &verifyOut))
5635 VUserLog(
"Error: Module verification failed:\n%s", verifyOut.str().c_str());
5640 if (module->getTargetTriple().empty())
5641 setTargetForModule(module, getProcessTarget());
5643 std::error_code err;
5644 raw_fd_ostream out(outputPath.c_str(), err, sys::fs::F_None);
5647 VUserLog(
"Error: Couldn't open file '%s' for writing: %s", outputPath.c_str(), err.message().c_str());
5650 llvm::WriteBitcodeToFile(module, out);
5660 void VuoCompiler::setTargetForModule(Module *module,
string targetTriple)
5662 module->setTargetTriple(targetTriple);
5665 auto target = TargetRegistry::lookupTarget(module->getTargetTriple(), error);
5668 VUserLog(
"Error: Couldn't look up target: %s", error.c_str());
5672 auto targetMachine = target->createTargetMachine(module->getTargetTriple(),
"",
"", TargetOptions(), Optional<Reloc::Model>());
5675 VUserLog(
"Error: Couldn't create targetMachine.");
5679 module->setDataLayout(targetMachine->createDataLayout());
5681 delete targetMachine;
5688 string VuoCompiler::getTargetArch(
string target)
5690 auto hyphen = target.find(
'-');
5691 if (hyphen == string::npos)
5694 return target.substr(0, hyphen);
5700 string VuoCompiler::getProcessTarget(
void)
5706 return getTargetArch(llvm::sys::getDefaultTargetTriple())
5709 +
"-apple-macosx10.10.0";
5720 Module *llvmModule = module->
getModule();
5749 delete baseNodeClass;
5782 if (nodeClassForNode)
5783 return nodeClassForNode->
newNode(title, x, y);
5797 if (nodeClassForNode)
5798 return nodeClassForNode->
newNode(nodeToCopyMetadataFrom);
5809 return createPublishedNode(nodeClassName, publishedInputPorts);
5818 return createPublishedNode(nodeClassName, publishedOutputPorts);
5824 VuoNode * VuoCompiler::createPublishedNode(
const string &nodeClassName,
const vector<VuoPublishedPort *> &publishedPorts)
5832 for (
size_t i = 0; i < publishedPorts.size(); ++i)
5834 VuoType *publishedPortType =
static_cast<VuoCompilerPort *
>(publishedPorts[i]->getCompiler())->getDataVuoType();
5838 set<VuoPort *> nodePorts;
5842 nodePorts.insert(inputPort);
5845 nodePorts.insert(outputPort);
5850 nodePorts.insert(inputPort);
5853 for (
VuoPort *port : nodePorts)
5860 reifyGenericPortTypes(node);
5871 dispatch_sync(environmentQueue, ^{
5872 if (environments.size() >= 5)
5873 environments.at(3).at(0)->addExpatriateSourceFile(sourcePath);
5883 dispatch_sync(environmentQueue, ^{
5884 if (environments.size() >= 5)
5886 environments.at(3).at(0)->removeExpatriateSourceFile(sourcePath);
5888 set<string> sourcesRemoved;
5889 sourcesRemoved.insert(getModuleKeyForPath(sourcePath));
5890 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), set<string>(), sourcesRemoved,
5891 false, false, environments.at(3).at(0), nullptr, nullptr,
"");
5914 string sourcePathCopy = sourcePath;
5915 string sourceCodeCopy = sourceCode;
5917 dispatch_async(environmentQueue, ^{
5919 ModuleInfo *sourceInfo = NULL;
5921 for (
const vector<Environment *> &envs : environments)
5923 for (Environment *env : envs)
5925 ModuleInfo *potentialSourceInfo = env->listSourceFile(nodeClassName);
5928 sourceInfo = potentialSourceInfo;
5937 bool shouldRecompileSourcesIfUnchanged;
5938 if (! sourceCodeCopy.empty())
5940 sourceInfo->setSourceCode(sourceCodeCopy);
5941 sourceInfo->setSourceCodeOverridden(
true);
5943 shouldRecompileSourcesIfUnchanged =
false;
5947 sourceInfo->revertSourceCode();
5948 sourceInfo->setSourceCodeOverridden(
false);
5950 shouldRecompileSourcesIfUnchanged =
true;
5952 sourceInfo->setAttempted(
false);
5953 sourceInfo->setLastModifiedToNow();
5955 set<string> sourcesModified;
5956 sourcesModified.insert(nodeClassName);
5958 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), sourcesModified, set<string>(),
5959 false, shouldRecompileSourcesIfUnchanged,
nullptr,
nullptr,
nullptr,
"");
5998 set<string> nodeClassNameSet;
5999 nodeClassNameSet.insert(nodeClassName);
6000 loadModulesIfNeeded(nodeClassNameSet);
6005 void (^envGetNodeClass)(Environment *) = ^
void (Environment *env) {
6010 applyToAllEnvironments(envGetNodeClass);
6021 loadModulesIfNeeded();
6023 __block map<string, VuoCompilerNodeClass *> nodeClasses;
6024 void (^envGetNodeClasses)(Environment *) = ^
void (Environment *env) {
6025 map<string, VuoCompilerNodeClass *> result = env->getNodeClasses();
6026 nodeClasses.insert(result.begin(), result.end());
6028 applyToInstalledEnvironments(envGetNodeClasses);
6039 set<string> typeNameSet;
6040 typeNameSet.insert(typeName);
6041 loadModulesIfNeeded(typeNameSet);
6044 void (^envGetType)(Environment *) = ^
void (Environment *env) {
6049 applyToInstalledEnvironments(envGetType);
6071 loadModulesIfNeeded();
6073 __block map<string, VuoCompilerType *> types;
6074 void (^envGetTypes)(Environment *) = ^
void (Environment *env) {
6075 map<string, VuoCompilerType *> result = env->getTypes();
6076 types.insert(result.begin(), result.end());
6078 applyToInstalledEnvironments(envGetTypes);
6089 set<string> libraryNameSet;
6090 libraryNameSet.insert(libraryModuleName);
6091 loadModulesIfNeeded(libraryNameSet);
6094 void (^envGetLibraryModule)(Environment *) = ^
void (Environment *env) {
6099 applyToInstalledEnvironments(envGetLibraryModule);
6111 loadModulesIfNeeded();
6113 __block map<string, VuoCompilerModule *> libraryModules;
6114 void (^envGetLibraryModules)(Environment *) = ^
void (Environment *env) {
6115 map<string, VuoCompilerModule *> result = env->getLibraryModules();
6116 libraryModules.insert(result.begin(), result.end());
6118 applyToInstalledEnvironments(envGetLibraryModules);
6119 return libraryModules;
6129 loadModulesIfNeeded();
6131 __block map<string, VuoNodeSet *> nodeSets;
6132 void (^envGetNodeSets)(Environment *) = ^
void (Environment *env) {
6133 map<string, VuoNodeSet *> result = env->getNodeSets();
6134 nodeSets.insert(result.begin(), result.end());
6136 applyToInstalledEnvironments(envGetNodeSets);
6147 loadModulesIfNeeded();
6150 void (^envFindNodeSet)(Environment *) = ^
void (Environment *env) {
6155 applyToInstalledEnvironments(envFindNodeSet);
6165 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
6170 applyToAllEnvironments(envFindModule);
6187 map<string, VuoCompilerNodeClass *> nodeClasses =
getNodeClasses();
6188 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
6195 else if (format ==
"path")
6199 else if (format ==
"dot")
6217 vector<string> VuoCompiler::getCoreVuoDependencies(
void)
6219 vector<string> dependencies;
6221 dependencies.push_back(
"VuoHeap");
6222 dependencies.push_back(
"VuoApp");
6224 dependencies.push_back(
"zmq");
6225 dependencies.push_back(
"json-c");
6226 dependencies.push_back(
"objc");
6227 dependencies.push_back(
"c");
6228 dependencies.push_back(
"AppKit.framework");
6231 dependencies.push_back(LLVM_ROOT
"/lib/libprofile_rt.dylib");
6233 return dependencies;
6239 string VuoCompiler::getRuntimeMainDependency(
void)
6241 return "VuoRuntimeMain.o";
6251 string VuoCompiler::getRuntimeDependency(
void)
6253 return "VuoRuntime.o";
6262 string VuoCompiler::getVuoFrameworkPath(
void)
6264 if (! vuoFrameworkInProgressPath.empty())
6265 return vuoFrameworkInProgressPath;
6273 string VuoCompiler::getClangPath(
void)
6284 string dir, moduleKey, ext;
6292 while (nodeClassNameParts.size() > 1 && nodeClassNameParts.back() == ext)
6293 nodeClassNameParts.pop_back();
6296 for (
string &part : nodeClassNameParts)
6300 if (nodeClassNameParts.size() == 1)
6301 nodeClassNameParts.insert(nodeClassNameParts.begin(),
"isf");
6315 __block
bool isLocal =
false;
6317 dispatch_sync(environmentQueue, ^{
6318 if (environments.size() >= 5)
6319 isLocal = environments.at(3).at(0)->findModule(moduleKey);
6333 return lastCompositionBaseDir.empty() ?
"" : lastCompositionBaseDir +
"/Modules";
6348 return lastCompositionBaseDir;
6354 void VuoCompiler::addModuleSearchPath(
string path)
6356 dispatch_sync(environmentQueue, ^{
6357 environments.back().at(0)->addModuleSearchPath(path);
6367 dispatch_sync(environmentQueue, ^{
6377 dispatch_sync(environmentQueue, ^{
6387 dispatch_sync(environmentQueue, ^{
6397 this->telemetry = telemetry;
6405 this->isVerbose = isVerbose;
6415 if (VuoPro::getProAccess())
6417 _shouldShowSplashWindow =
false;
6422 _shouldShowSplashWindow = potentiallyShow;
6430 return _shouldShowSplashWindow;
6436 void VuoCompiler::setClangPath(
const string &clangPath)
6438 this->clangPath = clangPath;
6446 string vuoFrameworkPath = getVuoFrameworkPath();
6447 return (vuoFrameworkPath.empty() ?
6448 VUO_BUILD_DIR
"/bin/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader" :
6449 vuoFrameworkPath +
"/Helpers/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader");
6455 string VuoCompiler::getCompositionStubPath(
void)
6457 string vuoFrameworkPath = getVuoFrameworkPath();
6458 return (vuoFrameworkPath.empty() ?
6459 VUO_BUILD_DIR
"/lib/libVuoCompositionStub.dylib" :
6460 vuoFrameworkPath +
"/Modules/libVuoCompositionStub.dylib");
6466 string VuoCompiler::getCachePathForComposition(
const string compositionDir)
6468 string modifierLetterColon(
"꞉");
6469 string cachedModulesName = compositionDir;
6479 __block vector<string> moduleSearchPaths;
6480 void (^envGetModuleSearchPaths)(Environment *) = ^
void (Environment *env) {
6481 vector<string> result = env->getModuleSearchPaths();
6482 moduleSearchPaths.insert(moduleSearchPaths.end(), result.begin(), result.end());
6484 applyToInstalledEnvironments(envGetModuleSearchPaths);
6486 __block vector<string> headerSearchPaths;
6487 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
6488 vector<string> result = env->getHeaderSearchPaths();
6489 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
6491 applyToInstalledEnvironments(envGetHeaderSearchPaths);
6493 __block vector<string> librarySearchPaths;
6494 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
6495 vector<string> result = env->getLibrarySearchPaths();
6496 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
6498 applyToInstalledEnvironments(envGetLibrarySearchPaths);
6500 __block vector<string> frameworkSearchPaths;
6501 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
6502 vector<string> result = env->getFrameworkSearchPaths();
6503 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
6505 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
6507 fprintf(stderr,
"Module (node class, type, library) search paths:\n");
6508 for (vector<string>::iterator i = moduleSearchPaths.begin(); i != moduleSearchPaths.end(); ++i)
6509 fprintf(stderr,
" %s\n", (*i).c_str());
6510 fprintf(stderr,
"Header search paths:\n");
6511 for (vector<string>::iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
6512 fprintf(stderr,
" %s\n", (*i).c_str());
6513 fprintf(stderr,
"Other library search paths:\n");
6514 for (vector<string>::iterator i = librarySearchPaths.begin(); i != librarySearchPaths.end(); ++i)
6515 fprintf(stderr,
" %s\n", (*i).c_str());
6516 fprintf(stderr,
"Other framework search paths:\n");
6517 for (vector<string>::iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
6518 fprintf(stderr,
" %s\n", (*i).c_str());
6519 fprintf(stderr,
"Framework path:\n");
6520 if (! getVuoFrameworkPath().empty())
6521 fprintf(stderr,
" %s\n", getVuoFrameworkPath().c_str());
6522 fprintf(stderr,
"Clang path:\n");
6523 if (! getClangPath().empty())
6524 fprintf(stderr,
" %s\n", getClangPath().c_str());
6540 string directory, file, extension;
6544 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6546 remove(compiledCompositionPath.c_str());
6575 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/" + processName +
".vuo";
6581 remove(compiledCompositionPath.c_str());
6605 string directory, file, extension;
6608 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6611 remove(compiledCompositionPath.c_str());
6640 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/UntitledComposition.vuo";
6646 remove(compiledCompositionPath.c_str());
6659 pendingDataQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.pending", 0);
6664 LoadedModulesData *data = dequeueData();
6671 void VuoCompilerDelegate::enqueueData(LoadedModulesData *data)
6673 dispatch_sync(pendingDataQueue, ^{
6674 pendingData.push_back(data);
6681 VuoCompilerDelegate::LoadedModulesData * VuoCompilerDelegate::dequeueData(
void)
6683 __block LoadedModulesData *ret;
6684 dispatch_sync(pendingDataQueue, ^{
6685 ret = pendingData.front();
6686 pendingData.pop_front();
6695 VuoCompilerDelegate::LoadedModulesData::LoadedModulesData(
const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
6698 referenceCountQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.reference", 0);
6701 this->modulesModified = modulesModified;
6702 this->modulesRemoved = modulesRemoved;
6703 this->issues = issues;
6709 VuoCompilerDelegate::LoadedModulesData::~LoadedModulesData(
void)
6713 for (set< pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); ++i)
6716 for (set<VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); ++i)
6723 void VuoCompilerDelegate::LoadedModulesData::retain(
void)
6725 dispatch_sync(referenceCountQueue, ^{
6733 void VuoCompilerDelegate::LoadedModulesData::release(
void)
6735 dispatch_sync(referenceCountQueue, ^{
6737 if (referenceCount == 0) {