11 #include <sys/param.h>
15 #include <CoreFoundation/CoreFoundation.h>
50 map<string, VuoFileUtilities::File *> VuoCompiler::Environment::moduleCacheFileForLocking;
51 dispatch_queue_t VuoCompiler::Environment::moduleCacheBuildingQueue = dispatch_queue_create(
"org.vuo.compiler.cache", NULL);
52 const string VuoCompiler::Environment::pidCacheDirPrefix =
"pid-";
53 set<VuoCompiler *> VuoCompiler::allCompilers;
54 dispatch_queue_t VuoCompiler::environmentQueue = dispatch_queue_create(
"org.vuo.compiler.environment", NULL);
55 map<string, vector< vector<VuoCompiler::Environment *> > > VuoCompiler::sharedEnvironments;
56 map<string, map<string, vector<VuoCompiler::Environment *> > > VuoCompiler::environmentsForCompositionFamily;
57 dispatch_group_t VuoCompiler::moduleSourceCompilersExistGlobally = dispatch_group_create();
58 string VuoCompiler::vuoFrameworkInProgressPath;
67 static void __attribute__((constructor)) VuoCompiler_init(
void)
70 struct rlimit rl{OPEN_MAX, OPEN_MAX};
71 getrlimit(RLIMIT_NOFILE, &rl);
72 rl.rlim_cur =
MIN(OPEN_MAX, rl.rlim_max);
73 if (setrlimit(RLIMIT_NOFILE, &rl))
74 VUserLog(
"Warning: Couldn't set open-files limit: %s", strerror(errno));
77 llvmQueue = dispatch_queue_create(
"org.vuo.compiler.llvm", NULL);
81 llvm::InitializeAllTargetMCs();
82 llvm::InitializeAllTargets();
91 raw_string_ostream stream(message);
92 DiagnosticPrinterRawOStream printer(stream);
95 if (! message.empty())
97 const char *severityName;
98 if (DI.getSeverity() == DS_Error)
99 severityName =
"error";
100 else if (DI.getSeverity() == DS_Warning)
101 severityName =
"warning";
103 severityName =
"note";
105 VuoLog(__FILE__, __LINE__,
"llvmDiagnosticHandler",
"%s: %s", severityName, message.c_str());
139 VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
const string &relativePath,
140 bool isSourceFile,
bool isSubcomposition)
143 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
149 VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
150 bool isSourceFile,
bool isSubcomposition)
152 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
158 void VuoCompiler::ModuleInfo::initialize(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
159 bool isSourceFile,
bool isSubcomposition)
161 this->environment = environment;
162 this->searchPath = searchPath;
165 sourceCodeOverridden =
false;
167 longestDownstreamPath = 0;
177 loading = dispatch_group_create();
180 if (isSubcomposition)
194 VuoCompiler::ModuleInfo::~ModuleInfo(
void)
203 dispatch_release(loading);
206 VuoCompiler::Environment * VuoCompiler::ModuleInfo::getEnvironment(
void)
const
211 string VuoCompiler::ModuleInfo::getSearchPath(
void)
const
216 string VuoCompiler::ModuleInfo::getModuleKey(
void)
const
226 string VuoCompiler::ModuleInfo::getSourceCode(
void)
const
231 void VuoCompiler::ModuleInfo::setSourceCode(
const string &sourceCode)
233 this->sourceCode = sourceCode;
236 void VuoCompiler::ModuleInfo::revertSourceCode(
void)
241 bool VuoCompiler::ModuleInfo::isSourceCodeOverridden(
void)
const
243 return sourceCodeOverridden;
246 void VuoCompiler::ModuleInfo::setSourceCodeOverridden(
bool overridden)
248 sourceCodeOverridden = overridden;
251 bool VuoCompiler::ModuleInfo::isNewerThan(ModuleInfo *other)
const
253 return lastModified > other->lastModified;
256 bool VuoCompiler::ModuleInfo::isNewerThan(
unsigned long ageInSeconds)
const
258 return lastModified > ageInSeconds;
261 bool VuoCompiler::ModuleInfo::isOlderThan(
unsigned long ageInSeconds)
const
263 return lastModified < ageInSeconds;
266 void VuoCompiler::ModuleInfo::setLastModifiedToNow(
void)
269 gettimeofday(&t, NULL);
270 lastModified = t.tv_sec;
273 set<string> VuoCompiler::ModuleInfo::getContainedNodeClasses(
void)
const
275 return containedNodeClasses;
278 int VuoCompiler::ModuleInfo::getLongestDownstreamPath(
void)
const
280 return longestDownstreamPath;
283 void VuoCompiler::ModuleInfo::setLongestDownstreamPath(
int pathLength)
285 longestDownstreamPath = pathLength;
288 bool VuoCompiler::ModuleInfo::getAttempted(
void)
const
293 void VuoCompiler::ModuleInfo::setAttempted(
bool attempted)
295 this->attempted = attempted;
298 dispatch_group_t VuoCompiler::ModuleInfo::getLoadingGroup(
void)
const
303 void VuoCompiler::ModuleInfo::dump()
const
305 fprintf(stderr,
"module %s:\n"
306 "\tloadingGroup=%p\n"
311 "\tsourceCodeOverridden=%d\n"
313 "\tcontainedNodeClasses:\n",
318 environment->getCompiledModuleCachePath().c_str(),
322 sourceCodeOverridden,
324 for (
auto i: containedNodeClasses)
325 fprintf(stderr,
"\t\t%s\n", i.c_str());
328 VuoCompiler::DependencyGraphVertex * VuoCompiler::DependencyGraphVertex::vertexForDependency(
const string &dependency,
VuoDirectedAcyclicGraph *graph)
332 return dynamic_cast<DependencyGraphVertex *
>(v);
334 DependencyGraphVertex *vv =
new DependencyGraphVertex();
335 vv->dependency = dependency;
336 vv->environment = NULL;
337 vv->compatible =
true;
341 string VuoCompiler::DependencyGraphVertex::getDependency(
void)
346 VuoCompiler::Environment * VuoCompiler::DependencyGraphVertex::getEnvironment(
void)
351 void VuoCompiler::DependencyGraphVertex::setEnvironment(Environment *environment)
353 this->environment = environment;
356 string VuoCompiler::DependencyGraphVertex::key(
void)
368 VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos,
369 const string &overriddenCompiledModuleCachePath)
371 this->allModuleInfos = allModuleInfos;
372 this->overriddenCompiledModuleCachePath = overriddenCompiledModuleCachePath;
373 hasSearchModuleKeys =
false;
384 VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos,
385 const string &overriddenCompiledModuleCachePath,
386 const set<string> &searchModuleKeys)
388 this->allModuleInfos = allModuleInfos;
389 this->overriddenCompiledModuleCachePath = overriddenCompiledModuleCachePath;
390 this->searchModuleKeys = searchModuleKeys;
391 hasSearchModuleKeys =
true;
400 void VuoCompiler::ModuleInfoIterator::initialize(
void)
402 currSearchPath = allModuleInfos->begin();
403 hasCurrModuleKey =
false;
405 if (! overriddenCompiledModuleCachePath.empty())
407 auto i = allModuleInfos->find(overriddenCompiledModuleCachePath);
408 if (i != allModuleInfos->end())
410 std::transform(i->second.begin(), i->second.end(),
411 std::inserter(overriddenModuleKeys, overriddenModuleKeys.begin()),
412 [](
const pair<string, ModuleInfo *> &p) { return p.first; });
422 VuoCompiler::ModuleInfo * VuoCompiler::ModuleInfoIterator::next(
void)
424 for ( ; currSearchPath != allModuleInfos->end(); ++currSearchPath)
426 if (! hasCurrModuleKey)
428 currModuleKey = currSearchPath->second.begin();
429 hasCurrModuleKey =
true;
432 bool isOverriddenCompiledModuleCachePath = ! overriddenCompiledModuleCachePath.empty() &&
435 for ( ; currModuleKey != currSearchPath->second.end(); ++currModuleKey)
437 if ((! hasSearchModuleKeys || searchModuleKeys.find(currModuleKey->first) != searchModuleKeys.end()) &&
438 (isOverriddenCompiledModuleCachePath || overriddenModuleKeys.find(currModuleKey->first) == overriddenModuleKeys.end()))
440 ModuleInfo *moduleInfo = currModuleKey->second;
446 hasCurrModuleKey =
false;
455 VuoCompiler::Environment::Environment(
string target,
bool builtIn,
bool generated)
456 : target(target), builtIn(builtIn), generated(generated)
458 compilersToNotifyQueue = dispatch_queue_create(
"org.vuo.compiler.notify", 0);
459 moduleSearchPathContentsChangedQueue = dispatch_queue_create(
"org.vuo.compiler.watch", 0);
460 lastModuleCacheRebuild = 0;
461 isModuleCacheableDataDirty =
false;
462 isModuleCacheInitialized =
false;
463 isModuleCacheAvailable =
false;
472 VuoCompiler::Environment::~Environment(
void)
474 stopWatchingModuleSearchPaths();
475 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{});
477 dispatch_release(moduleSearchPathContentsChangedQueue);
478 dispatch_release(compilersToNotifyQueue);
480 for (map<string, VuoCompilerNodeClass *>::iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
481 destroyModule(i->second);
483 for (map<string, VuoCompilerType *>::iterator i = types.begin(); i != types.end(); ++i)
484 destroyModule(i->second);
486 for (map<string, VuoCompilerModule *>::iterator i = libraryModules.begin(); i != libraryModules.end(); ++i)
487 destroyModule(i->second);
489 for (set<VuoCompilerGenericType *>::iterator i = genericTypes.begin(); i != genericTypes.end(); ++i)
491 VuoType *base = (*i)->getBase();
496 for (map<string, VuoNodeSet *>::iterator i = nodeSetForName.begin(); i != nodeSetForName.end(); ++i)
499 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
500 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
503 for (map<
string, map<string, ModuleInfo *> >::iterator i = sourceFilesAtSearchPath.begin(); i != sourceFilesAtSearchPath.end(); ++i)
504 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
507 delete dependencyGraph;
508 delete compositionDependencyGraph;
514 string VuoCompiler::Environment::getTarget()
522 void VuoCompiler::Environment::addCompilerToNotify(
VuoCompiler *compiler)
524 dispatch_sync(compilersToNotifyQueue, ^{
525 compilersToNotify.insert(compiler);
532 void VuoCompiler::Environment::removeCompilerToNotify(
VuoCompiler *compiler)
534 dispatch_sync(compilersToNotifyQueue, ^{
535 compilersToNotify.erase(compiler);
544 map<string, VuoCompilerNodeClass *> VuoCompiler::Environment::getNodeClasses(
void)
556 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
557 if (nodeClassIter != nodeClasses.end())
558 return nodeClassIter->second;
571 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
572 if (nodeClassIter != nodeClasses.end())
574 nodeClass = nodeClassIter->second;
576 nodeClasses.erase(nodeClassIter);
577 removeFromDependencyGraph(nodeClass);
589 map<string, VuoCompilerType *> VuoCompiler::Environment::getTypes(
void)
599 VuoCompilerType * VuoCompiler::Environment::getType(
const string &moduleKey)
601 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
602 if (typeIter != types.end())
603 return typeIter->second;
613 map<string, VuoNodeSet *> VuoCompiler::Environment::getNodeSets(
void)
615 return nodeSetForName;
623 VuoCompilerModule *VuoCompiler::Environment::getLibraryModule(
const string &libraryModuleName)
625 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(libraryModuleName);
626 if (libraryIter != libraryModules.end())
627 return libraryIter->second;
637 map<string, VuoCompilerModule *> VuoCompiler::Environment::getLibraryModules(
void)
639 return libraryModules;
648 VuoCompilerModule * VuoCompiler::Environment::findModule(
const string &moduleKey)
650 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
651 if (nodeClassIter != nodeClasses.end())
652 return nodeClassIter->second;
654 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
655 if (typeIter != types.end())
656 return typeIter->second;
658 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(moduleKey);
659 if (libraryIter != libraryModules.end())
660 return libraryIter->second;
670 VuoNodeSet * VuoCompiler::Environment::findNodeSet(
const string &name)
673 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(name);
674 if (nodeSetIter != nodeSetForName.end())
675 return nodeSetIter->second;
686 void VuoCompiler::Environment::addModuleSearchPath(
const string &path,
bool shouldWatch)
688 moduleSearchPaths.push_back(path);
690 updateModulesAtSearchPath(path);
691 updateSourceFilesAtSearchPath(path);
694 startWatchingModuleSearchPath(path);
702 vector<string> VuoCompiler::Environment::getModuleSearchPaths(
void)
704 return moduleSearchPaths;
712 void VuoCompiler::Environment::addHeaderSearchPath(
const string &path)
714 headerSearchPaths.push_back(path);
722 vector<string> VuoCompiler::Environment::getHeaderSearchPaths(
void)
724 return headerSearchPaths;
732 void VuoCompiler::Environment::addLibrarySearchPath(
const string &path)
734 librarySearchPaths.push_back(path);
742 vector<string> VuoCompiler::Environment::getLibrarySearchPaths(
void)
744 return librarySearchPaths;
752 void VuoCompiler::Environment::addFrameworkSearchPath(
const string &path)
754 frameworkSearchPaths.push_back(path);
762 vector<string> VuoCompiler::Environment::getFrameworkSearchPaths(
void)
764 return frameworkSearchPaths;
769 return dependencyGraph;
774 return compositionDependencyGraph;
782 void VuoCompiler::Environment::setModuleCachePath(
const string &path,
bool shouldAddModuleSearchPath)
784 moduleCachePath = path;
786 if (shouldAddModuleSearchPath)
788 addModuleSearchPath(getCompiledModuleCachePath(),
false);
789 addModuleSearchPath(getOverriddenCompiledModuleCachePath(),
false);
798 string VuoCompiler::Environment::getCompiledModuleCachePath(
void)
800 return (moduleCachePath.empty() ?
"" : moduleCachePath +
"/Modules/" + VuoCompiler::getTargetArch(target));
808 string VuoCompiler::Environment::getOverriddenCompiledModuleCachePath(
void)
810 if (moduleCachePath.empty())
816 string dir, moduleCacheDirName, ext;
819 return (
VuoFileUtilities::getCachePath() +
"/" + pidCacheDirPrefix + pid.str() +
"/" + moduleCacheDirName +
"/Modules/" + VuoCompiler::getTargetArch(target));
829 void VuoCompiler::Environment::addExpatriateSourceFile(
const string &sourcePath)
831 expatriateSourceFiles.push_back(sourcePath);
833 if (find(moduleSearchPaths.begin(), moduleSearchPaths.end(),
"") == moduleSearchPaths.end())
834 moduleSearchPaths.push_back(
"");
836 auto iter = sourceFilesAtSearchPath.find(
"");
837 if (iter != sourceFilesAtSearchPath.end())
838 sourceFilesAtSearchPath.erase(iter);
846 void VuoCompiler::Environment::removeExpatriateSourceFile(
const string &sourcePath)
848 for (
auto i = expatriateSourceFiles.begin(); i != expatriateSourceFiles.end(); ++i)
852 expatriateSourceFiles.erase(i);
854 auto iter = sourceFilesAtSearchPath.find(
"");
855 if (iter != sourceFilesAtSearchPath.end())
856 sourceFilesAtSearchPath.erase(iter);
875 void VuoCompiler::Environment::updateModulesAtSearchPath(
const string &path)
877 if (moduleFilesAtSearchPath.find(path) != moduleFilesAtSearchPath.end())
880 set<string> moduleExtensions;
881 moduleExtensions.insert(
"vuonode");
882 moduleExtensions.insert(
"vuonode+");
883 moduleExtensions.insert(
"bc");
884 moduleExtensions.insert(
"bc+");
885 set<string> archiveExtensions;
886 archiveExtensions.insert(
"vuonode");
889 map<string, ModuleInfo *> fileForModuleKey;
890 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
898 ModuleInfo *m =
new ModuleInfo(
this, path, moduleFile,
false,
false);
899 fileForModuleKey[m->getModuleKey()] = m;
902 if (path == getCompiledModuleCachePath())
904 for (map<string, ModuleInfo *>::iterator i = fileForModuleKey.begin(); i != fileForModuleKey.end(); )
906 ModuleInfo *sourceInfo = listSourceFile(i->first);
907 if (! sourceInfo || sourceInfo->isNewerThan(i->second))
909 ModuleInfo *m = i->second;
912 fileForModuleKey.erase(i++);
919 moduleFilesAtSearchPath[path] = fileForModuleKey;
927 void VuoCompiler::Environment::updateModuleAtSearchPath(
const string &moduleSearchPath,
const string &moduleRelativePath)
929 string dir, file, ext;
932 set<string> moduleExtensions;
933 moduleExtensions.insert(ext);
934 set<string> archiveExtensions;
935 archiveExtensions.insert(
"vuonode");
939 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
943 ModuleInfo *m =
new ModuleInfo(
this, moduleSearchPath, moduleFile,
false,
false);
944 moduleFilesAtSearchPath[moduleSearchPath][m->getModuleKey()] = m;
955 void VuoCompiler::Environment::updateSourceFilesAtSearchPath(
const string &path)
957 map<string, map<string, ModuleInfo *> >::iterator sourceFilesIter = sourceFilesAtSearchPath.find(path);
958 if (sourceFilesIter != sourceFilesAtSearchPath.end())
961 set<VuoFileUtilities::File *> sourceFiles;
964 set<string> sourceExtensions;
965 sourceExtensions.insert(
"vuo");
966 sourceExtensions.insert(
"fs");
968 sourceExtensions.insert(cext.begin(), cext.end());
973 for (
const string &sourcePath : expatriateSourceFiles)
975 string dir, file, ext;
978 sourceFiles.insert(sourceFile);
982 map<string, ModuleInfo *> fileForModuleKey;
983 for (set<VuoFileUtilities::File *>::iterator i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
987 string dir, moduleKey, ext;
989 bool isSubcomposition = (ext ==
"vuo");
992 if (path.empty() && !sourceFile->
exists())
995 ModuleInfo *m =
new ModuleInfo(
this, path, sourceFile,
true, isSubcomposition);
996 if (fileForModuleKey.find(m->getModuleKey()) != fileForModuleKey.end())
997 VUserLog(
"Warning: Conflicting source files for module %s are installed at %s", m->getModuleKey().c_str(), path.c_str());
998 fileForModuleKey[m->getModuleKey()] = m;
1000 if (isSubcomposition)
1002 DependencyGraphVertex *compositionVertex = DependencyGraphVertex::vertexForDependency(moduleKey, compositionDependencyGraph);
1003 compositionDependencyGraph->addVertex(compositionVertex);
1005 compositionVertex->setEnvironment(
this);
1007 set<string> dependencies = m->getContainedNodeClasses();
1008 for (set<string>::iterator j = dependencies.begin(); j != dependencies.end(); ++j)
1010 DependencyGraphVertex *dependencyVertex = DependencyGraphVertex::vertexForDependency(*j, compositionDependencyGraph);
1011 compositionDependencyGraph->addEdge(compositionVertex, dependencyVertex);
1016 sourceFilesAtSearchPath[path] = fileForModuleKey;
1024 VuoCompiler::ModuleInfo * VuoCompiler::Environment::listModule(
const string &moduleKey)
1026 for (
const auto &moduleFiles : moduleFilesAtSearchPath)
1028 map<string, ModuleInfo *>::const_iterator foundIter = moduleFiles.second.find(moduleKey);
1029 if (foundIter != moduleFiles.second.end())
1030 return foundIter->second;
1041 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listModules(
const set<string> &moduleKeys)
1043 for (
const string &path : moduleSearchPaths)
1044 updateModulesAtSearchPath(path);
1046 return ModuleInfoIterator(&moduleFilesAtSearchPath, getOverriddenCompiledModuleCachePath(), moduleKeys);
1054 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllModules(
void)
1056 for (
const string &path : moduleSearchPaths)
1057 updateModulesAtSearchPath(path);
1059 return ModuleInfoIterator(&moduleFilesAtSearchPath, getOverriddenCompiledModuleCachePath());
1067 VuoCompiler::ModuleInfo * VuoCompiler::Environment::listSourceFile(
const string &moduleKey)
1069 for (
const auto &sourceFiles : sourceFilesAtSearchPath)
1071 map<string, ModuleInfo *>::const_iterator foundIter = sourceFiles.second.find(moduleKey);
1072 if (foundIter != sourceFiles.second.end())
1073 return foundIter->second;
1084 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listSourceFiles(
const set<string> &moduleKeys)
1086 for (
const string &path : moduleSearchPaths)
1087 updateSourceFilesAtSearchPath(path);
1089 return ModuleInfoIterator(&sourceFilesAtSearchPath,
"", moduleKeys);
1097 VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllSourceFiles(
void)
1099 for (
const string &path : moduleSearchPaths)
1100 updateSourceFilesAtSearchPath(path);
1102 return ModuleInfoIterator(&sourceFilesAtSearchPath,
"");
1108 vector<string> VuoCompiler::Environment::getBuiltInModuleSearchPaths(
void)
1110 vector<string> builtInModuleSearchPaths;
1112 string vuoFrameworkPath = getVuoFrameworkPath();
1113 if (! vuoFrameworkPath.empty())
1115 builtInModuleSearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1119 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/library");
1120 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/node");
1121 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type");
1122 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1125 return builtInModuleSearchPaths;
1131 vector<string> VuoCompiler::Environment::getBuiltInHeaderSearchPaths(
void)
1133 vector<string> builtInHeaderSearchPaths;
1135 string vuoFrameworkPath = getVuoFrameworkPath();
1136 if (! vuoFrameworkPath.empty())
1138 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers");
1139 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos");
1140 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos/pthread");
1141 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/Headers/lib/c++/v1");
1145 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/library");
1146 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/node");
1147 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type");
1148 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type/list");
1149 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/runtime");
1150 builtInHeaderSearchPaths.push_back(JSONC_ROOT
"/include");
1151 builtInHeaderSearchPaths.push_back(LLVM_ROOT
"/include/c++/v1");
1154 return builtInHeaderSearchPaths;
1160 vector<string> VuoCompiler::Environment::getBuiltInLibrarySearchPaths(
void)
1162 vector<string> builtInLibrarySearchPaths;
1164 string vuoFrameworkPath = getVuoFrameworkPath();
1165 if (! vuoFrameworkPath.empty())
1167 builtInLibrarySearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1170 builtInLibrarySearchPaths.push_back(OPENSSL_ROOT
"/lib");
1174 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/library");
1175 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/node");
1176 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type");
1177 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1178 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/runtime");
1181 builtInLibrarySearchPaths.insert(builtInLibrarySearchPaths.end(), conanLibDirs.begin(), conanLibDirs.end());
1184 return builtInLibrarySearchPaths;
1190 vector<string> VuoCompiler::Environment::getBuiltInFrameworkSearchPaths(
void)
1192 vector<string> builtInFrameworkSearchPaths;
1194 string vuoFrameworkPath = getVuoFrameworkPath();
1195 if (! vuoFrameworkPath.empty())
1197 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Modules/");
1198 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/");
1201 return builtInFrameworkSearchPaths;
1210 void VuoCompiler::Environment::startWatchingModuleSearchPath(
const string &moduleSearchPath)
1213 moduleSearchPathWatchers.insert(watcher);
1221 void VuoCompiler::Environment::stopWatchingModuleSearchPaths(
void)
1223 for (set<VuoFileWatcher *>::iterator i = moduleSearchPathWatchers.begin(); i != moduleSearchPathWatchers.end(); ++i)
1226 moduleSearchPathWatchers.clear();
1233 void VuoCompiler::Environment::fileChanged(
const string &moduleSearchPath)
1235 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{
1236 moduleSearchPathContentsChanged(moduleSearchPath);
1247 void VuoCompiler::Environment::moduleSearchPathContentsChanged(
const string &moduleSearchPath)
1252 __block set<string> modulesAdded;
1253 __block set<string> modulesModifed;
1254 __block set<string> modulesRemoved;
1255 __block set<string> compositionsAdded;
1256 __block set<string> compositionsModifed;
1257 __block set<string> compositionsRemoved;
1259 dispatch_sync(environmentQueue, ^{
1263 map<string, ModuleInfo *> oldModules;
1264 map<string, ModuleInfo *> oldCompositions;
1266 map<string, map<string, ModuleInfo *> >::iterator mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1267 if (mf != moduleFilesAtSearchPath.end())
1269 for (map<string, ModuleInfo *>::iterator j = mf->second.begin(); j != mf->second.end(); ++j)
1271 oldModules[j->first] = j->second;
1274 moduleFilesAtSearchPath.erase(mf);
1277 map<string, map<string, ModuleInfo *> >::iterator cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1278 if (cf != sourceFilesAtSearchPath.end())
1280 for (map<string, ModuleInfo *>::iterator j = cf->second.begin(); j != cf->second.end(); ++j)
1282 oldCompositions[j->first] = j->second;
1284 VuoDirectedAcyclicGraph::Vertex *vertex = compositionDependencyGraph->findVertex(j->first);
1285 compositionDependencyGraph->removeVertex(vertex);
1288 sourceFilesAtSearchPath.erase(cf);
1293 updateModulesAtSearchPath(moduleSearchPath);
1294 updateSourceFilesAtSearchPath(moduleSearchPath);
1298 auto omf = moduleFilesAtSearchPath.find(getOverriddenCompiledModuleCachePath());
1299 if (omf != moduleFilesAtSearchPath.end())
1301 for (
auto oldComposition : oldCompositions)
1303 for (
auto i = omf->second.begin(); i != omf->second.end(); ++i)
1305 if (i->first == oldComposition.first)
1308 omf->second.erase(i);
1317 mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1318 if (mf != moduleFilesAtSearchPath.end())
1320 for (map<string, ModuleInfo *>::iterator n = mf->second.begin(); n != mf->second.end(); ++n)
1322 string moduleKey = n->first;
1324 map<string, ModuleInfo *>::iterator o = oldModules.find(moduleKey);
1325 if (o != oldModules.end())
1327 if (n->second->isNewerThan(o->second))
1329 modulesModifed.insert(moduleKey);
1333 n->second->setAttempted(o->second->getAttempted());
1337 oldModules.erase(o);
1341 modulesAdded.insert(moduleKey);
1346 cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1347 if (cf != sourceFilesAtSearchPath.end())
1349 for (map<string, ModuleInfo *>::iterator n = cf->second.begin(); n != cf->second.end(); ++n)
1351 string moduleKey = n->first;
1353 map<string, ModuleInfo *>::iterator o = oldCompositions.find(moduleKey);
1354 if (o != oldCompositions.end())
1356 if (n->second->isNewerThan(o->second))
1358 compositionsModifed.insert(moduleKey);
1362 n->second->setAttempted(o->second->getAttempted());
1363 n->second->setSourceCode(o->second->getSourceCode());
1367 oldCompositions.erase(o);
1371 compositionsAdded.insert(moduleKey);
1376 for (map<string, ModuleInfo *>::iterator o = oldModules.begin(); o != oldModules.end(); ++o)
1379 modulesRemoved.insert(o->first);
1382 for (map<string, ModuleInfo *>::iterator o = oldCompositions.begin(); o != oldCompositions.end(); ++o)
1385 compositionsRemoved.insert(o->first);
1388 compilerForLoading->loadModulesAndSources(modulesAdded, modulesModifed, modulesRemoved,
1389 compositionsAdded, compositionsModifed, compositionsRemoved,
1390 false,
false,
this,
nullptr,
nullptr,
"");
1393 delete compilerForLoading;
1402 void VuoCompiler::Environment::moduleFileChanged(
const string &modulePath,
const string &moduleSourceCode,
1403 std::function<
void(
void)> moduleLoadedCallback,
1407 dispatch_sync(environmentQueue, ^{
1409 string moduleDir, moduleKey, ext;
1415 bool foundOldModule =
false;
1416 auto moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1417 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1419 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1420 if (moduleIter != moduleSearchPathIter->second.end())
1422 delete moduleIter->second;
1423 moduleSearchPathIter->second.erase(moduleIter);
1424 foundOldModule =
true;
1430 updateModuleAtSearchPath(moduleDir, moduleKey +
"." + ext);
1434 bool foundNewModule =
false;
1435 moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1436 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1438 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1439 if (moduleIter != moduleSearchPathIter->second.end())
1441 foundNewModule =
true;
1445 set<string> modulesAdded;
1446 set<string> modulesModified;
1447 set<string> modulesRemoved;
1451 modulesModified.insert(moduleKey);
1453 else if (! foundOldModule && foundNewModule)
1455 modulesAdded.insert(moduleKey);
1457 else if (foundOldModule && ! foundNewModule)
1459 modulesRemoved.insert(moduleKey);
1462 compiler->loadModulesAndSources(modulesAdded, modulesModified, modulesRemoved,
1463 set<string>(), set<string>(), set<string>(),
1464 false,
false,
this, issues, moduleLoadedCallback, moduleSourceCode);
1472 void VuoCompiler::Environment::notifyCompilers(
const set<VuoCompilerModule *> &modulesAdded,
1473 const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
1475 bool oldModulesInvalidated)
1477 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()) )
1479 set< pair<VuoCompilerModule *, VuoCompilerModule *> > invalidatedModulesModified;
1480 set<VuoCompilerModule *> invalidatedModulesRemoved;
1481 if (oldModulesInvalidated)
1483 invalidatedModulesModified = modulesModified;
1484 invalidatedModulesRemoved = modulesRemoved;
1487 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(invalidatedModulesModified, invalidatedModulesRemoved, issues);
1489 map<string, VuoCompilerModule *> modulesAddedMap;
1490 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModifiedMap;
1491 map<string, VuoCompilerModule *> modulesRemovedMap;
1493 modulesAddedMap[m->getPseudoBase()->getModuleKey()] = m;
1494 for (pair<VuoCompilerModule *, VuoCompilerModule *> m : modulesModified)
1495 modulesModifiedMap[m.first->getPseudoBase()->getModuleKey()] = m;
1497 modulesRemovedMap[m->getPseudoBase()->getModuleKey()] = m;
1499 dispatch_sync(compilersToNotifyQueue, ^{
1500 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1501 delegateData->retain();
1503 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1504 (*i)->loadedModules(modulesAddedMap, modulesModifiedMap, modulesRemovedMap, issues, delegateData, this);
1524 set<VuoCompilerModule *> VuoCompiler::Environment::loadCompiledModules(
const set<string> &moduleKeys,
const map<string, string> &sourceCodeForModule)
1526 ModuleInfoIterator modulesToLoadIter = listModules(moduleKeys);
1527 set<VuoCompilerModule *> modulesLoaded;
1529 ModuleInfo *moduleInfo;
1530 while ((moduleInfo = modulesToLoadIter.next()))
1532 string moduleKey = moduleInfo->getModuleKey();
1536 if (moduleInfo->getEnvironment() !=
this || findModule(moduleKey) || moduleInfo->getAttempted())
1539 moduleInfo->setAttempted(
true);
1546 modulesLoaded.insert(module);
1547 addToDependencyGraph(module);
1551 string searchPath = moduleInfo->getSearchPath();
1558 ModuleInfo *sourceInfo = listSourceFile(moduleKey);
1562 auto sourceCodeIter = sourceCodeForModule.find(moduleKey);
1563 if (sourceCodeIter != sourceCodeForModule.end())
1570 return modulesLoaded;
1584 set<dispatch_group_t> VuoCompiler::Environment::loadSpecializedModules(
const set<string> &moduleKeys,
1587 set<dispatch_group_t > loadingGroups;
1589 for (
string moduleKey : moduleKeys)
1598 if (findModule(moduleKey))
1603 map<string, dispatch_group_t>::iterator iter = specializedModulesLoading.find(moduleKey);
1604 if (iter != specializedModulesLoading.end())
1606 loadingGroups.insert(iter->second);
1607 dispatch_retain(iter->second);
1611 dispatch_group_t loadingGroup = dispatch_group_create();
1612 specializedModulesLoading[moduleKey] = loadingGroup;
1613 loadingGroups.insert(loadingGroup);
1619 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1620 dispatch_group_async(loadingGroup, queue, ^{
1634 compiler->loadNodeClassGeneratedAtRuntime(specNodeClass,
this);
1637 if (!dependencies.empty())
1638 compiler->loadModulesIfNeeded(dependencies);
1641 dispatch_sync(environmentQueue, ^{
1642 specializedModulesLoading.erase(moduleKey);
1647 return loadingGroups;
1662 set<dispatch_group_t> VuoCompiler::Environment::compileModulesFromSourceCode(
const set<string> &moduleKeys,
bool shouldRecompileIfUnchanged)
1664 ModuleInfoIterator modulesToLoadIter = listSourceFiles(moduleKeys);
1666 int environmentIndex = sharedEnvironments[target].size();
1667 for (
int i = 0; i < sharedEnvironments[target].size(); ++i)
1668 if (
this == sharedEnvironments[target].at(i).at(0))
1669 environmentIndex = i;
1671 set<dispatch_group_t> sourcesLoading;
1672 int sourcesEnqueued = 0;
1673 ModuleInfo *sourceInfo;
1674 while ((sourceInfo = modulesToLoadIter.next()))
1676 string moduleKey = sourceInfo->getModuleKey();
1678 dispatch_group_t loadingGroup = sourceInfo->getLoadingGroup();
1679 sourcesLoading.insert(loadingGroup);
1684 if (sourceInfo->getAttempted())
1689 string sourceCode = sourceInfo->getSourceCode();
1691 if (! shouldRecompileIfUnchanged)
1694 if (existingNodeClass && existingNodeClass->
getSourceCode() == sourceCode)
1700 sourceInfo->setAttempted(
true);
1702 dispatch_group_enter(loadingGroup);
1703 dispatch_group_enter(moduleSourceCompilersExistGlobally);
1707 queueItem->
sourcePath = sourceInfo->getFile()->path();
1709 queueItem->
sourceFile = sourceInfo->getFile();
1710 queueItem->
cachedModulesPath = sourceInfo->isSourceCodeOverridden() ? getOverriddenCompiledModuleCachePath() : getCompiledModuleCachePath();
1713 queueItem->
priority = { environmentIndex, sourceInfo->getLongestDownstreamPath() };
1714 moduleCompilationQueue->enqueue(queueItem);
1723 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1724 dispatch_async(queue, ^{
1725 for (
int i = 0; i < sourcesEnqueued; ++i)
1728 VUserLog(
"Compiling %s", queueItem->moduleKey.c_str());
1730 dispatch_async(queue, ^{
1739 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1746 auto moduleLoadedCallback = [=](){
1747 dispatch_group_leave(queueItemForCallback->
loadingGroup);
1748 moduleCompilationQueue->completed(queueItemForCallback);
1751 string ext = queueItem->sourceFile->extension();
1762 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1769 auto getType = [&compiler] (
const string &moduleKey) {
return compiler->
getType(moduleKey); };
1776 setTargetForModule(module, target);
1777 writeModuleToBitcode(module, queueItem->compiledModulePath);
1785 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1788 moduleLoadedCallback();
1796 compiler->
compileModule(queueItem->sourcePath, queueItem->compiledModulePath, vector<string>());
1806 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1816 Module *module = compiler->compileCompositionToModule(composition, queueItem->moduleKey,
false, issues);
1821 setTargetForModule(module, target);
1822 writeModuleToBitcode(module, queueItem->compiledModulePath);
1827 delete baseComposition;
1837 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1841 dispatch_group_leave(moduleSourceCompilersExistGlobally);
1846 return sourcesLoading;
1857 set<VuoCompilerModule *> VuoCompiler::Environment::unloadCompiledModules(
const set<string> &moduleKeys)
1859 set<VuoCompilerModule *> modulesUnloaded;
1861 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1863 string moduleKey = *i;
1866 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
1867 if (nodeClassIter != nodeClasses.end())
1869 module = nodeClassIter->second;
1870 nodeClasses.erase(nodeClassIter);
1874 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
1875 if (typeIter != types.end())
1877 module = typeIter->second;
1878 types.erase(typeIter);
1882 map<string, VuoCompilerModule *>::iterator libraryModuleIter = libraryModules.find(moduleKey);
1883 if (libraryModuleIter != libraryModules.end())
1885 module = libraryModuleIter->second;
1886 libraryModules.erase(libraryModuleIter);
1893 modulesUnloaded.insert(module);
1894 removeFromDependencyGraph(module);
1899 return modulesUnloaded;
1907 void VuoCompiler::Environment::deleteModulesCompiledFromSourceCode(
const set<string> &moduleKeys)
1909 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1911 string moduleKey = *i;
1913 map<string, ModuleInfo *>::iterator iter = moduleFilesAtSearchPath[getCompiledModuleCachePath()].find(moduleKey);
1914 if (iter != moduleFilesAtSearchPath[getCompiledModuleCachePath()].end())
1926 VuoCompilerModule * VuoCompiler::Environment::loadModule(ModuleInfo *moduleInfo)
1928 string moduleKey = moduleInfo->getModuleKey();
1942 __block
size_t inputDataBytes;
1943 __block
char *rawInputData;
1947 rawInputData = moduleInfo->getFile()->getContentsAsRawData(inputDataBytes);
1951 rawInputData = NULL;
1952 VUserLog(
"Warning: Couldn't load module '%s'. Its file may have been deleted. (%s)", moduleKey.c_str(), e.
what());
1958 char *processedInputData;
1960 processedInputData = loadModule_Pro0(moduleInfo, moduleKey, inputDataBytes, rawInputData);
1962 processedInputData = rawInputData;
1965 Module *module = NULL;
1966 set<string> moduleArchs;
1967 bool moduleParseError = !processedInputData;
1968 if (!moduleParseError)
1970 string moduleReadError;
1971 string arch = VuoCompiler::getTargetArch(target);
1972 VuoLog_status(
"Loading module \"%s\" (%s)", moduleKey.c_str(), arch.c_str());
1973 module = readModuleFromBitcodeData(processedInputData, inputDataBytes, arch, moduleArchs, moduleReadError);
1975 free(processedInputData);
1979 moduleParseError =
true;
1984 VUserLog(
"Error: Couldn't load module '%s' into %s environment: %s.", moduleKey.c_str(), arch.c_str(), moduleReadError.c_str());
1988 if (!moduleParseError)
1991 if (! moduleInfo->getFile()->isInArchive())
1992 modulePath = moduleInfo->getFile()->path();
2010 libraryModules[moduleKey] = compilerModule;
2015 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(nodeSet->
getName());
2016 if (nodeSetIter == nodeSetForName.end())
2018 nodeSetForName[nodeSet->
getName()] = nodeSet;
2023 nodeSet = nodeSetIter->second;
2025 compilerModule->getPseudoBase()->setNodeSet(nodeSet);
2029 loadModule_Pro1(rawInputData, processedInputData, compilerModule);
2032 compilerModule->setBuiltIn( isBuiltInOriginal() );
2034 return compilerModule;
2038 destroyLlvmModule(module);
2057 removeFromDependencyGraph(oldNodeClass);
2058 destroyModule(oldNodeClass);
2061 nodeClasses[moduleKey] = newNodeClass;
2062 addToDependencyGraph(newNodeClass);
2068 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
2069 dependencyGraph->addVertex(vertex);
2071 vertex->setEnvironment(
this);
2074 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
2076 DependencyGraphVertex *depVertex = DependencyGraphVertex::vertexForDependency(*i, dependencyGraph);
2077 dependencyGraph->addEdge(vertex, depVertex);
2081 void VuoCompiler::Environment::removeFromDependencyGraph(
VuoCompilerModule *module)
2083 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
2084 dependencyGraph->removeVertex(vertex);
2097 void VuoCompiler::Environment::reifyPortTypes(
const map<string, VuoCompilerType *> &inheritedTypes)
2099 map<string, VuoCompilerType *> availableTypes = inheritedTypes;
2100 availableTypes.insert(types.begin(), types.end());
2102 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
2108 vector<VuoPortClass *> portClasses;
2109 portClasses.insert(portClasses.end(), inputPortClasses.begin(), inputPortClasses.end());
2110 portClasses.insert(portClasses.end(), outputPortClasses.begin(), outputPortClasses.end());
2112 for (vector<VuoPortClass *>::iterator j = portClasses.begin(); j != portClasses.end(); ++j)
2132 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2133 if (reifiedTypeIter != availableTypes.end())
2136 reifiedType = reifiedTypeIter->second;
2147 for (vector<VuoCompilerTriggerDescription *>::iterator j = triggers.begin(); j != triggers.end(); ++j)
2155 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2156 if (reifiedTypeIter != availableTypes.end())
2177 void VuoCompiler::Environment::getCacheableModulesAndDependencies(set<string> &cacheableModulesAndDependencies,
2178 set<string> &dylibsNeededToLinkToThisCache,
2179 set<string> &frameworksNeededToLinkToThisCache)
2181 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty)
2183 cacheableModulesAndDependencies = moduleCacheContents;
2184 dylibsNeededToLinkToThisCache = moduleCacheDylibs;
2185 frameworksNeededToLinkToThisCache = moduleCacheFrameworks;
2192 map<string, VuoCompilerModule *> allModules;
2193 allModules.insert(nodeClasses.begin(), nodeClasses.end());
2194 allModules.insert(types.begin(), types.end());
2195 allModules.insert(libraryModules.begin(), libraryModules.end());
2197 set<string> dependencies;
2198 for (map<string, VuoCompilerModule *>::iterator i = allModules.begin(); i != allModules.end(); ++i)
2200 string moduleKey = i->first;
2205 if (module->requiresPro())
2213 cacheableModulesAndDependencies.insert(moduleKey);
2216 dependencies.insert(moduleDependencies.begin(), moduleDependencies.end());
2220 if (builtIn && ! generated)
2222 vector<string> coreDependencies = getCoreVuoDependencies();
2223 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
2228 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
2230 string dependency = *i;
2231 if (allModules.find(dependency) == allModules.end())
2234 frameworksNeededToLinkToThisCache.insert(dependency);
2237 string dependencyPath = VuoCompiler::getLibraryPath(dependency, librarySearchPaths);
2238 if (! dependencyPath.empty())
2241 dylibsNeededToLinkToThisCache.insert(dependencyPath);
2243 cacheableModulesAndDependencies.insert(dependency);
2249 moduleCacheDylibs = dylibsNeededToLinkToThisCache;
2250 moduleCacheFrameworks = frameworksNeededToLinkToThisCache;
2257 if (!vuoFrameworkInProgressPath.empty())
2258 currentModuleCacheDylib +=
"-" + VuoCompiler::getTargetArch(target);
2282 void VuoCompiler::Environment::useModuleCache(
bool shouldUseExistingCache,
VuoCompiler *compiler,
2283 set<string> cacheableModulesAndDependencies,
2284 set<string> dylibsNeededToLinkToCaches, set<string> frameworksNeededToLinkToCaches,
2285 unsigned long lastPrerequisiteModuleCacheRebuild)
2289 static dispatch_once_t checked = 0;
2290 static bool prelinkCache =
true;
2291 dispatch_once(&checked, ^{
2293 bool result = CFPreferencesGetAppBooleanValue(CFSTR(
"prelinkCache"), CFSTR(
"org.vuo.Editor"), &valid);
2295 prelinkCache = result;
2299 VDebugLog(
"Ignoring the module cache since the 'prelinkCache' preference is false.");
2305 if (moduleCachePath.empty())
2311 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty &&
2312 (builtIn || lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild))
2314 VDebugLog(
"No need to recheck %s.", cacheDescription.c_str());
2320 VDebugLog(
"Checking if %s is up-to-date…", cacheDescription.c_str());
2322 bool isCacheUpToDate =
true;
2324 if (isModuleCacheInitialized && isModuleCacheableDataDirty)
2325 isCacheUpToDate =
false;
2327 isModuleCacheInitialized =
true;
2328 isModuleCacheableDataDirty =
false;
2331 if (!vuoFrameworkInProgressPath.empty())
2332 indexPath +=
"-" + VuoCompiler::getTargetArch(target);
2333 string dir, file, ext;
2335 string indexFileName = file +
"." + ext;
2342 if (shouldUseExistingCache)
2343 throw VuoException(
"Trying to use the existing cache, but the cache directory doesn't exist.",
false);
2346 isCacheUpToDate =
false;
2350 if (! indexFileExists)
2352 if (shouldUseExistingCache)
2353 throw VuoException(
"Trying to use the existing cache, but the cache index doesn't exist.",
false);
2356 isCacheUpToDate =
false;
2363 fileForLocking = moduleCacheFileForLocking[indexPath];
2364 if (! fileForLocking)
2367 moduleCacheFileForLocking[indexPath] = fileForLocking;
2371 VDebugLog(
"\tWarning: Couldn't lock for reading.");
2376 if (currentModuleCacheDylib.empty())
2379 if (shouldUseExistingCache && currentModuleCacheDylib.empty())
2380 throw VuoException(
"Trying to use the existing cache, but the cache dylib doesn't exist.",
false);
2384 if (isCacheUpToDate)
2385 isCacheUpToDate = lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild;
2389 if (isCacheUpToDate)
2394 if (shouldUseExistingCache)
2395 throw VuoException(
"Trying to use the existing cache, but the cache doesn't contain readable data.",
false);
2397 isCacheUpToDate =
false;
2403 const char separator =
'\n';
2404 if (isCacheUpToDate || shouldUseExistingCache)
2407 string index = indexFile.getContentsAsString();
2410 moduleCacheContents.clear();
2411 moduleCacheContents.insert(actualIndex.begin(), actualIndex.end());
2413 if (shouldUseExistingCache)
2415 isModuleCacheAvailable =
true;
2422 if (isCacheUpToDate)
2424 if (moduleCacheContents.size() != cacheableModulesAndDependencies.size())
2425 isCacheUpToDate =
false;
2428 set<string> contentsInBoth;
2429 std::set_intersection(moduleCacheContents.begin(), moduleCacheContents.end(),
2430 cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end(),
2431 std::inserter(contentsInBoth, contentsInBoth.begin()));
2433 if (contentsInBoth.size() != cacheableModulesAndDependencies.size())
2434 isCacheUpToDate =
false;
2440 if (isCacheUpToDate)
2444 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
2446 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2448 if (! j->second->isOlderThan(cacheLastModified))
2450 isCacheUpToDate =
false;
2459 if (isCacheUpToDate)
2463 isModuleCacheAvailable =
true;
2474 gettimeofday(&t, NULL);
2475 lastModuleCacheRebuild = t.tv_sec;
2478 dispatch_async(moduleCacheBuildingQueue, ^{
2479 VDebugLog(
"Rebuilding %s…", cacheDescription.c_str());
2481 set<Module *> modulesToLink;
2482 set<string> librariesToLink;
2483 set<string> frameworksToLink;
2485 compiler->getLinkerInputs(cacheableModulesAndDependencies, Optimization_SmallBinary, modulesToLink, librariesToLink, frameworksToLink);
2487 librariesToLink.insert(dylibsNeededToLinkToCaches.begin(), dylibsNeededToLinkToCaches.end());
2488 frameworksToLink.insert(frameworksNeededToLinkToCaches.begin(), frameworksNeededToLinkToCaches.end());
2491 bool gotLockForWriting =
false;
2496 if (! gotLockForWriting)
2497 throw VuoException(
"The cache file is being used by another process. "
2498 "If any composition windows are open from previous Vuo sessions, quit them. "
2499 "If any processes whose names start with \"VuoComposition\" or one of your composition file names appear in Activity Monitor, force-quit them.",
2503 string dir, file, ext;
2507 compiler->link(tmpPath, modulesToLink, librariesToLink, frameworksToLink,
true,
"",
false, issues);
2510 VUserLog(
"Warning: May not have fully rebuilt %s for the \"faster build\" optimization:\n%s", cacheDescription.c_str(), issues->
getLongDescription(
false).c_str());
2517 getVuoFrameworkPath() +
"/Helpers/install_name_tool",
2519 currentModuleCacheDylib,
2520 currentModuleCacheDylib,
2526 if (vuoFrameworkInProgressPath.empty())
2527 adHocCodeSign(currentModuleCacheDylib);
2530 vector<string> expectedContents(cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end());
2539 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2541 dispatch_sync(environmentQueue, ^{
2542 moduleCacheContents = cacheableModulesAndDependencies;
2543 isModuleCacheAvailable =
true;
2549 if (gotLockForWriting)
2551 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2553 VUserLog(
"Warning: Couldn't rebuild %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2561 if (vuoFrameworkInProgressPath.empty())
2562 VUserLog(
"Warning: Couldn't use %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2569 void VuoCompiler::Environment::waitForModuleCachesToBuild(
void)
2571 dispatch_sync(moduleCacheBuildingQueue, ^{});
2583 bool VuoCompiler::Environment::findInModuleCache(
const string &moduleOrDependency,
string &cachePath)
2585 if (isModuleCacheAvailable && moduleCacheContents.find(moduleOrDependency) != moduleCacheContents.end())
2587 cachePath = currentModuleCacheDylib;
2597 string VuoCompiler::Environment::getCurrentModuleCacheDylib(
void)
2599 return currentModuleCacheDylib;
2606 unsigned long VuoCompiler::Environment::getLastModuleCacheRebuild(
void)
2608 return lastModuleCacheRebuild;
2617 void VuoCompiler::Environment::modulesChanged(
void)
2619 isModuleCacheableDataDirty =
true;
2620 isModuleCacheAvailable =
false;
2626 bool VuoCompiler::Environment::isBuiltInOriginal()
2628 return builtIn && ! generated;
2634 bool VuoCompiler::Environment::isBuiltIn()
2642 bool VuoCompiler::Environment::isGenerated()
2650 string VuoCompiler::Environment::getName()
2652 if (isBuiltInOriginal())
2654 else if (
this == sharedEnvironments[target][0][1])
2655 return "builtin (generated)";
2656 else if (
this == sharedEnvironments[target][1][0])
2658 else if (
this == sharedEnvironments[target][1][1])
2659 return "system (generated)";
2660 else if (
this == sharedEnvironments[target][2][0])
2662 else if (
this == sharedEnvironments[target][2][1])
2663 return "user (generated)";
2664 return "composition-local";
2670 void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *))
2672 dispatch_sync(environmentQueue, ^{
2673 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2674 doForEnvironment((*i)[0]);
2682 void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *,
bool *,
string),
bool *result,
string arg)
2684 dispatch_sync(environmentQueue, ^{
2685 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2686 doForEnvironment((*i)[0], result, arg);
2694 void VuoCompiler::applyToAllEnvironments(
void (^doForEnvironment)(Environment *environment))
2696 dispatch_sync(environmentQueue, ^{
2697 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2698 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j) {
2699 doForEnvironment(*j);
2722 this->target = target = getProcessTarget();
2723 VDebugLog(
"%p target=%s (from current process)",
this, this->target.c_str());
2727 this->target = target;
2728 VDebugLog(
"%p target=%s",
this, this->target.c_str());
2735 shouldLoadAllModules =
true;
2736 hasLoadedAllModules =
false;
2737 modulesToLoadQueue = dispatch_queue_create(
"org.vuo.compiler.modules", NULL);
2738 moduleSourceCompilersExist = dispatch_group_create();
2739 moduleCacheBuilding = dispatch_group_create();
2740 dependencyGraph = NULL;
2741 compositionDependencyGraph = NULL;
2743 _shouldShowSplashWindow =
false;
2745 delegateQueue = dispatch_queue_create(
"org.vuo.compiler.delegate", NULL);
2748 if (! vuoFrameworkPath.empty())
2749 clangPath = vuoFrameworkPath +
"/Helpers/clang";
2751 clangPath = LLVM_ROOT
"/bin/clang";
2753 dispatch_sync(environmentQueue, ^{
2754 allCompilers.insert(
this);
2756 if (sharedEnvironments[target].empty())
2758 sharedEnvironments[target] = vector< vector<Environment *> >(3, vector<Environment *>(2, NULL));
2759 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2760 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2761 *j =
new Environment(this->target, i == sharedEnvironments[target].begin(), j != i->begin());
2763 vector<string> builtInModuleSearchPaths = Environment::getBuiltInModuleSearchPaths();
2764 for (vector<string>::iterator i = builtInModuleSearchPaths.begin(); i != builtInModuleSearchPaths.end(); ++i)
2765 sharedEnvironments[target][0][0]->addModuleSearchPath(*i,
false);
2767 vector<string> builtInHeaderSearchPaths = Environment::getBuiltInHeaderSearchPaths();
2768 for (vector<string>::iterator i = builtInHeaderSearchPaths.begin(); i != builtInHeaderSearchPaths.end(); ++i)
2769 sharedEnvironments[target][0][0]->addHeaderSearchPath(*i);
2771 vector<string> builtInLibrarySearchPaths = Environment::getBuiltInLibrarySearchPaths();
2772 for (vector<string>::iterator i = builtInLibrarySearchPaths.begin(); i != builtInLibrarySearchPaths.end(); ++i)
2773 sharedEnvironments[target][0][0]->addLibrarySearchPath(*i);
2775 vector<string> builtInFrameworkSearchPaths = Environment::getBuiltInFrameworkSearchPaths();
2776 for (vector<string>::iterator i = builtInFrameworkSearchPaths.begin(); i != builtInFrameworkSearchPaths.end(); ++i)
2777 sharedEnvironments[target][0][0]->addFrameworkSearchPath(*i);
2791 if (! vuoFrameworkPath.empty())
2793 vector<string> moduleCachePaths(3);
2794 moduleCachePaths[0] = vuoFrameworkPath +
"/Modules/Builtin";
2798 for (
size_t i = 0; i < moduleCachePaths.size(); ++i)
2800 string moduleCachePath = moduleCachePaths[i];
2802 sharedEnvironments[target][i][0]->setModuleCachePath(moduleCachePath,
true);
2803 sharedEnvironments[target][i][1]->setModuleCachePath(moduleCachePath,
false);
2821 dispatch_sync(environmentQueue, ^{
2822 allCompilers.erase(
this);
2825 dispatch_group_wait(moduleCacheBuilding, DISPATCH_TIME_FOREVER);
2826 dispatch_release(moduleCacheBuilding);
2828 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
2829 (*i)[0]->removeCompilerToNotify(
this);
2831 dispatch_sync(delegateQueue, ^{});
2833 dispatch_release(modulesToLoadQueue);
2834 dispatch_release(delegateQueue);
2836 delete dependencyGraph;
2837 delete compositionDependencyGraph;
2843 void VuoCompiler::reset(
void)
2845 dispatch_group_wait(moduleSourceCompilersExistGlobally, DISPATCH_TIME_FOREVER);
2847 dispatch_sync(environmentQueue, ^{
2849 for (
auto e : sharedEnvironments)
2850 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2852 (*i)[0]->stopWatchingModuleSearchPaths();
2853 dispatch_sync((*i)[0]->moduleSearchPathContentsChangedQueue, ^{});
2856 for (
auto e : environmentsForCompositionFamily)
2857 for (map<
string, vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2859 (i->second)[0]->stopWatchingModuleSearchPaths();
2860 dispatch_sync((i->second)[0]->moduleSearchPathContentsChangedQueue, ^{});
2863 for (
auto e : sharedEnvironments)
2864 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2865 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2868 for (
auto e : environmentsForCompositionFamily)
2869 for (map<
string, vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2870 for (vector<Environment *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2873 allCompilers.clear();
2874 sharedEnvironments.clear();
2875 environmentsForCompositionFamily.clear();
2887 dispatch_async(delegateQueue, ^{
2888 this->delegate = delegate;
2903 string compositionModulesDir;
2904 string compositionBaseDir;
2905 lastCompositionIsSubcomposition =
false;
2906 if (! compositionPath.empty())
2914 string compositionDir;
2917 lastCompositionIsSubcomposition = (compositionDir == compositionModulesDir);
2922 dispatch_sync(environmentQueue, ^{
2923 if (! environments.empty() && compositionBaseDir == lastCompositionBaseDir) {
2926 lastCompositionBaseDir = compositionBaseDir;
2930 Environment *oldCompositionFamilyInstalledEnvironment =
nullptr;
2931 vector<Environment *> compositionEnvironments;
2932 if (! environments.empty())
2934 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2935 (*i)[0]->removeCompilerToNotify(this);
2938 if (environments.size() >= 5) {
2939 oldCompositionFamilyInstalledEnvironment = environments[3][0];
2942 compositionEnvironments = environments.back();
2944 environments.clear();
2951 bool isCompositionInSharedEnvironment =
false;
2952 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2954 environments.push_back(*i);
2956 vector<string> moduleSearchPaths = (*i)[0]->getModuleSearchPaths();
2957 for (vector<string>::iterator j = moduleSearchPaths.begin(); j != moduleSearchPaths.end(); ++j)
2959 string moduleSearchPath = *j;
2960 VuoFileUtilities::canonicalizePath(moduleSearchPath);
2961 if (moduleSearchPath == compositionModulesDir)
2963 isCompositionInSharedEnvironment = true;
2968 if (isCompositionInSharedEnvironment) {
2975 Environment *newCompositionFamilyInstalledEnvironment =
nullptr;
2976 if (! isCompositionInSharedEnvironment && ! compositionPath.empty())
2978 vector<Environment *> compositionFamilyEnvironments = environmentsForCompositionFamily[target][compositionBaseDir];
2979 if (compositionFamilyEnvironments.empty())
2981 compositionFamilyEnvironments = vector<Environment *>(2, NULL);
2982 compositionFamilyEnvironments[0] = new Environment(this->target, false, false);
2983 compositionFamilyEnvironments[1] = new Environment(this->target, false, true);
2984 environmentsForCompositionFamily[target][compositionBaseDir] = compositionFamilyEnvironments;
2988 compositionFamilyEnvironments[0]->addModuleSearchPath(compositionModulesDir);
2992 string moduleCachePath = getCachePathForComposition(compositionBaseDir);
2994 compositionFamilyEnvironments[0]->setModuleCachePath(moduleCachePath, true);
2995 compositionFamilyEnvironments[1]->setModuleCachePath(moduleCachePath, false);
2997 environments.push_back(compositionFamilyEnvironments);
2999 newCompositionFamilyInstalledEnvironment = compositionFamilyEnvironments[0];
3004 if (compositionEnvironments.empty())
3006 compositionEnvironments = vector<Environment *>(2, NULL);
3007 compositionEnvironments[0] = new Environment(this->target, false, false);
3008 compositionEnvironments[1] = new Environment(this->target, false, true);
3010 environments.push_back(compositionEnvironments);
3012 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
3013 (*i)[0]->addCompilerToNotify(this);
3016 delete dependencyGraph;
3017 delete compositionDependencyGraph;
3018 dependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getDependencyGraph(); });
3019 compositionDependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getCompositionDependencyGraph(); });
3024 if (oldCompositionFamilyInstalledEnvironment != newCompositionFamilyInstalledEnvironment)
3026 auto getModules = [] (Environment *env)
3028 map<string, VuoCompilerModule *> modules;
3031 for (
auto i : env->getNodeClasses()) {
3034 for (
auto i : env->getTypes()) {
3037 for (
auto i : env->getLibraryModules()) {
3044 map<string, VuoCompilerModule *> modulesAdded = getModules(newCompositionFamilyInstalledEnvironment);
3045 map<string, VuoCompilerModule *> modulesRemoved = getModules(oldCompositionFamilyInstalledEnvironment);
3047 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified;
3048 for (map<string, VuoCompilerModule *>::iterator
add = modulesAdded.begin();
add != modulesAdded.end(); )
3050 map<string, VuoCompilerModule *>::iterator rem = modulesRemoved.find(
add->first);
3051 if (rem != modulesRemoved.end())
3053 modulesModified[
add->first] = make_pair(rem->second,
add->second);
3054 modulesAdded.erase(
add++);
3055 modulesRemoved.erase(rem);
3063 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty()) )
3066 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues);
3067 delegateData->retain();
3069 Environment *scopeEnvironment = newCompositionFamilyInstalledEnvironment;
3070 if (! scopeEnvironment) {
3071 scopeEnvironment = compositionEnvironments.at(0);
3074 loadedModules(modulesAdded, modulesModified, modulesRemoved, issues, delegateData, scopeEnvironment);
3088 if (!graphForEnvironment)
3093 for (vector< vector<Environment *> >::const_iterator i = environments.begin(); i != environments.end(); ++i)
3097 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(i->at(1)));
3101 for (vector< vector<Environment *> >::const_iterator ii = environments.begin(); ii != i; ++ii)
3103 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(ii->at(0)));
3104 network->
addEdge(graphForEnvironment(i->at(1)), graphForEnvironment(ii->at(0)));
3131 void VuoCompiler::loadModulesIfNeeded(
const set<string> &moduleKeys)
3133 __block
bool willLoadAllModules =
false;
3134 if (moduleKeys.empty())
3136 dispatch_sync(modulesToLoadQueue, ^{
3137 if (shouldLoadAllModules && ! hasLoadedAllModules) {
3138 willLoadAllModules =
true;
3139 hasLoadedAllModules =
true;
3144 if (! willLoadAllModules && moduleKeys.empty())
3149 dispatch_group_enter(moduleSourceCompilersExist);
3150 __block set<dispatch_group_t> sourcesLoading;
3151 dispatch_sync(environmentQueue, ^{
3152 sourcesLoading = loadModulesAndSources(moduleKeys, set<string>(), set<string>(),
3153 moduleKeys, set<string>(), set<string>(),
3154 willLoadAllModules,
false,
nullptr,
nullptr,
nullptr,
"");
3160 for (set<dispatch_group_t>::iterator i = sourcesLoading.begin(); i != sourcesLoading.end(); ++i)
3162 dispatch_group_wait(*i, DISPATCH_TIME_FOREVER);
3163 dispatch_release(*i);
3165 dispatch_group_leave(moduleSourceCompilersExist);
3176 set<dispatch_group_t> VuoCompiler::loadModulesAndSources(
const set<string> &modulesAddedKeys,
const set<string> &modulesModifiedKeys,
const set<string> &modulesRemovedKeys,
3177 const set<string> &sourcesAddedKeys,
const set<string> &sourcesModifiedKeys,
const set<string> &sourcesRemovedKeys,
3178 bool willLoadAllModules,
bool shouldRecompileSourcesIfUnchanged,
3179 Environment *currentEnvironment,
VuoCompilerIssues *issuesForCurrentEnvironment,
3180 std::function<
void(
void)> moduleLoadedCallback,
const string &moduleAddedOrModifiedSourceCode)
3192 map<Environment *, set<string> > modulesAdded;
3193 map<Environment *, set<string> > modulesModified;
3194 map<Environment *, set<string> > modulesRemoved;
3195 map<Environment *, set<string> > sourcesAdded;
3196 map<Environment *, set<string> > sourcesModified;
3197 map<Environment *, set<string> > sourcesRemoved;
3198 map<Environment *, set<string> > potentialSpecializedModules;
3200 if (currentEnvironment)
3202 modulesAdded[currentEnvironment] = modulesAddedKeys;
3203 modulesModified[currentEnvironment] = modulesModifiedKeys;
3204 modulesRemoved[currentEnvironment] = modulesRemovedKeys;
3205 sourcesAdded[currentEnvironment] = sourcesAddedKeys;
3206 sourcesModified[currentEnvironment] = sourcesModifiedKeys;
3207 sourcesRemoved[currentEnvironment] = sourcesRemovedKeys;
3211 Environment *genEnv =
nullptr;
3212 if (! willLoadAllModules)
3218 int scope = environments.size() - (lastCompositionIsSubcomposition ? 2 : 1);
3219 genEnv = environments.at(scope).at(1);
3220 potentialSpecializedModules[genEnv] = modulesAddedKeys;
3223 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3225 Environment *env = (*i).at(0);
3227 ModuleInfoIterator modulesAddedIter = (willLoadAllModules ? env->listAllModules() : env->listModules(modulesAddedKeys));
3228 ModuleInfoIterator sourcesAddedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesAddedKeys));
3229 ModuleInfoIterator sourcesModifiedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesModifiedKeys));
3231 ModuleInfo *moduleInfo;
3232 while ((moduleInfo = modulesAddedIter.next()))
3234 string moduleKey = moduleInfo->getModuleKey();
3236 modulesAdded[env].insert(moduleKey);
3238 if (! willLoadAllModules)
3240 auto foundIter = potentialSpecializedModules[genEnv].find(moduleKey);
3241 if (foundIter != potentialSpecializedModules[genEnv].end())
3242 potentialSpecializedModules[genEnv].erase(foundIter);
3248 auto isCompiledModuleAtSameSearchPath = [&env] (ModuleInfo *sourceInfo)
3250 ModuleInfo *compiledModuleInfo = env->listModule(sourceInfo->getModuleKey());
3251 return (compiledModuleInfo && compiledModuleInfo->getSearchPath() == sourceInfo->getSearchPath());
3254 while ((moduleInfo = sourcesAddedIter.next()))
3256 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3259 sourcesAdded[env].insert( moduleInfo->getModuleKey() );
3262 while ((moduleInfo = sourcesModifiedIter.next()))
3264 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3267 sourcesModified[env].insert( moduleInfo->getModuleKey() );
3272 map<Environment *, VuoCompilerIssues *> issues;
3273 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3275 Environment *env = (*i).at(0);
3276 issues[env] = (env == currentEnvironment && issuesForCurrentEnvironment ? issuesForCurrentEnvironment :
new VuoCompilerIssues());
3281 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3283 Environment *env = (*i).at(0);
3288 set<VuoDirectedAcyclicGraph::Vertex *> circularDependencies = env->getCompositionDependencyGraph()->getCycleVertices();
3290 set<string> sourcesAddedModified;
3291 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3292 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3294 for (set<string>::iterator j = sourcesAddedModified.begin(); j != sourcesAddedModified.end(); ++j)
3296 string moduleKey = *j;
3299 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator k = circularDependencies.begin(); k != circularDependencies.end(); ++k)
3301 DependencyGraphVertex *vertex =
static_cast<DependencyGraphVertex *
>(*k);
3302 if (vertex->getDependency() == moduleKey)
3311 sourcesAdded[env].erase(moduleKey);
3312 sourcesModified[env].erase(moduleKey);
3315 "Subcomposition contains itself",
3316 "%moduleKey contains an instance of itself, "
3317 "or contains another subcomposition that contains an instance of %moduleKey.");
3318 issue.setModuleKey(moduleKey);
3320 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3322 issue.setFilePath(sourceInfo->getFile()->path());
3324 issues[env]->append(issue);
3331 for (
const vector<Environment *> &envs : environments)
3333 Environment *env = envs.at(0);
3335 set<string> sourcesAddedModified;
3336 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3337 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3339 for (
const string &moduleKey : sourcesAddedModified)
3342 int pathLength = env->getCompositionDependencyGraph()->getLongestDownstreamPath(vertex);
3344 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3345 sourceInfo->setLongestDownstreamPath(pathLength);
3353 map<Environment *, set<string> > modulesDepOnModulesModified;
3354 map<Environment *, set<string> > sourcesDepOnModulesModified;
3355 map<Environment *, set<string> > modulesDepOnModulesRemoved;
3356 map<Environment *, set<string> > sourcesDepOnModulesRemoved;
3359 __block map<Environment *, set<string> > modulesDepOnModulesModified_otherCompiler;
3360 __block map<Environment *, set<string> > sourcesDepOnModulesModified_otherCompiler;
3361 __block map<Environment *, set<string> > modulesDepOnModulesRemoved_otherCompiler;
3362 __block map<Environment *, set<string> > sourcesDepOnModulesRemoved_otherCompiler;
3364 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3366 searchDependencyGraphs.push_back(compiler->dependencyGraph);
3368 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getDependencyGraph() :
nullptr);
3370 findDependentModulesAndSources(modulesModified, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3371 modulesDepOnModulesModified, modulesDepOnModulesModified_otherCompiler,
3372 sourcesDepOnModulesModified, sourcesDepOnModulesModified_otherCompiler);
3374 findDependentModulesAndSources(modulesRemoved, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3375 modulesDepOnModulesRemoved, modulesDepOnModulesRemoved_otherCompiler,
3376 sourcesDepOnModulesRemoved, sourcesDepOnModulesRemoved_otherCompiler);
3378 set<Environment *> otherEnvironments;
3379 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesModified_otherCompiler.begin(); i != modulesDepOnModulesModified_otherCompiler.end(); ++i)
3380 otherEnvironments.insert(i->first);
3381 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesModified_otherCompiler.begin(); i != sourcesDepOnModulesModified_otherCompiler.end(); ++i)
3382 otherEnvironments.insert(i->first);
3383 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesRemoved_otherCompiler.begin(); i != modulesDepOnModulesRemoved_otherCompiler.end(); ++i)
3384 otherEnvironments.insert(i->first);
3385 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesRemoved_otherCompiler.begin(); i != sourcesDepOnModulesRemoved_otherCompiler.end(); ++i)
3386 otherEnvironments.insert(i->first);
3388 for (Environment *env : otherEnvironments)
3392 for (
const vector<Environment *> &ee : c->environments)
3393 for (Environment *e : ee)
3397 goto foundOtherCompiler;
3401 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3402 dispatch_sync(environmentQueue, ^{
3403 otherCompiler->loadModulesAndSources(set<string>(), modulesDepOnModulesModified_otherCompiler[env], modulesDepOnModulesRemoved_otherCompiler[env],
3404 set<string>(), sourcesDepOnModulesModified_otherCompiler[env], sourcesDepOnModulesRemoved_otherCompiler[env],
3405 false,
true, env,
nullptr,
nullptr,
"");
3415 map<Environment *, set<VuoCompilerModule *> > actualModulesRemoved;
3416 for (
const vector<Environment *> &envs : environments)
3418 for (Environment *env : envs)
3420 set<string> modulesToUnload;
3421 modulesToUnload.insert(modulesRemoved[env].begin(), modulesRemoved[env].end());
3422 modulesToUnload.insert(modulesModified[env].begin(), modulesModified[env].end());
3423 modulesToUnload.insert(modulesDepOnModulesRemoved[env].begin(), modulesDepOnModulesRemoved[env].end());
3424 modulesToUnload.insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3426 actualModulesRemoved[env] = env->unloadCompiledModules(modulesToUnload);
3428 if (!env->isBuiltInOriginal() && !actualModulesRemoved[env].empty())
3430 set<string> actualModulesRemovedKeys;
3431 for (
auto m : actualModulesRemoved[env])
3432 actualModulesRemovedKeys.insert(m->getPseudoBase()->getModuleKey());
3445 map<Environment *, set<string> > modulesToLoad;
3446 map<Environment *, map<string, string> > modulesToLoadSourceCode;
3447 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3449 Environment *env = (*i).at(0);
3451 if (! modulesAdded[env].empty())
3452 modulesToLoad[env].insert(modulesAdded[env].begin(), modulesAdded[env].end());
3453 if (! modulesModified[env].empty())
3454 modulesToLoad[env].insert(modulesModified[env].begin(), modulesModified[env].end());
3455 if (! modulesDepOnModulesModified[env].empty())
3456 modulesToLoad[env].insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3458 if (env == currentEnvironment && moduleLoadedCallback)
3460 if (modulesAdded[env].size() == 1)
3461 modulesToLoadSourceCode[env][*modulesAdded[env].begin()] = moduleAddedOrModifiedSourceCode;
3462 else if (modulesModified[env].size() == 1)
3463 modulesToLoadSourceCode[env][*modulesModified[env].begin()] = moduleAddedOrModifiedSourceCode;
3467 map<Environment *, set<VuoCompilerModule *> > actualModulesAdded;
3468 while (! modulesToLoad.empty())
3470 set<string> dependenciesToLoad;
3471 map<Environment *, set<string> > potentialSpecializedDependencies;
3472 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3474 Environment *env = (*i).at(0);
3475 Environment *genEnv = (*i).at(1);
3477 set<VuoCompilerModule *> actualModulesLoaded = env->loadCompiledModules(modulesToLoad[env], modulesToLoadSourceCode[env]);
3479 actualModulesAdded[env].insert(actualModulesLoaded.begin(), actualModulesLoaded.end());
3480 modulesToLoad.erase(env);
3482 for (set<VuoCompilerModule *>::iterator j = actualModulesLoaded.begin(); j != actualModulesLoaded.end(); ++j)
3484 set<string> dependencies = (*j)->getDependencies();
3485 dependenciesToLoad.insert(dependencies.begin(), dependencies.end());
3486 potentialSpecializedDependencies[genEnv].insert(dependencies.begin(), dependencies.end());
3489 if (!env->isBuiltInOriginal() && !actualModulesLoaded.empty())
3491 map<string, string> actualFilesAndHashesLoaded;
3492 for (
auto module : actualModulesLoaded)
3500 if (cnc && !cnc->getSourcePath().empty())
3503 if (!cnc->getSourceCode().empty())
3518 actualFilesAndHashesLoaded[path] = hash;
3521 for (pair<string, string> item : actualFilesAndHashesLoaded)
3522 VUserLog(
"Loaded into %s environment: [%8.8s] %s", env->getName().c_str(), item.second.c_str(), item.first.c_str());
3526 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3528 Environment *env = (*i).at(0);
3530 ModuleInfoIterator dependenciesInEnv = env->listModules(dependenciesToLoad);
3531 ModuleInfo *moduleInfo;
3532 while ((moduleInfo = dependenciesInEnv.next()))
3534 modulesToLoad[env].insert( moduleInfo->getModuleKey() );
3536 for (map<Environment *, set<string> >::iterator j = potentialSpecializedDependencies.begin(); j != potentialSpecializedDependencies.end(); ++j)
3538 auto foundIter = j->second.find( moduleInfo->getModuleKey() );
3539 if (foundIter != j->second.end())
3540 j->second.erase(foundIter);
3545 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3547 Environment *genEnv = (*i).at(1);
3548 potentialSpecializedModules[genEnv].insert(potentialSpecializedDependencies[genEnv].begin(), potentialSpecializedDependencies[genEnv].end());
3555 set<dispatch_group_t> specializedModulesLoading;
3556 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3558 Environment *genEnv = (*i).at(1);
3559 set<dispatch_group_t> s = genEnv->loadSpecializedModules(potentialSpecializedModules[genEnv],
this,
llvmQueue);
3560 specializedModulesLoading.insert(s.begin(), s.end());
3565 if (moduleLoadedCallback)
3566 moduleLoadedCallback();
3570 map<Environment *, set< pair<VuoCompilerModule *, VuoCompilerModule *> > > actualModulesModified;
3571 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3573 Environment *env = (*i).at(0);
3575 for (set<VuoCompilerModule *>::iterator
add = actualModulesAdded[env].begin();
add != actualModulesAdded[env].end(); )
3577 set<VuoCompilerModule *>::iterator rem;
3578 for (rem = actualModulesRemoved[env].begin(); rem != actualModulesRemoved[env].end(); ++rem)
3579 if ((*rem)->getPseudoBase()->getModuleKey() == (*add)->getPseudoBase()->getModuleKey())
3582 if (rem != actualModulesRemoved[env].end())
3584 actualModulesModified[env].insert( make_pair(*rem, *
add) );
3585 actualModulesRemoved[env].erase(rem);
3586 actualModulesAdded[env].erase(
add++);
3595 bool wereModulesAddedOrModified =
false;
3596 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3598 Environment *env = (*i).at(0);
3599 if (! (actualModulesAdded[env].empty() && actualModulesModified[env].empty()) )
3601 wereModulesAddedOrModified =
true;
3606 if (wereModulesAddedOrModified)
3608 map<string, VuoCompilerType *> inheritedTypes;
3609 for (
const vector<Environment *> &envs : environments)
3611 for (Environment *env : envs)
3613 env->reifyPortTypes(inheritedTypes);
3614 map<string, VuoCompilerType *> envTypes = env->getTypes();
3615 inheritedTypes.insert(envTypes.begin(), envTypes.end());
3624 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3626 Environment *env = (*i).at(0);
3628 set<string> sourcesToUnload;
3629 sourcesToUnload.insert(sourcesRemoved[env].begin(), sourcesRemoved[env].end());
3630 sourcesToUnload.insert(sourcesDepOnModulesRemoved[env].begin(), sourcesDepOnModulesRemoved[env].end());
3631 if (! sourcesToUnload.empty())
3633 string moduleSearchPath = env->getModuleSearchPaths().front();
3635 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3638 dispatch_sync(environmentQueue, ^{
3639 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), sourcesToUnload,
3640 set<string>(), set<string>(), set<string>(),
3641 false,
false, env,
nullptr,
nullptr,
"");
3644 delete otherCompiler;
3648 if (!env->isBuiltInOriginal() && !sourcesToUnload.empty())
3651 env->deleteModulesCompiledFromSourceCode(sourcesToUnload);
3659 map<Environment *, set<string> > sourcesDepOnModulesAdded;
3661 map<Environment *, set<string> > modulesDepOnModulesAdded;
3662 __block map<Environment *, set<string> > modulesDepOnModulesAdded_otherCompiler;
3663 __block map<Environment *, set<string> > sourcesDepOnModulesAdded_otherCompiler;
3665 map<Environment *, set<string> > actualModuleKeysAdded;
3666 for (
const vector<Environment *> &envs : environments)
3668 Environment *env = envs.at(0);
3673 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3674 searchDependencyGraphs.push_back(compositionDependencyGraph);
3675 for (map<
string, vector<Environment *> >::iterator ii = environmentsForCompositionFamily[target].begin(); ii != environmentsForCompositionFamily[target].end(); ++ii)
3677 vector< vector<Environment *> > otherEnvs = sharedEnvironments[target];
3678 otherEnvs.push_back(ii->second);
3680 searchDependencyGraphs.push_back(other);
3683 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getCompositionDependencyGraph() :
nullptr);
3685 findDependentModulesAndSources(actualModuleKeysAdded, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3686 modulesDepOnModulesAdded, modulesDepOnModulesAdded_otherCompiler,
3687 sourcesDepOnModulesAdded, sourcesDepOnModulesAdded_otherCompiler);
3689 set<Environment *> otherEnvironments;
3690 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesAdded_otherCompiler.begin(); i != sourcesDepOnModulesAdded_otherCompiler.end(); ++i)
3691 otherEnvironments.insert(i->first);
3693 for (Environment *env : otherEnvironments)
3695 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3696 string moduleSearchPath = env->getModuleSearchPaths().front();
3699 dispatch_sync(environmentQueue, ^{
3700 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), set<string>(),
3701 sourcesDepOnModulesAdded_otherCompiler[env], set<string>(), set<string>(),
3702 false,
true, env,
nullptr,
nullptr,
"");
3705 delete otherCompiler;
3710 set<dispatch_group_t> sourcesLoading;
3711 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3713 Environment *env = (*i).at(0);
3715 set<string> sourcesToCompile;
3716 sourcesToCompile.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3717 sourcesToCompile.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3719 if (sourcesToCompile.size() == 0)
3722 set<dispatch_group_t> s = env->compileModulesFromSourceCode(sourcesToCompile, shouldRecompileSourcesIfUnchanged);
3723 sourcesLoading.insert(s.begin(), s.end());
3726 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3728 Environment *env = (*i).at(0);
3730 set<string> sourcesToCompile;
3731 sourcesToCompile.insert(sourcesDepOnModulesAdded[env].begin(), sourcesDepOnModulesAdded[env].end());
3732 sourcesToCompile.insert(sourcesDepOnModulesModified[env].begin(), sourcesDepOnModulesModified[env].end());
3734 if (sourcesToCompile.size() == 0)
3737 env->compileModulesFromSourceCode(sourcesToCompile,
true);
3742 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3744 Environment *env = (*i).at(0);
3745 env->notifyCompilers(actualModulesAdded[env], actualModulesModified[env], actualModulesRemoved[env], issues[env]);
3752 for (
const dispatch_group_t &group : sourcesLoading)
3753 dispatch_retain(group);
3755 set<dispatch_group_t> loadingGroups;
3756 loadingGroups.insert(specializedModulesLoading.begin(), specializedModulesLoading.end());
3757 loadingGroups.insert(sourcesLoading.begin(), sourcesLoading.end());
3758 return loadingGroups;
3772 void VuoCompiler::findDependentModulesAndSources(map<Environment *, set<string> > &changedModules,
3773 const vector<VuoDirectedAcyclicNetwork *> &searchDependencyGraphs,
3775 map<Environment *, set<string> > &modulesDepOnChangedModules_this,
3776 map<Environment *, set<string> > &modulesDepOnChangedModules_other,
3777 map<Environment *, set<string> > &sourcesDepOnChangedModules_this,
3778 map<Environment *, set<string> > &sourcesDepOnChangedModules_other)
3780 for (
const vector<Environment *> &envs : environments)
3782 Environment *env = envs.at(0);
3784 for (
const string &module : changedModules[env])
3786 set<VuoDirectedAcyclicGraph::Vertex *> dependents;
3789 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices;
3790 if (currentEnvironmentDependencyGraph)
3796 moduleVertices.push_back(mv);
3799 moduleVertices = searchDependencyGraph->findVertex(module);
3803 DependencyGraphVertex *moduleVertex =
static_cast<DependencyGraphVertex *
>(moduleVertexRaw);
3804 if (moduleVertex->getEnvironment())
3806 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = searchDependencyGraph->getUpstreamVertices(moduleVertex);
3807 dependents.insert(upstream.begin(), upstream.end());
3812 set< pair<Environment *, string> > dependentsMap;
3815 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(dependentVertexRaw);
3816 Environment *dependentEnv = v->getEnvironment();
3820 string dependent = v->getDependency();
3822 dependentsMap.insert({dependentEnv, dependent});
3828 for (
auto i : envs.at(1)->getNodeClasses())
3832 dependentsMap.insert({envs.at(1), i.first});
3835 for (
auto i : dependentsMap)
3837 Environment *dependentEnv = i.first;
3838 string dependent = i.second;
3842 if (changedModules[dependentEnv].find(dependent) != changedModules[dependentEnv].end())
3845 ModuleInfo *foundSourceInfo = dependentEnv->listSourceFile(dependent);
3846 ModuleInfo *foundModuleInfo = dependentEnv->listModule(dependent);
3848 bool belongsToCurrentCompiler =
false;
3849 for (
const vector<Environment *> &envs2 : environments)
3851 if (find(envs2.begin(), envs2.end(), dependentEnv) != envs2.end())
3853 belongsToCurrentCompiler =
true;
3858 map<Environment *, set<string> > *whicheverDependents =
nullptr;
3859 ModuleInfo *moduleInfo =
nullptr;
3860 if (foundSourceInfo)
3862 moduleInfo = foundSourceInfo;
3863 whicheverDependents = (belongsToCurrentCompiler ? &sourcesDepOnChangedModules_this : &sourcesDepOnChangedModules_other);
3865 else if (foundModuleInfo)
3867 moduleInfo = foundModuleInfo;
3868 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3872 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3875 (*whicheverDependents)[dependentEnv].insert(dependent);
3877 moduleInfo->setAttempted(
false);
3886 void VuoCompiler::loadedModules(map<string, VuoCompilerModule *> modulesAdded,
3887 map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified,
3888 map<string, VuoCompilerModule *> modulesRemoved,
3889 VuoCompilerIssues *issues,
void *delegateDataV, Environment *currentEnvironment)
3901 auto findVersionsOfModule = [
this, currentEnvironment] (
const string &moduleKey)
3903 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions;
3904 for (
const vector<Environment *> &envs : environments)
3906 Environment *env = envs.at(0);
3908 if (module || env == currentEnvironment)
3909 moduleVersions.push_back( make_pair(env, module) );
3911 return moduleVersions;
3914 for (map<string, VuoCompilerModule *>::iterator i = modulesAdded.begin(); i != modulesAdded.end(); )
3916 string moduleKey = i->first;
3919 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3921 if (moduleVersions.size() > 1)
3923 modulesAdded.erase(i++);
3925 if (moduleVersions.back().second == moduleAdded)
3927 VuoCompilerModule *moduleSuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3928 modulesModified[moduleKey] = make_pair(moduleSuperseded, moduleAdded);
3935 for (map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); )
3937 string moduleKey = i->first;
3940 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3942 if (moduleVersions.size() > 1 && moduleVersions.back().second != moduleModified)
3943 modulesModified.erase(i++);
3948 for (map<string, VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); )
3950 string moduleKey = i->first;
3953 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3955 if (moduleVersions.size() > 1)
3957 modulesRemoved.erase(i++);
3959 if (moduleVersions.back().first == currentEnvironment)
3961 VuoCompilerModule *moduleUnsuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3962 modulesModified[moduleKey] = make_pair(moduleRemoved, moduleUnsuperseded);
3969 dispatch_async(delegateQueue, ^{
3970 VuoCompilerDelegate::LoadedModulesData *delegateData =
static_cast<VuoCompilerDelegate::LoadedModulesData *
>(delegateDataV);
3972 if (delegate && ! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()))
3974 delegate->enqueueData(delegateData);
3975 delegate->
loadedModules(modulesAdded, modulesModified, modulesRemoved, issues);
3979 delegateData->release();
3989 void VuoCompiler::loadNodeClassGeneratedAtRuntime(
VuoCompilerNodeClass *nodeClass, Environment *env)
3991 Module *module = nodeClass->
getModule();
3995 setTargetForModule(nodeClass->
getModule(), env->getTarget());
3999 dispatch_sync(environmentQueue, ^{
4000 env->replaceNodeClass(nodeClass);
4003 __block map<string, VuoCompilerType *> inheritedTypes;
4004 void (^envReifyPortTypes)(Environment *) = ^
void (Environment *env) {
4005 env->reifyPortTypes(inheritedTypes);
4006 map<string, VuoCompilerType *> currentTypes = env->getTypes();
4007 inheritedTypes.insert(currentTypes.begin(), currentTypes.end());
4009 applyToAllEnvironments(envReifyPortTypes);
4018 reifyGenericPortTypes(node->getBase());
4026 void VuoCompiler::reifyGenericPortTypes(
VuoNode *node)
4036 vector<VuoPort *> ports;
4037 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
4038 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
4040 for (vector<VuoPort *>::iterator j = ports.begin(); j != ports.end(); ++j)
4087 vector<string> allIncludePaths = includePaths;
4088 string preprocessedInputPath = inputPath;
4090 string tmpPreprocessedInputDir;
4091 string dir, file, ext;
4096 string preprocessedInputContents = inputContents;
4098 if (inputContents != preprocessedInputContents)
4101 allIncludePaths.push_back(dir.empty() ?
"." : dir);
4103 preprocessedInputPath = tmpPreprocessedInputDir +
"/" + file +
"." + ext;
4108 else if (ext ==
"fs")
4114 auto getType = [
this] (
const string &moduleKey) {
return this->
getType(moduleKey); };
4119 setTargetForModule(module, target);
4120 writeModuleToBitcode(module, outputPath);
4130 vector<string> extraArgs;
4131 for (vector<string>::iterator i = allIncludePaths.begin(); i != allIncludePaths.end(); ++i)
4133 extraArgs.push_back(
"-I");
4134 extraArgs.push_back(*i);
4140 string buildTimeMacOSSDKFolder = MACOS_SDK_ROOT;
4143 extraArgs.push_back(
"-isysroot");
4144 extraArgs.push_back(buildTimeMacOSSDKFolder);
4148 __block vector<string> headerSearchPaths;
4149 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
4150 vector<string> result = env->getHeaderSearchPaths();
4151 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
4153 applyToInstalledEnvironments(envGetHeaderSearchPaths);
4156 __block Module *module;
4158 module = readModuleFromC(preprocessedInputPath, headerSearchPaths, extraArgs, issues);
4161 if (! tmpPreprocessedInputDir.empty())
4163 remove(tmpPreprocessedInputDir.c_str());
4172 if (! compilerModule)
4174 VUserLog(
"Error: Didn't recognize '%s' as a node class, type, or library.", inputPath.c_str());
4178 setTargetForModule(module, target);
4179 writeModuleToBitcode(module, outputPath);
4188 Module * VuoCompiler::compileCompositionToModule(
VuoCompilerComposition *composition,
const string &moduleKey,
bool isTopLevelComposition,
4191 composition->
check(issues);
4193 reifyGenericPortTypes(composition);
4196 isTopLevelComposition,
4198 if (telemetry ==
"console")
4201 __block Module *module =
nullptr;
4206 setTargetForModule(module, target);
4236 Module *module = compileCompositionToModule(composition, moduleKey, isTopLevelComposition, issues);
4241 writeModuleToBitcode(module, outputPath);
4260 VDebugLog(
"Compiling '%s' (%s)…", inputPath.c_str(), target.c_str());
4270 "",
"The composition file couldn't be read or was empty.");
4309 delete baseComposition;
4328 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
false, rPath, shouldAdHocCodeSign);
4350 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
true,
"", shouldAdHocCodeSign);
4367 void VuoCompiler::linkCompositionToCreateExecutableOrDynamicLibrary(
string compiledCompositionPath,
string linkedCompositionPath,
4368 Optimization optimization,
bool isDylib,
string rPath,
bool shouldAdHocCodeSign)
4374 shouldLoadAllModules =
false;
4376 set<string> dependencies = getDependenciesForComposition(compiledCompositionPath);
4377 dependencies.insert(getRuntimeDependency());
4379 dependencies.insert(getRuntimeMainDependency());
4381 set<Module *> modules;
4382 set<string> libraries;
4383 set<string> frameworks;
4384 getLinkerInputs(dependencies, optimization, modules, libraries, frameworks);
4386 libraries.insert(compiledCompositionPath);
4388 link(linkedCompositionPath, modules, libraries, frameworks, isDylib, rPath, shouldAdHocCodeSign);
4411 bool shouldAdHocCodeSign =
false;
4413 shouldAdHocCodeSign =
true;
4419 set<string> allDependencies = getDependenciesForComposition(compiledCompositionPath);
4420 set<string> addedDependencies;
4421 std::set_difference(allDependencies.begin(), allDependencies.end(),
4422 carriedOverDependencies.begin(), carriedOverDependencies.end(),
4423 std::inserter(addedDependencies, addedDependencies.end()));
4429 set<string> carriedOverExternalLibraries = runningCompositionLibraries->
getExternalLibraries();
4434 string nonUnloadableResourcePath;
4435 string unloadableResourcePath;
4436 set<string> nonUnloadableDependencies;
4437 set<string> unloadableDependencies;
4438 map<string, set<string> > builtInCacheDependencies;
4439 map<string, set<string> > userCacheDependencies;
4440 set<string> builtInLibraries;
4441 set<string> userLibraries;
4442 set<string> addedExternalLibraries;
4443 set<string> addedFrameworks;
4444 set<string> allFrameworks;
4445 if (! addedDependencies.empty())
4449 set<string> builtInModuleAndLibraryDependencies;
4450 set<string> userModuleAndLibraryDependencies;
4451 set<Module *> builtInModules;
4452 set<Module *> userModules;
4455 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4456 builtInModules, userModules, builtInLibraries, userLibraries, addedExternalLibraries, addedFrameworks);
4458 allFrameworks.insert(carriedOverFrameworks.begin(), carriedOverFrameworks.end());
4459 allFrameworks.insert(addedFrameworks.begin(), addedFrameworks.end());
4461 string dir, linkedCompositionFile, ext;
4468 __block vector<string> currentCacheLibraries;
4469 applyToAllEnvironments(^
void (Environment *env) {
4470 currentCacheLibraries.push_back( env->getCurrentModuleCacheDylib() );
4473 for (
string cachePath : carriedOverUserCacheLibraries)
4475 for (
string currentCachePath : currentCacheLibraries)
4481 userCacheDependencies[currentCachePath].insert(dependenciesInCache.begin(), dependenciesInCache.end());
4483 auto cacheDependenciesIter = userCacheDependencies.find(cachePath);
4484 if (cacheDependenciesIter != userCacheDependencies.end())
4486 userCacheDependencies[currentCachePath].insert(cacheDependenciesIter->second.begin(), cacheDependenciesIter->second.end());
4487 userCacheDependencies.erase(cacheDependenciesIter);
4490 auto carriedOverIter = find(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(), cachePath);
4491 if (carriedOverIter != carriedOverUnloadableLibraries.end())
4492 *carriedOverIter = currentCachePath;
4500 if (wasModuleCacheRebuilt)
4504 vector<string> carriedOverUnloadableMinusResourceLibraries;
4505 std::set_difference(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(),
4506 carriedOverResourceLibraries.begin(), carriedOverResourceLibraries.end(),
4507 std::back_inserter(carriedOverUnloadableMinusResourceLibraries));
4509 carriedOverUnloadableLibraries = carriedOverUnloadableMinusResourceLibraries;
4512 userModuleAndLibraryDependencies.insert(dependenciesInResourceLibraries.begin(), dependenciesInResourceLibraries.end());
4514 set<string> builtInModuleAndLibraryDependencies_tmp;
4515 set<string> userModuleAndLibraryDependencies_tmp;
4516 map<string, set<string> > builtInCacheDependencies_tmp;
4517 set<Module *> builtInModules_tmp;
4518 set<string> builtInLibraries_tmp;
4519 set<string> externalLibraries_tmp;
4520 set<string> externalFrameworks_tmp;
4523 builtInModuleAndLibraryDependencies_tmp, userModuleAndLibraryDependencies_tmp, builtInCacheDependencies_tmp, userCacheDependencies,
4524 builtInModules_tmp, userModules, builtInLibraries_tmp, userLibraries, externalLibraries_tmp, externalFrameworks_tmp);
4529 if (! builtInModules.empty() || builtInLibraries.size() > builtInCacheDependencies.size())
4532 nonUnloadableDependencies = builtInModuleAndLibraryDependencies;
4534 set<string> librariesForNonUnloadableResource = builtInLibraries;
4535 librariesForNonUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4536 librariesForNonUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4537 librariesForNonUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4539 link(nonUnloadableResourcePath, builtInModules, librariesForNonUnloadableResource, allFrameworks,
true,
"", shouldAdHocCodeSign);
4541 for (set<string>::iterator i = builtInLibraries.begin(); i != builtInLibraries.end(); )
4544 builtInLibraries.erase(i++);
4549 for (set<string>::iterator i = addedExternalLibraries.begin(); i != addedExternalLibraries.end(); )
4552 addedExternalLibraries.erase(i++);
4560 if (! userModules.empty() || userLibraries.size() > userCacheDependencies.size() || wasModuleCacheRebuilt)
4563 unloadableDependencies = userModuleAndLibraryDependencies;
4565 set<string> librariesForUnloadableResource = userLibraries;
4566 librariesForUnloadableResource.insert(builtInLibraries.begin(), builtInLibraries.end());
4567 librariesForUnloadableResource.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4568 librariesForUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4569 librariesForUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4570 librariesForUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4571 if (! nonUnloadableResourcePath.empty())
4572 librariesForUnloadableResource.insert(nonUnloadableResourcePath);
4574 link(unloadableResourcePath, userModules, librariesForUnloadableResource, allFrameworks,
true,
"", shouldAdHocCodeSign);
4576 for (set<string>::iterator i = userLibraries.begin(); i != userLibraries.end(); )
4579 userLibraries.erase(i++);
4588 set<string> vuoRuntimePaths;
4590 set<Module *> modules;
4591 set<string> libraries;
4592 set<string> frameworks;
4594 set<string> dependencies;
4595 dependencies.insert(getRuntimeDependency());
4597 vuoRuntimePaths = libraries;
4603 set<Module *> modules;
4604 set<string> libraries;
4606 libraries.insert(compiledCompositionPath);
4607 libraries.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4608 libraries.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4609 libraries.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4610 libraries.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4611 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4612 libraries.insert(userLibraries.begin(), userLibraries.end());
4613 if (! nonUnloadableResourcePath.empty())
4614 libraries.insert(nonUnloadableResourcePath);
4615 if (! unloadableResourcePath.empty())
4616 libraries.insert(unloadableResourcePath);
4617 libraries.insert(vuoRuntimePaths.begin(), vuoRuntimePaths.end());
4618 link(linkedCompositionPath, modules, libraries, allFrameworks,
true,
"", shouldAdHocCodeSign);
4623 if (! nonUnloadableResourcePath.empty())
4626 if (! unloadableResourcePath.empty())
4629 for (map<
string, set<string> >::iterator i = builtInCacheDependencies.begin(); i != builtInCacheDependencies.end(); ++i)
4632 for (map<
string, set<string> >::iterator i = userCacheDependencies.begin(); i != userCacheDependencies.end(); ++i)
4645 set<string> VuoCompiler::getDependenciesForComposition(
const string &compiledCompositionPath)
4647 VDebugLog(
"Gathering dependencies for '%s'…", compiledCompositionPath.c_str());
4650 __block set<string> directDependencies;
4652 Module *module = readModuleFromBitcode(compiledCompositionPath, getTargetArch(target));
4656 delete compilerModule;
4662 auto deps = getDependenciesForComposition(directDependencies,
true);
4681 set<string> directDependencies;
4690 vector<VuoPublishedPort *> publishedPorts;
4691 publishedPorts.insert(publishedPorts.end(), publishedInputPorts.begin(), publishedInputPorts.end());
4692 publishedPorts.insert(publishedPorts.end(), publishedOutputPorts.begin(), publishedOutputPorts.end());
4695 if (publishedPort->getClass()->hasCompiler())
4711 directDependencies.insert(dependency);
4716 return directDependencies;
4728 return getDependenciesForComposition(directDependencies,
false);
4738 __block vector<string> librarySearchPaths;
4739 applyToInstalledEnvironments(^
void (Environment *env) {
4740 vector<string> result = env->getLibrarySearchPaths();
4741 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
4744 set<string> dylibDeps;
4745 for (
string dep : getDependenciesForComposition(composition))
4747 string path = getLibraryPath(dep, librarySearchPaths);
4749 dylibDeps.insert(path);
4768 set<string> VuoCompiler::getDependenciesForComposition(
const set<string> &directDependencies,
bool checkCompatibility)
4771 for (set<string>::const_iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4774 set<string> dependencies;
4775 for (set<string>::iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4777 string moduleKey = *i;
4779 dependencies.insert(moduleKey);
4782 vector<VuoDirectedAcyclicGraph::Vertex *> firstPassVertices = dependencyGraph->
findVertex(moduleKey);
4783 set<VuoDirectedAcyclicGraph::Vertex *> firstPassDependencies(firstPassVertices.begin(), firstPassVertices.end());
4784 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassVertices.begin(); j != firstPassVertices.end(); ++j)
4787 firstPassDependencies.insert(downstream.begin(), downstream.end());
4791 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassDependencies.begin(); j != firstPassDependencies.end(); ++j)
4793 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(*j);
4798 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
4799 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = moduleVertices.begin(); j != moduleVertices.end(); ++j)
4803 dependencies.insert(
static_cast<DependencyGraphVertex *
>(v)->getDependency() );
4808 if (checkCompatibility)
4816 set<VuoCompilerNodeClass *> nodeClassesReported;
4818 for (
string moduleKey : dependencies)
4823 vector<VuoCompilerNodeClass *> incompatibleNodeClasses;
4826 if (moduleAsNodeClass)
4827 incompatibleNodeClasses.push_back(moduleAsNodeClass);
4830 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
4833 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = dependencyGraph->
getUpstreamVertices(v);
4835 vector<string> upstreamModuleKeys;
4836 std::transform(upstream.begin(), upstream.end(),
4837 std::back_inserter(upstreamModuleKeys),
4840 vector<string> potentialNodeClassNames;
4841 std::set_intersection(directDependencies.begin(), directDependencies.end(),
4842 upstreamModuleKeys.begin(), upstreamModuleKeys.end(),
4843 std::back_inserter(potentialNodeClassNames));
4845 for (
string nodeClassName : potentialNodeClassNames)
4848 if (upstreamNodeClass)
4849 incompatibleNodeClasses.push_back(upstreamNodeClass);
4854 if (incompatibleNodeClasses.empty())
4857 "Dependencies incompatible with system",
4859 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4867 if (nodeClassesReported.find(nodeClass) != nodeClassesReported.end())
4870 nodeClassesReported.insert(nodeClass);
4873 "Nodes incompatible with system",
4875 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4886 "Dependencies incompatible with system",
4887 "Some dependencies of this composition are only compatible with " + actualCompatibility.
toString() +
4888 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4897 vector<string> coreDependencies = getCoreVuoDependencies();
4898 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
4900 return dependencies;
4910 for (
string dependency : dependencies)
4917 return compatibility;
4924 void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4925 set<Module *> &modules, set<string> &libraries, set<string> &frameworks)
4927 set<string> builtInModuleAndLibraryDependencies;
4928 set<string> userModuleAndLibraryDependencies;
4929 map<string, set<string> > builtInCacheDependencies;
4930 map<string, set<string> > userCacheDependencies;
4931 set<Module *> builtInModules;
4932 set<Module *> userModules;
4933 set<string> builtInLibraries;
4934 set<string> userLibraries;
4935 set<string> externalLibraries;
4937 getLinkerInputs(dependencies, optimization,
4938 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4939 builtInModules, userModules, builtInLibraries, userLibraries, externalLibraries, frameworks);
4941 modules.insert(builtInModules.begin(), builtInModules.end());
4942 modules.insert(userModules.begin(), userModules.end());
4943 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4944 libraries.insert(userLibraries.begin(), userLibraries.end());
4945 libraries.insert(externalLibraries.begin(), externalLibraries.end());
4961 void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4962 set<string> &builtInModuleAndLibraryDependencies, set<string> &userModuleAndLibraryDependencies,
4963 map<
string, set<string> > &builtInCacheDependencies, map<
string, set<string> > &userCacheDependencies,
4964 set<Module *> &builtInModules, set<Module *> &userModules,
4965 set<string> &builtInLibraries, set<string> &userLibraries,
4966 set<string> &externalLibraries, set<string> &externalFrameworks)
4969 if (shouldUseModuleCache)
4972 __block vector<string> librarySearchPaths;
4973 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
4974 vector<string> result = env->getLibrarySearchPaths();
4975 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
4977 applyToInstalledEnvironments(envGetLibrarySearchPaths);
4979 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
4981 string dependency = *i;
4983 bool foundInCache =
false;
4984 string moduleCachePath;
4985 bool isInBuiltInModuleCache =
false;
4986 if (shouldUseModuleCache)
4987 foundInCache = findInModuleCache(dependency, moduleCachePath, isInBuiltInModuleCache);
4991 if (isInBuiltInModuleCache)
4993 builtInLibraries.insert(moduleCachePath);
4994 builtInCacheDependencies[moduleCachePath].insert(dependency);
4998 userLibraries.insert(moduleCachePath);
4999 userCacheDependencies[moduleCachePath].insert(dependency);
5005 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
5010 applyToAllEnvironments(envFindModule);
5020 if (module->isBuiltIn())
5021 builtInLibraries.insert(modulePath);
5023 userLibraries.insert(modulePath);
5027 if (module->isBuiltIn())
5028 builtInModules.insert(module->getModule());
5030 userModules.insert(module->getModule());
5033 if (module->isBuiltIn())
5034 builtInModuleAndLibraryDependencies.insert(dependency);
5036 userModuleAndLibraryDependencies.insert(dependency);
5042 externalFrameworks.insert(dependency);
5045 string dependencyPath = getLibraryPath(dependency, librarySearchPaths);
5046 if (! dependencyPath.empty())
5047 externalLibraries.insert(dependencyPath);
5051 else if (dependency !=
"c"
5052 && dependency !=
"objc")
5053 VUserLog(
"Warning: Could not locate dependency '%s'.", dependency.c_str());
5065 string VuoCompiler::getLibraryPath(
const string &dependency, vector<string> librarySearchPaths)
5072 if (dependency !=
"crypto"
5073 && dependency !=
"ssl")
5074 librarySearchPaths.push_back(
"/usr/lib");
5076 for (
auto &path : librarySearchPaths)
5078 vector<string> variations;
5079 variations.push_back(path +
"/" + dependency);
5080 variations.push_back(path +
"/lib" + dependency);
5081 variations.push_back(path +
"/lib" + dependency +
".dylib");
5082 variations.push_back(path +
"/lib" + dependency +
".a");
5083 for (
auto &variation : variations)
5098 void VuoCompiler::useModuleCache(
bool shouldUseExistingBuiltInCaches,
bool shouldUseExistingOtherCaches)
5100 loadModulesIfNeeded();
5101 dispatch_group_wait(moduleSourceCompilersExist, DISPATCH_TIME_FOREVER);
5105 dispatch_sync(environmentQueue, ^{
5106 set<string> dylibsForCachesOfInstalledModules;
5107 set<string> frameworksForCachesOfInstalledModules;
5108 unsigned long lastPrerequisiteModuleCacheRebuild = 0;
5109 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
5111 set<string> dylibsForCacheOfGeneratedModules;
5112 set<string> frameworksForCacheOfGeneratedModules;
5114 for (int j = i->size() - 1; j >= 0; --j)
5116 Environment *env = i->at(j);
5117 bool installed = (j == 0);
5119 set<string> cacheableModulesAndDependencies;
5120 set<string> dylibsNeededToLinkToThisCache;
5121 set<string> frameworksNeededToLinkToThisCache;
5122 env->getCacheableModulesAndDependencies(cacheableModulesAndDependencies,
5123 dylibsNeededToLinkToThisCache, frameworksNeededToLinkToThisCache);
5125 set<string> accumulatedDylibs;
5126 accumulatedDylibs.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5127 accumulatedDylibs.insert(dylibsForCachesOfInstalledModules.begin(), dylibsForCachesOfInstalledModules.end());
5128 accumulatedDylibs.insert(dylibsForCacheOfGeneratedModules.begin(), dylibsForCacheOfGeneratedModules.end());
5130 set<string> accumulatedFrameworks;
5131 accumulatedFrameworks.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5132 accumulatedFrameworks.insert(frameworksForCachesOfInstalledModules.begin(), frameworksForCachesOfInstalledModules.end());
5133 accumulatedFrameworks.insert(frameworksForCacheOfGeneratedModules.begin(), frameworksForCacheOfGeneratedModules.end());
5135 bool shouldUseExistingCache = (env->isBuiltIn() ? shouldUseExistingBuiltInCaches : shouldUseExistingOtherCaches);
5136 env->useModuleCache(shouldUseExistingCache, this, cacheableModulesAndDependencies,
5137 accumulatedDylibs, accumulatedFrameworks, lastPrerequisiteModuleCacheRebuild);
5139 string cacheDylib = env->getCurrentModuleCacheDylib();
5140 accumulatedDylibs.insert(cacheDylib);
5141 dylibsForCachesOfInstalledModules.insert(cacheDylib);
5143 lastPrerequisiteModuleCacheRebuild = max(lastPrerequisiteModuleCacheRebuild, env->getLastModuleCacheRebuild());
5147 dylibsForCachesOfInstalledModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5148 frameworksForCachesOfInstalledModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5152 dylibsForCacheOfGeneratedModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5153 frameworksForCacheOfGeneratedModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5159 Environment::waitForModuleCachesToBuild();
5170 bool VuoCompiler::findInModuleCache(
const string &moduleOrDependency,
string &cachePath,
bool &isBuiltinCache)
5172 __block
bool found =
false;
5173 __block
string outPath;
5174 __block
bool outBuiltin;
5175 dispatch_sync(environmentQueue, ^{
5176 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
5178 bool builtin = (i == environments.begin());
5180 for (int j = i->size() - 1; j >= 0; --j)
5182 Environment *env = i->at(j);
5185 bool resultFound = env->findInModuleCache(moduleOrDependency, resultPath);
5189 outPath = resultPath;
5190 outBuiltin = builtin;
5196 cachePath = outPath;
5197 isBuiltinCache = outBuiltin;
5210 dispatch_group_async(moduleCacheBuilding, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
5211 useModuleCache(
true,
false);
5230 return getTargetArch(target);
5248 vuoFrameworkInProgressPath = vuoFrameworkPath;
5251 compiler.useModuleCache(
false,
true);
5263 unsigned long maxSeconds = 30 * 24 * 60 * 60;
5266 for (set<VuoFileUtilities::File *>::iterator i = cacheDirs.begin(); i != cacheDirs.end(); ++i)
5268 string path = (*i)->path();
5270 string file = (*i)->basename();
5271 if (file !=
"Builtin" && file !=
"System" && file !=
"User")
5274 if (fileSeconds > maxSeconds)
5280 string pidAsString = file.substr(Environment::pidCacheDirPrefix.length());
5281 int pid = atoi(pidAsString.c_str());
5282 if (kill(pid, 0) != 0)
5296 dispatch_sync(modulesToLoadQueue, ^{
5297 this->shouldLoadAllModules = shouldLoadAllModules;
5313 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)
5315 VDebugLog(
"Linking '%s' (%s)…", outputPath.c_str(), getTargetArch(target).c_str());
5318 bool ownsIssues =
false;
5330 unique_ptr<Module> compositeModule(
new Module(
"composite", *
globalLLVMContext));
5331 Linker linker(*compositeModule);
5332 setTargetForModule(compositeModule.get(), target);
5334 for (
auto i : modules)
5336 unique_ptr<Module> upi = llvm::CloneModule(i);
5337 if (linker.linkInModule(std::move(upi)))
5339 VuoCompilerIssue issue(VuoCompilerIssue::IssueType::Error,
"linking composite module",
"",
5340 "",
"Failed to link in the module with ID '" + i->getModuleIdentifier() +
"'");
5345 writeModuleToBitcode(compositeModule.get(), compositeModulePath);
5354 string clangPath(getClangPath() +
"++");
5356 vector<const char *> args;
5357 vector<char *> argsToFree;
5358 args.push_back(clangPath.c_str());
5361 char *outputPathZ = strdup((
"-o" + outputPath).c_str());
5362 args.push_back(outputPathZ);
5363 argsToFree.push_back(outputPathZ);
5366 args.push_back(compositeModulePath.c_str());
5368 vector<string> coreDependencies = getCoreVuoDependencies();
5369 for (set<string>::const_iterator i = libraries.begin(); i != libraries.end(); ++i)
5371 string library = *i;
5373 for (vector<string>::iterator j = coreDependencies.begin(); j != coreDependencies.end(); ++j)
5375 string coreDependency = *j;
5377 args.push_back(
"-force_load");
5385 library = libraryObject;
5388 char *libraryZ = strdup(library.c_str());
5389 args.push_back(libraryZ);
5390 argsToFree.push_back(libraryZ);
5394 vector<string> frameworkArguments;
5396 __block vector<string> frameworkSearchPaths;
5397 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
5398 vector<string> result = env->getFrameworkSearchPaths();
5399 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
5401 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
5403 for (vector<string>::const_iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
5407 frameworkArguments.push_back(a);
5408 char *frameworkArgument = strdup(a.c_str());
5409 args.push_back(frameworkArgument);
5410 argsToFree.push_back(frameworkArgument);
5413 for (set<string>::const_iterator i = frameworks.begin(); i != frameworks.end(); ++i)
5415 args.push_back(
"-framework");
5417 string frameworkName = *i;
5418 frameworkName = frameworkName.substr(0, frameworkName.length() -
string(
".framework").length());
5419 char *frameworkNameZ = strdup(frameworkName.c_str());
5420 args.push_back(frameworkNameZ);
5421 argsToFree.push_back(frameworkNameZ);
5427 string vuoFrameworkContainingFolder = vuoFrameworkPath +
"/..";
5428 string frameworkMacOSSDKFolder = vuoFrameworkPath +
"/SDKs/MacOSX10.11.sdk";
5432 args.push_back(
"-Xlinker");
5433 args.push_back(
"-syslibroot");
5434 args.push_back(
"-Xlinker");
5435 char *frameworkMacOSSDKFolderZ = strdup(frameworkMacOSSDKFolder.c_str());
5436 args.push_back(frameworkMacOSSDKFolderZ);
5437 argsToFree.push_back(frameworkMacOSSDKFolderZ);
5441 args.push_back(
"-Xlinker");
5442 args.push_back(
"--no-demangle");
5445 args.push_back(
"-v");
5448 args.push_back(
"-dynamiclib");
5450 args.push_back(
"-Xlinker");
5451 args.push_back(
"-headerpad_max_install_names");
5454 args.push_back(
"-rpath");
5455 string rPathArg = (rPath.empty() ? vuoFrameworkContainingFolder : rPath);
5456 args.push_back(rPathArg.c_str());
5459 args.push_back(
"-rpath");
5460 args.push_back(LLVM_ROOT
"/lib");
5463 args.push_back(
"-target");
5464 args.push_back(target.c_str());
5466 args.push_back(
"-std=c++11");
5467 args.push_back(
"-stdlib=libc++");
5468 args.push_back(
"-mmacosx-version-min=10.10");
5472 clang::DiagnosticOptions *diagOptions =
new clang::DiagnosticOptions();
5473 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5474 clang::DiagnosticsEngine Diags(DiagID, diagOptions, diagnosticConsumer);
5479 for (vector<const char *>::iterator i = args.begin(); i != args.end(); ++i)
5486 const StringRef stdoutPath(stdoutFile);
5487 const StringRef *redirects[] = {
5494 const char **argsz = (
const char **)malloc(
sizeof(
char *) * args.size() + 1);
5495 for (
int i = 0; i < args.size(); ++i)
5497 argsz[args.size()] =
nullptr;
5500 bool executionFailed;
5502 int ret = llvm::sys::ExecuteAndWait(args[0], argsz,
nullptr, redirects, 0, 0, &errMsg, &executionFailed);
5504 for (
auto i : argsToFree)
5508 remove(compositeModulePath.c_str());
5514 chmod(outputPath.c_str(), 0755);
5519 if (!errMsg.empty())
5522 details +=
"\n" + errMsg +
"\n";
5525 if (!stdoutFileContents.empty())
5527 VUserLog(
"%s", stdoutFileContents.c_str());
5528 details +=
"\n" + stdoutFileContents +
"\n";
5540 if (shouldAdHocCodeSign)
5541 adHocCodeSign(outputPath);
5547 void VuoCompiler::adHocCodeSign(
string path)
5551 "/usr/bin/codesign",
5557 "CODESIGN_ALLOCATE=" + getCodesignAllocatePath(),
5569 Module *VuoCompiler::readModuleFromC(
string inputPath,
const vector<string> &headerSearchPaths,
const vector<string> &extraArgs,
VuoCompilerIssues *issues)
5573 vector<const char *> args;
5574 args.push_back(inputPath.c_str());
5575 args.push_back(
"-DVUO_COMPILER");
5576 args.push_back(
"-fblocks");
5579 args.push_back(
"-Wall");
5580 args.push_back(
"-Wextra");
5581 args.push_back(
"-Wimplicit-fallthrough");
5582 args.push_back(
"-Wno-unused-parameter");
5583 args.push_back(
"-Wno-c++11-extensions");
5584 args.push_back(
"-Wno-sign-compare");
5585 args.push_back(
"-Werror=implicit");
5589 args.push_back(
"-std=c++11");
5590 args.push_back(
"-stdlib=libc++");
5593 for (vector<string>::const_iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
5595 args.push_back(
"-I");
5596 args.push_back(i->c_str());
5600 args.push_back(
"-v");
5602 for (vector<string>::const_iterator i = extraArgs.begin(); i != extraArgs.end(); ++i)
5603 args.push_back(i->c_str());
5606 clang::DiagnosticOptions * diagOptions =
new clang::DiagnosticOptions();
5607 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5608 clang::DiagnosticsEngine *diags =
new clang::DiagnosticsEngine(DiagID, diagOptions, diagnosticConsumer);
5610 shared_ptr<clang::CompilerInvocation> compilerInvocation(
new clang::CompilerInvocation);
5611 clang::CompilerInvocation::CreateFromArgs(*compilerInvocation, &args[0], &args[0] + args.size(), *diags);
5612 compilerInvocation->TargetOpts->Triple = target;
5614 clang::CompilerInstance Clang;
5615 Clang.setInvocation(compilerInvocation);
5617 Clang.setDiagnostics(diags);
5618 if (!Clang.hasDiagnostics())
5622 string builtinHeaderSearchPath;
5624 if (vuoFrameworkPath.empty())
5626 builtinHeaderSearchPath = getClangPath();
5631 builtinHeaderSearchPath +=
"lib/clang/" CLANG_VERSION_STRING;
5634 builtinHeaderSearchPath = vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/lib/clang/" CLANG_VERSION_STRING;
5635 Clang.getHeaderSearchOpts().ResourceDir = builtinHeaderSearchPath;
5638 clang::CodeGenAction *Act =
new clang::EmitLLVMOnlyAction();
5639 if (!Clang.ExecuteAction(*Act))
5642 unique_ptr<Module> module = Act->takeModule();
5644 VUserLog(
"Error compiling %s: module is null.", inputPath.c_str());
5645 return module.release();
5653 Module *VuoCompiler::readModuleFromBitcode(
string inputPath,
string arch)
5655 string dir, file, ext;
5658 return readModuleFromBitcode(&inputFile, arch);
5670 size_t inputDataBytes;
5674 set<string> availableArchs;
5676 Module *module = readModuleFromBitcodeData(inputData, inputDataBytes, arch, availableArchs, error);
5679 VUserLog(
"Error: Couldn't parse module '%s' (%s): %s.", inputFile->
getRelativePath().c_str(), arch.c_str(), error.c_str());
5691 Module *VuoCompiler::readModuleFromBitcodeData(
char *inputData,
size_t inputDataBytes,
string arch,
5692 set<string> &availableArchs,
string &error)
5694 if (inputDataBytes <
sizeof(
unsigned int))
5697 __block Module *module =
nullptr;
5699 StringRef inputDataAsStringRef(inputData, inputDataBytes);
5700 auto mb = MemoryBuffer::getMemBuffer(inputDataAsStringRef,
"",
false);
5703 error =
"Couldn't create MemoryBuffer";
5707 MemoryBufferRef bitcodeBuffer;
5709 unsigned int fileID = *(
unsigned int *)inputData;
5710 if (fileID == 0x0b17c0de)
5712 bitcodeBuffer = mb.get()->getMemBufferRef();
5714 else if (fileID == 0xdec04342)
5717 bitcodeBuffer = mb.get()->getMemBufferRef();
5718 moduleArch =
"x86_64";
5719 availableArchs.insert(moduleArch);
5722 else if (fileID == 0xbebafeca)
5726 error =
"It's a Mach-O universal binary, but this compiler instance's LLVM target isn't set";
5732 auto binary = llvm::object::MachOUniversalBinary::create(mb.get()->getMemBufferRef());
5735 error =
"Couldn't read Mach-O universal binary:";
5736 handleAllErrors(binary.takeError(), [&error](
const ErrorInfoBase &ei) {
5737 error +=
" " + ei.message();
5742 for (
auto &o : binary.get()->objects())
5744 if (o.getArchFlagName() == arch)
5745 bitcodeBuffer = MemoryBufferRef(mb.get()->getMemBufferRef().getBuffer().slice(o.getOffset(), o.getOffset() + o.getSize()),
"");
5747 availableArchs.insert(o.getArchFlagName());
5750 if (!bitcodeBuffer.getBufferSize())
5752 error =
"The Mach-O universal binary doesn't have an \"" + arch +
"\" slice";
5760 error =
"Couldn't parse bitcode file:";
5761 handleAllErrors(wrappedModule.takeError(), [&error](
const ErrorInfoBase &ei) {
5762 error +=
" " + ei.message();
5767 module = wrappedModule.get().release();
5769 if (moduleArch.empty())
5770 moduleArch = getTargetArch(module->getTargetTriple());
5772 if (availableArchs.empty())
5773 availableArchs.insert(moduleArch);
5775 if (moduleArch != arch)
5777 error =
"The module's CPU architecture \"" + moduleArch +
"\" doesn't match the compiler's CPU architecture \"" + arch +
"\"";
5793 bool VuoCompiler::writeModuleToBitcode(Module *module,
string outputPath)
5796 raw_string_ostream verifyOut(str);
5797 if (llvm::verifyModule(*module, &verifyOut))
5799 VUserLog(
"Error: Module verification failed:\n%s", verifyOut.str().c_str());
5804 if (module->getTargetTriple().empty())
5805 setTargetForModule(module, getProcessTarget());
5807 std::error_code err;
5808 raw_fd_ostream out(outputPath.c_str(), err, sys::fs::F_None);
5811 VUserLog(
"Error: Couldn't open file '%s' for writing: %s", outputPath.c_str(), err.message().c_str());
5814 llvm::WriteBitcodeToFile(module, out);
5825 void VuoCompiler::setTargetForModule(Module *module,
string targetTriple)
5828 llvm::Triple triple(targetTriple);
5829 if (triple.isMacOSX())
5830 triple.setOSName(
"macosx10.10.0");
5832 module->setTargetTriple(triple.str());
5835 auto target = TargetRegistry::lookupTarget(module->getTargetTriple(), error);
5838 VUserLog(
"Error: Couldn't look up target: %s", error.c_str());
5842 auto targetMachine = target->createTargetMachine(module->getTargetTriple(),
"",
"", TargetOptions(), Optional<Reloc::Model>());
5845 VUserLog(
"Error: Couldn't create targetMachine.");
5849 module->setDataLayout(targetMachine->createDataLayout());
5851 delete targetMachine;
5858 string VuoCompiler::getTargetArch(
string target)
5860 auto hyphen = target.find(
'-');
5861 if (hyphen == string::npos)
5864 return target.substr(0, hyphen);
5870 string VuoCompiler::getProcessTarget(
void)
5876 llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
5879 if (triple.isMacOSX())
5881 unsigned int major, minor, micro;
5882 if (triple.getMacOSXVersion(major, minor, micro))
5884 ostringstream osVersion;
5885 osVersion <<
"macosx" << major <<
"." << minor <<
"." << micro;
5886 triple.setOSName(osVersion.str());
5890 return triple.str();
5901 Module *llvmModule = module->
getModule();
5930 delete baseNodeClass;
5963 if (nodeClassForNode)
5964 return nodeClassForNode->
newNode(title, x, y);
5978 if (nodeClassForNode)
5979 return nodeClassForNode->
newNode(nodeToCopyMetadataFrom);
5990 return createPublishedNode(nodeClassName, publishedInputPorts);
5999 return createPublishedNode(nodeClassName, publishedOutputPorts);
6005 VuoNode * VuoCompiler::createPublishedNode(
const string &nodeClassName,
const vector<VuoPublishedPort *> &publishedPorts)
6013 for (
size_t i = 0; i < publishedPorts.size(); ++i)
6015 VuoType *publishedPortType =
static_cast<VuoCompilerPort *
>(publishedPorts[i]->getCompiler())->getDataVuoType();
6019 set<VuoPort *> nodePorts;
6023 nodePorts.insert(inputPort);
6026 nodePorts.insert(outputPort);
6031 nodePorts.insert(inputPort);
6034 for (
VuoPort *port : nodePorts)
6041 reifyGenericPortTypes(node);
6052 dispatch_sync(environmentQueue, ^{
6053 if (environments.size() >= 5)
6054 environments.at(3).at(0)->addExpatriateSourceFile(sourcePath);
6064 dispatch_sync(environmentQueue, ^{
6065 if (environments.size() >= 5)
6067 environments.at(3).at(0)->removeExpatriateSourceFile(sourcePath);
6069 set<string> sourcesRemoved;
6070 sourcesRemoved.insert(getModuleKeyForPath(sourcePath));
6071 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), set<string>(), sourcesRemoved,
6072 false, false, environments.at(3).at(0), nullptr, nullptr,
"");
6095 string sourcePathCopy = sourcePath;
6096 string sourceCodeCopy = sourceCode;
6098 dispatch_async(environmentQueue, ^{
6100 ModuleInfo *sourceInfo = NULL;
6102 for (
const vector<Environment *> &envs : environments)
6104 for (Environment *env : envs)
6106 ModuleInfo *potentialSourceInfo = env->listSourceFile(nodeClassName);
6109 sourceInfo = potentialSourceInfo;
6118 bool shouldRecompileSourcesIfUnchanged;
6119 if (! sourceCodeCopy.empty())
6121 sourceInfo->setSourceCode(sourceCodeCopy);
6122 sourceInfo->setSourceCodeOverridden(
true);
6124 shouldRecompileSourcesIfUnchanged =
false;
6128 sourceInfo->revertSourceCode();
6129 sourceInfo->setSourceCodeOverridden(
false);
6131 shouldRecompileSourcesIfUnchanged =
true;
6133 sourceInfo->setAttempted(
false);
6134 sourceInfo->setLastModifiedToNow();
6136 set<string> sourcesModified;
6137 sourcesModified.insert(nodeClassName);
6139 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), sourcesModified, set<string>(),
6140 false, shouldRecompileSourcesIfUnchanged,
nullptr,
nullptr,
nullptr,
"");
6179 set<string> nodeClassNameSet;
6180 nodeClassNameSet.insert(nodeClassName);
6181 loadModulesIfNeeded(nodeClassNameSet);
6186 void (^envGetNodeClass)(Environment *) = ^
void (Environment *env) {
6191 applyToAllEnvironments(envGetNodeClass);
6202 loadModulesIfNeeded();
6204 __block map<string, VuoCompilerNodeClass *> nodeClasses;
6205 void (^envGetNodeClasses)(Environment *) = ^
void (Environment *env) {
6206 map<string, VuoCompilerNodeClass *> result = env->getNodeClasses();
6207 nodeClasses.insert(result.begin(), result.end());
6209 applyToInstalledEnvironments(envGetNodeClasses);
6220 set<string> typeNameSet;
6221 typeNameSet.insert(typeName);
6222 loadModulesIfNeeded(typeNameSet);
6225 void (^envGetType)(Environment *) = ^
void (Environment *env) {
6230 applyToInstalledEnvironments(envGetType);
6252 loadModulesIfNeeded();
6254 __block map<string, VuoCompilerType *> types;
6255 void (^envGetTypes)(Environment *) = ^
void (Environment *env) {
6256 map<string, VuoCompilerType *> result = env->getTypes();
6257 types.insert(result.begin(), result.end());
6259 applyToInstalledEnvironments(envGetTypes);
6270 set<string> libraryNameSet;
6271 libraryNameSet.insert(libraryModuleName);
6272 loadModulesIfNeeded(libraryNameSet);
6275 void (^envGetLibraryModule)(Environment *) = ^
void (Environment *env) {
6280 applyToInstalledEnvironments(envGetLibraryModule);
6292 loadModulesIfNeeded();
6294 __block map<string, VuoCompilerModule *> libraryModules;
6295 void (^envGetLibraryModules)(Environment *) = ^
void (Environment *env) {
6296 map<string, VuoCompilerModule *> result = env->getLibraryModules();
6297 libraryModules.insert(result.begin(), result.end());
6299 applyToInstalledEnvironments(envGetLibraryModules);
6300 return libraryModules;
6310 loadModulesIfNeeded();
6312 __block map<string, VuoNodeSet *> nodeSets;
6313 void (^envGetNodeSets)(Environment *) = ^
void (Environment *env) {
6314 map<string, VuoNodeSet *> result = env->getNodeSets();
6315 nodeSets.insert(result.begin(), result.end());
6317 applyToInstalledEnvironments(envGetNodeSets);
6328 loadModulesIfNeeded();
6331 void (^envFindNodeSet)(Environment *) = ^
void (Environment *env) {
6336 applyToInstalledEnvironments(envFindNodeSet);
6346 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
6351 applyToAllEnvironments(envFindModule);
6368 map<string, VuoCompilerNodeClass *> nodeClasses =
getNodeClasses();
6369 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
6376 else if (format ==
"path")
6380 else if (format ==
"dot")
6398 vector<string> VuoCompiler::getCoreVuoDependencies(
void)
6400 vector<string> dependencies;
6402 dependencies.push_back(
"VuoHeap");
6403 dependencies.push_back(
"VuoApp");
6405 dependencies.push_back(
"zmq");
6406 dependencies.push_back(
"json-c");
6407 dependencies.push_back(
"objc");
6408 dependencies.push_back(
"c");
6409 dependencies.push_back(
"AppKit.framework");
6412 dependencies.push_back(LLVM_ROOT
"/lib/libprofile_rt.dylib");
6414 return dependencies;
6420 string VuoCompiler::getRuntimeMainDependency(
void)
6422 return "VuoRuntimeMain.o";
6432 string VuoCompiler::getRuntimeDependency(
void)
6434 return "VuoRuntime.o";
6445 if (! vuoFrameworkInProgressPath.empty())
6446 return vuoFrameworkInProgressPath;
6454 string VuoCompiler::getClangPath(
void)
6465 string dir, moduleKey, ext;
6473 while (nodeClassNameParts.size() > 1 && nodeClassNameParts.back() == ext)
6474 nodeClassNameParts.pop_back();
6477 for (
string &part : nodeClassNameParts)
6481 if (nodeClassNameParts.size() == 1)
6482 nodeClassNameParts.insert(nodeClassNameParts.begin(),
"isf");
6496 __block
bool isLocal =
false;
6498 dispatch_sync(environmentQueue, ^{
6499 if (environments.size() >= 5)
6500 isLocal = environments.at(3).at(0)->findModule(moduleKey);
6514 return lastCompositionBaseDir.empty() ?
"" : lastCompositionBaseDir +
"/Modules";
6529 return lastCompositionBaseDir;
6535 void VuoCompiler::addModuleSearchPath(
string path)
6537 dispatch_sync(environmentQueue, ^{
6538 environments.back().at(0)->addModuleSearchPath(path);
6548 dispatch_sync(environmentQueue, ^{
6558 dispatch_sync(environmentQueue, ^{
6568 dispatch_sync(environmentQueue, ^{
6578 this->telemetry = telemetry;
6586 this->isVerbose = isVerbose;
6596 if (VuoPro::getProAccess())
6598 _shouldShowSplashWindow =
false;
6603 _shouldShowSplashWindow = potentiallyShow;
6611 return _shouldShowSplashWindow;
6617 void VuoCompiler::setClangPath(
const string &clangPath)
6619 this->clangPath = clangPath;
6628 return (vuoFrameworkPath.empty() ?
6629 VUO_BUILD_DIR
"/bin/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader" :
6630 vuoFrameworkPath +
"/Helpers/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader");
6636 string VuoCompiler::getCompositionStubPath(
void)
6639 return (vuoFrameworkPath.empty() ?
6640 VUO_BUILD_DIR
"/lib/libVuoCompositionStub.dylib" :
6641 vuoFrameworkPath +
"/Modules/libVuoCompositionStub.dylib");
6647 string VuoCompiler::getCachePathForComposition(
const string compositionDir)
6649 string modifierLetterColon(
"꞉");
6650 string cachedModulesName = compositionDir;
6660 __block vector<string> moduleSearchPaths;
6661 void (^envGetModuleSearchPaths)(Environment *) = ^
void (Environment *env) {
6662 vector<string> result = env->getModuleSearchPaths();
6663 moduleSearchPaths.insert(moduleSearchPaths.end(), result.begin(), result.end());
6665 applyToInstalledEnvironments(envGetModuleSearchPaths);
6667 __block vector<string> headerSearchPaths;
6668 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
6669 vector<string> result = env->getHeaderSearchPaths();
6670 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
6672 applyToInstalledEnvironments(envGetHeaderSearchPaths);
6674 __block vector<string> librarySearchPaths;
6675 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
6676 vector<string> result = env->getLibrarySearchPaths();
6677 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
6679 applyToInstalledEnvironments(envGetLibrarySearchPaths);
6681 __block vector<string> frameworkSearchPaths;
6682 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
6683 vector<string> result = env->getFrameworkSearchPaths();
6684 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
6686 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
6688 fprintf(stderr,
"Module (node class, type, library) search paths:\n");
6689 for (vector<string>::iterator i = moduleSearchPaths.begin(); i != moduleSearchPaths.end(); ++i)
6690 fprintf(stderr,
" %s\n", (*i).c_str());
6691 fprintf(stderr,
"Header search paths:\n");
6692 for (vector<string>::iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
6693 fprintf(stderr,
" %s\n", (*i).c_str());
6694 fprintf(stderr,
"Other library search paths:\n");
6695 for (vector<string>::iterator i = librarySearchPaths.begin(); i != librarySearchPaths.end(); ++i)
6696 fprintf(stderr,
" %s\n", (*i).c_str());
6697 fprintf(stderr,
"Other framework search paths:\n");
6698 for (vector<string>::iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
6699 fprintf(stderr,
" %s\n", (*i).c_str());
6700 fprintf(stderr,
"Framework path:\n");
6703 fprintf(stderr,
"Clang path:\n");
6704 if (! getClangPath().empty())
6705 fprintf(stderr,
" %s\n", getClangPath().c_str());
6721 string directory, file, extension;
6725 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6727 remove(compiledCompositionPath.c_str());
6756 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/" + processName +
".vuo";
6762 remove(compiledCompositionPath.c_str());
6786 string directory, file, extension;
6789 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6792 remove(compiledCompositionPath.c_str());
6821 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/UntitledComposition.vuo";
6827 remove(compiledCompositionPath.c_str());
6840 pendingDataQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.pending", 0);
6845 LoadedModulesData *data = dequeueData();
6852 void VuoCompilerDelegate::enqueueData(LoadedModulesData *data)
6854 dispatch_sync(pendingDataQueue, ^{
6855 pendingData.push_back(data);
6862 VuoCompilerDelegate::LoadedModulesData * VuoCompilerDelegate::dequeueData(
void)
6864 __block LoadedModulesData *ret;
6865 dispatch_sync(pendingDataQueue, ^{
6866 ret = pendingData.front();
6867 pendingData.pop_front();
6876 VuoCompilerDelegate::LoadedModulesData::LoadedModulesData(
const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
6879 referenceCountQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.reference", 0);
6882 this->modulesModified = modulesModified;
6883 this->modulesRemoved = modulesRemoved;
6884 this->issues = issues;
6890 VuoCompilerDelegate::LoadedModulesData::~LoadedModulesData(
void)
6894 for (set< pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); ++i)
6897 for (set<VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); ++i)
6904 void VuoCompilerDelegate::LoadedModulesData::retain(
void)
6906 dispatch_sync(referenceCountQueue, ^{
6914 void VuoCompilerDelegate::LoadedModulesData::release(
void)
6916 dispatch_sync(referenceCountQueue, ^{
6918 if (referenceCount == 0) {