15#include <CoreFoundation/CoreFoundation.h>
50map<string, VuoFileUtilities::File *> VuoCompiler::Environment::moduleCacheFileForLocking;
51dispatch_queue_t VuoCompiler::Environment::moduleCacheBuildingQueue = dispatch_queue_create(
"org.vuo.compiler.cache", NULL);
52const string VuoCompiler::Environment::pidCacheDirPrefix =
"pid-";
53set<VuoCompiler *> VuoCompiler::allCompilers;
54dispatch_queue_t VuoCompiler::environmentQueue = dispatch_queue_create(
"org.vuo.compiler.environment", NULL);
55map<string, vector< vector<VuoCompiler::Environment *> > > VuoCompiler::sharedEnvironments;
56map<string, map<string, vector<VuoCompiler::Environment *> > > VuoCompiler::environmentsForCompositionFamily;
57dispatch_group_t VuoCompiler::moduleSourceCompilersExistGlobally = dispatch_group_create();
58string VuoCompiler::vuoFrameworkInProgressPath;
67static void __attribute__((constructor)) VuoCompiler_init(
void)
70 struct rlimit rl{OPEN_MAX, OPEN_MAX};
71 getrlimit(RLIMIT_NOFILE, &rl);
72 rl.rlim_cur =
MIN(OPEN_MAX, rl.rlim_max);
73 if (setrlimit(RLIMIT_NOFILE, &rl))
74 VUserLog(
"Warning: Couldn't set open-files limit: %s", strerror(errno));
77 llvmQueue = dispatch_queue_create(
"org.vuo.compiler.llvm", NULL);
81 llvm::InitializeAllTargetMCs();
82 llvm::InitializeAllTargets();
91 raw_string_ostream stream(message);
92 DiagnosticPrinterRawOStream printer(stream);
95 if (! message.empty())
97 const char *severityName;
98 if (DI.getSeverity() == DS_Error)
99 severityName =
"error";
100 else if (DI.getSeverity() == DS_Warning)
101 severityName =
"warning";
103 severityName =
"note";
105 VuoLog(
VuoLog_moduleName, __FILE__, __LINE__,
"llvmDiagnosticHandler",
"%s: %s", severityName, message.c_str());
139VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
const string &relativePath,
140 bool isSourceFile,
bool isSubcomposition)
143 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
149VuoCompiler::ModuleInfo::ModuleInfo(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
150 bool isSourceFile,
bool isSubcomposition)
152 initialize(environment, searchPath, file, isSourceFile, isSubcomposition);
158void VuoCompiler::ModuleInfo::initialize(Environment *environment,
const string &searchPath,
VuoFileUtilities::File *file,
159 bool isSourceFile,
bool isSubcomposition)
161 this->environment = environment;
162 this->searchPath = searchPath;
165 sourceCodeOverridden =
false;
167 longestDownstreamPath = 0;
177 loading = dispatch_group_create();
180 if (isSubcomposition)
194VuoCompiler::ModuleInfo::~ModuleInfo(
void)
203 dispatch_release(loading);
206VuoCompiler::Environment * VuoCompiler::ModuleInfo::getEnvironment(
void)
const
211string VuoCompiler::ModuleInfo::getSearchPath(
void)
const
216string VuoCompiler::ModuleInfo::getModuleKey(
void)
const
226string VuoCompiler::ModuleInfo::getSourceCode(
void)
const
231void VuoCompiler::ModuleInfo::setSourceCode(
const string &sourceCode)
233 this->sourceCode = sourceCode;
236void VuoCompiler::ModuleInfo::revertSourceCode(
void)
241bool VuoCompiler::ModuleInfo::isSourceCodeOverridden(
void)
const
243 return sourceCodeOverridden;
246void VuoCompiler::ModuleInfo::setSourceCodeOverridden(
bool overridden)
248 sourceCodeOverridden = overridden;
251bool VuoCompiler::ModuleInfo::isNewerThan(ModuleInfo *other)
const
253 return lastModified > other->lastModified;
256bool VuoCompiler::ModuleInfo::isNewerThan(
unsigned long ageInSeconds)
const
258 return lastModified > ageInSeconds;
261bool VuoCompiler::ModuleInfo::isOlderThan(
unsigned long ageInSeconds)
const
263 return lastModified < ageInSeconds;
266void VuoCompiler::ModuleInfo::setLastModifiedToNow(
void)
269 gettimeofday(&t, NULL);
270 lastModified = t.tv_sec;
273set<string> VuoCompiler::ModuleInfo::getContainedNodeClasses(
void)
const
275 return containedNodeClasses;
278int VuoCompiler::ModuleInfo::getLongestDownstreamPath(
void)
const
280 return longestDownstreamPath;
283void VuoCompiler::ModuleInfo::setLongestDownstreamPath(
int pathLength)
285 longestDownstreamPath = pathLength;
288bool VuoCompiler::ModuleInfo::getAttempted(
void)
const
293void VuoCompiler::ModuleInfo::setAttempted(
bool attempted)
295 this->attempted = attempted;
298dispatch_group_t VuoCompiler::ModuleInfo::getLoadingGroup(
void)
const
303void VuoCompiler::ModuleInfo::dump()
const
305 fprintf(stderr,
"module %s:\n"
306 "\tloadingGroup=%p\n"
311 "\tsourceCodeOverridden=%d\n"
313 "\tcontainedNodeClasses:\n",
318 environment->getCompiledModuleCachePath().c_str(),
322 sourceCodeOverridden,
324 for (
auto i: containedNodeClasses)
325 fprintf(stderr,
"\t\t%s\n", i.c_str());
328VuoCompiler::DependencyGraphVertex * VuoCompiler::DependencyGraphVertex::vertexForDependency(
const string &dependency,
VuoDirectedAcyclicGraph *graph)
332 return dynamic_cast<DependencyGraphVertex *
>(v);
334 DependencyGraphVertex *vv =
new DependencyGraphVertex();
335 vv->dependency = dependency;
336 vv->environment = NULL;
337 vv->compatible =
true;
341string VuoCompiler::DependencyGraphVertex::getDependency(
void)
346VuoCompiler::Environment * VuoCompiler::DependencyGraphVertex::getEnvironment(
void)
351void VuoCompiler::DependencyGraphVertex::setEnvironment(Environment *environment)
353 this->environment = environment;
356string VuoCompiler::DependencyGraphVertex::key(
void)
368VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos,
369 const string &overriddenCompiledModuleCachePath)
371 this->allModuleInfos = allModuleInfos;
372 this->overriddenCompiledModuleCachePath = overriddenCompiledModuleCachePath;
373 hasSearchModuleKeys =
false;
384VuoCompiler::ModuleInfoIterator::ModuleInfoIterator(map<
string, map<string, ModuleInfo *> > *allModuleInfos,
385 const string &overriddenCompiledModuleCachePath,
386 const set<string> &searchModuleKeys)
388 this->allModuleInfos = allModuleInfos;
389 this->overriddenCompiledModuleCachePath = overriddenCompiledModuleCachePath;
390 this->searchModuleKeys = searchModuleKeys;
391 hasSearchModuleKeys =
true;
400void VuoCompiler::ModuleInfoIterator::initialize(
void)
402 currSearchPath = allModuleInfos->begin();
403 hasCurrModuleKey =
false;
405 if (! overriddenCompiledModuleCachePath.empty())
407 auto i = allModuleInfos->find(overriddenCompiledModuleCachePath);
408 if (i != allModuleInfos->end())
410 std::transform(i->second.begin(), i->second.end(),
411 std::inserter(overriddenModuleKeys, overriddenModuleKeys.begin()),
412 [](
const pair<string, ModuleInfo *> &p) { return p.first; });
422VuoCompiler::ModuleInfo * VuoCompiler::ModuleInfoIterator::next(
void)
424 for ( ; currSearchPath != allModuleInfos->end(); ++currSearchPath)
426 if (! hasCurrModuleKey)
428 currModuleKey = currSearchPath->second.begin();
429 hasCurrModuleKey =
true;
432 bool isOverriddenCompiledModuleCachePath = ! overriddenCompiledModuleCachePath.empty() &&
435 for ( ; currModuleKey != currSearchPath->second.end(); ++currModuleKey)
437 if ((! hasSearchModuleKeys || searchModuleKeys.find(currModuleKey->first) != searchModuleKeys.end()) &&
438 (isOverriddenCompiledModuleCachePath || overriddenModuleKeys.find(currModuleKey->first) == overriddenModuleKeys.end()))
440 ModuleInfo *moduleInfo = currModuleKey->second;
446 hasCurrModuleKey =
false;
455VuoCompiler::Environment::Environment(
string target,
bool builtIn,
bool generated)
456 : target(target), builtIn(builtIn), generated(generated)
458 compilersToNotifyQueue = dispatch_queue_create(
"org.vuo.compiler.notify", 0);
459 moduleSearchPathContentsChangedQueue = dispatch_queue_create(
"org.vuo.compiler.watch", 0);
460 lastModuleCacheRebuild = 0;
461 isModuleCacheableDataDirty =
false;
462 isModuleCacheInitialized =
false;
463 isModuleCacheAvailable =
false;
472VuoCompiler::Environment::~Environment(
void)
474 stopWatchingModuleSearchPaths();
475 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{});
477 dispatch_release(moduleSearchPathContentsChangedQueue);
478 dispatch_release(compilersToNotifyQueue);
480 for (map<string, VuoCompilerNodeClass *>::iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
481 destroyModule(i->second);
483 for (map<string, VuoCompilerType *>::iterator i = types.begin(); i != types.end(); ++i)
484 destroyModule(i->second);
486 for (map<string, VuoCompilerModule *>::iterator i = libraryModules.begin(); i != libraryModules.end(); ++i)
487 destroyModule(i->second);
489 for (set<VuoCompilerGenericType *>::iterator i = genericTypes.begin(); i != genericTypes.end(); ++i)
491 VuoType *base = (*i)->getBase();
496 for (map<string, VuoNodeSet *>::iterator i = nodeSetForName.begin(); i != nodeSetForName.end(); ++i)
499 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
500 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
503 for (map<
string, map<string, ModuleInfo *> >::iterator i = sourceFilesAtSearchPath.begin(); i != sourceFilesAtSearchPath.end(); ++i)
504 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
507 delete dependencyGraph;
508 delete compositionDependencyGraph;
514string VuoCompiler::Environment::getTarget()
522void VuoCompiler::Environment::addCompilerToNotify(
VuoCompiler *compiler)
524 dispatch_sync(compilersToNotifyQueue, ^{
525 compilersToNotify.insert(compiler);
532void VuoCompiler::Environment::removeCompilerToNotify(
VuoCompiler *compiler)
534 dispatch_sync(compilersToNotifyQueue, ^{
535 compilersToNotify.erase(compiler);
544map<string, VuoCompilerNodeClass *> VuoCompiler::Environment::getNodeClasses(
void)
556 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
557 if (nodeClassIter != nodeClasses.end())
558 return nodeClassIter->second;
571 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
572 if (nodeClassIter != nodeClasses.end())
574 nodeClass = nodeClassIter->second;
576 nodeClasses.erase(nodeClassIter);
577 removeFromDependencyGraph(nodeClass);
589map<string, VuoCompilerType *> VuoCompiler::Environment::getTypes(
void)
599VuoCompilerType * VuoCompiler::Environment::getType(
const string &moduleKey)
601 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
602 if (typeIter != types.end())
603 return typeIter->second;
613map<string, VuoNodeSet *> VuoCompiler::Environment::getNodeSets(
void)
615 return nodeSetForName;
623VuoCompilerModule *VuoCompiler::Environment::getLibraryModule(
const string &libraryModuleName)
625 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(libraryModuleName);
626 if (libraryIter != libraryModules.end())
627 return libraryIter->second;
637map<string, VuoCompilerModule *> VuoCompiler::Environment::getLibraryModules(
void)
639 return libraryModules;
650 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
651 if (nodeClassIter != nodeClasses.end())
652 return nodeClassIter->second;
654 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
655 if (typeIter != types.end())
656 return typeIter->second;
658 map<string, VuoCompilerModule *>::iterator libraryIter = libraryModules.find(moduleKey);
659 if (libraryIter != libraryModules.end())
660 return libraryIter->second;
670VuoNodeSet * VuoCompiler::Environment::findNodeSet(
const string &name)
673 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(name);
674 if (nodeSetIter != nodeSetForName.end())
675 return nodeSetIter->second;
686void VuoCompiler::Environment::addModuleSearchPath(
const string &path,
bool shouldWatch)
688 moduleSearchPaths.push_back(path);
690 updateModulesAtSearchPath(path);
691 updateSourceFilesAtSearchPath(path);
694 startWatchingModuleSearchPath(path);
702vector<string> VuoCompiler::Environment::getModuleSearchPaths(
void)
704 return moduleSearchPaths;
712void VuoCompiler::Environment::addHeaderSearchPath(
const string &path)
714 headerSearchPaths.push_back(path);
722vector<string> VuoCompiler::Environment::getHeaderSearchPaths(
void)
724 return headerSearchPaths;
732void VuoCompiler::Environment::addLibrarySearchPath(
const string &path)
734 librarySearchPaths.push_back(path);
742vector<string> VuoCompiler::Environment::getLibrarySearchPaths(
void)
744 return librarySearchPaths;
752void VuoCompiler::Environment::addFrameworkSearchPath(
const string &path)
754 frameworkSearchPaths.push_back(path);
762vector<string> VuoCompiler::Environment::getFrameworkSearchPaths(
void)
764 return frameworkSearchPaths;
769 return dependencyGraph;
774 return compositionDependencyGraph;
782void VuoCompiler::Environment::setModuleCachePath(
const string &path,
bool shouldAddModuleSearchPath)
784 moduleCachePath = path;
786 if (shouldAddModuleSearchPath)
788 addModuleSearchPath(getCompiledModuleCachePath(),
false);
789 addModuleSearchPath(getOverriddenCompiledModuleCachePath(),
false);
798string VuoCompiler::Environment::getCompiledModuleCachePath(
void)
800 return (moduleCachePath.empty() ?
"" : moduleCachePath +
"/Modules/" + VuoCompiler::getTargetArch(target));
808string VuoCompiler::Environment::getOverriddenCompiledModuleCachePath(
void)
810 if (moduleCachePath.empty())
816 string dir, moduleCacheDirName, ext;
819 return (
VuoFileUtilities::getCachePath() +
"/" + pidCacheDirPrefix + pid.str() +
"/" + moduleCacheDirName +
"/Modules/" + VuoCompiler::getTargetArch(target));
829void VuoCompiler::Environment::addExpatriateSourceFile(
const string &sourcePath)
831 expatriateSourceFiles.push_back(sourcePath);
833 if (find(moduleSearchPaths.begin(), moduleSearchPaths.end(),
"") == moduleSearchPaths.end())
834 moduleSearchPaths.push_back(
"");
836 auto iter = sourceFilesAtSearchPath.find(
"");
837 if (iter != sourceFilesAtSearchPath.end())
838 sourceFilesAtSearchPath.erase(iter);
846void VuoCompiler::Environment::removeExpatriateSourceFile(
const string &sourcePath)
848 for (
auto i = expatriateSourceFiles.begin(); i != expatriateSourceFiles.end(); ++i)
852 expatriateSourceFiles.erase(i);
854 auto iter = sourceFilesAtSearchPath.find(
"");
855 if (iter != sourceFilesAtSearchPath.end())
856 sourceFilesAtSearchPath.erase(iter);
875void VuoCompiler::Environment::updateModulesAtSearchPath(
const string &path)
877 if (moduleFilesAtSearchPath.find(path) != moduleFilesAtSearchPath.end())
880 set<string> moduleExtensions;
881 moduleExtensions.insert(
"vuonode");
882 moduleExtensions.insert(
"vuonode+");
883 moduleExtensions.insert(
"bc");
884 moduleExtensions.insert(
"bc+");
885 set<string> archiveExtensions;
886 archiveExtensions.insert(
"vuonode");
889 map<string, ModuleInfo *> fileForModuleKey;
890 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
898 ModuleInfo *m =
new ModuleInfo(
this, path, moduleFile,
false,
false);
899 fileForModuleKey[m->getModuleKey()] = m;
902 if (path == getCompiledModuleCachePath())
904 for (map<string, ModuleInfo *>::iterator i = fileForModuleKey.begin(); i != fileForModuleKey.end(); )
906 ModuleInfo *sourceInfo = listSourceFile(i->first);
907 if (! sourceInfo || sourceInfo->isNewerThan(i->second))
909 ModuleInfo *m = i->second;
912 fileForModuleKey.erase(i++);
919 moduleFilesAtSearchPath[path] = fileForModuleKey;
927void VuoCompiler::Environment::updateModuleAtSearchPath(
const string &moduleSearchPath,
const string &moduleRelativePath)
929 string dir, file, ext;
932 set<string> moduleExtensions;
933 moduleExtensions.insert(ext);
934 set<string> archiveExtensions;
935 archiveExtensions.insert(
"vuonode");
939 for (set<VuoFileUtilities::File *>::iterator i = moduleFiles.begin(); i != moduleFiles.end(); ++i)
943 ModuleInfo *m =
new ModuleInfo(
this, moduleSearchPath, moduleFile,
false,
false);
944 moduleFilesAtSearchPath[moduleSearchPath][m->getModuleKey()] = m;
955void VuoCompiler::Environment::updateSourceFilesAtSearchPath(
const string &path)
957 map<string, map<string, ModuleInfo *> >::iterator sourceFilesIter = sourceFilesAtSearchPath.find(path);
958 if (sourceFilesIter != sourceFilesAtSearchPath.end())
961 set<VuoFileUtilities::File *> sourceFiles;
964 set<string> sourceExtensions;
965 sourceExtensions.insert(
"vuo");
966 sourceExtensions.insert(
"fs");
968 sourceExtensions.insert(cext.begin(), cext.end());
973 for (
const string &sourcePath : expatriateSourceFiles)
975 string dir, file, ext;
978 sourceFiles.insert(sourceFile);
982 map<string, ModuleInfo *> fileForModuleKey;
983 for (set<VuoFileUtilities::File *>::iterator i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
987 string dir, moduleKey, ext;
989 bool isSubcomposition = (ext ==
"vuo");
992 if (path.empty() && !sourceFile->
exists())
995 ModuleInfo *m =
new ModuleInfo(
this, path, sourceFile,
true, isSubcomposition);
996 if (fileForModuleKey.find(m->getModuleKey()) != fileForModuleKey.end())
997 VUserLog(
"Warning: Conflicting source files for module %s are installed at %s", m->getModuleKey().c_str(), path.c_str());
998 fileForModuleKey[m->getModuleKey()] = m;
1000 if (isSubcomposition)
1002 DependencyGraphVertex *compositionVertex = DependencyGraphVertex::vertexForDependency(moduleKey, compositionDependencyGraph);
1003 compositionDependencyGraph->addVertex(compositionVertex);
1005 compositionVertex->setEnvironment(
this);
1007 set<string> dependencies = m->getContainedNodeClasses();
1008 for (set<string>::iterator j = dependencies.begin(); j != dependencies.end(); ++j)
1010 DependencyGraphVertex *dependencyVertex = DependencyGraphVertex::vertexForDependency(*j, compositionDependencyGraph);
1011 compositionDependencyGraph->addEdge(compositionVertex, dependencyVertex);
1016 sourceFilesAtSearchPath[path] = fileForModuleKey;
1024VuoCompiler::ModuleInfo * VuoCompiler::Environment::listModule(
const string &moduleKey)
1026 for (
const auto &moduleFiles : moduleFilesAtSearchPath)
1028 map<string, ModuleInfo *>::const_iterator foundIter = moduleFiles.second.find(moduleKey);
1029 if (foundIter != moduleFiles.second.end())
1030 return foundIter->second;
1041VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listModules(
const set<string> &moduleKeys)
1043 for (
const string &path : moduleSearchPaths)
1044 updateModulesAtSearchPath(path);
1046 return ModuleInfoIterator(&moduleFilesAtSearchPath, getOverriddenCompiledModuleCachePath(), moduleKeys);
1054VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllModules(
void)
1056 for (
const string &path : moduleSearchPaths)
1057 updateModulesAtSearchPath(path);
1059 return ModuleInfoIterator(&moduleFilesAtSearchPath, getOverriddenCompiledModuleCachePath());
1067VuoCompiler::ModuleInfo * VuoCompiler::Environment::listSourceFile(
const string &moduleKey)
1069 for (
const auto &sourceFiles : sourceFilesAtSearchPath)
1071 map<string, ModuleInfo *>::const_iterator foundIter = sourceFiles.second.find(moduleKey);
1072 if (foundIter != sourceFiles.second.end())
1073 return foundIter->second;
1084VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listSourceFiles(
const set<string> &moduleKeys)
1086 for (
const string &path : moduleSearchPaths)
1087 updateSourceFilesAtSearchPath(path);
1089 return ModuleInfoIterator(&sourceFilesAtSearchPath,
"", moduleKeys);
1097VuoCompiler::ModuleInfoIterator VuoCompiler::Environment::listAllSourceFiles(
void)
1099 for (
const string &path : moduleSearchPaths)
1100 updateSourceFilesAtSearchPath(path);
1102 return ModuleInfoIterator(&sourceFilesAtSearchPath,
"");
1108vector<string> VuoCompiler::Environment::getBuiltInModuleSearchPaths(
void)
1110 vector<string> builtInModuleSearchPaths;
1112 string vuoFrameworkPath = getVuoFrameworkPath();
1113 if (! vuoFrameworkPath.empty())
1115 builtInModuleSearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1119 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/library");
1120 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/node");
1121 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type");
1122 builtInModuleSearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1125 return builtInModuleSearchPaths;
1131vector<string> VuoCompiler::Environment::getBuiltInHeaderSearchPaths(
void)
1133 vector<string> builtInHeaderSearchPaths;
1135 string vuoFrameworkPath = getVuoFrameworkPath();
1136 if (! vuoFrameworkPath.empty())
1138 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/Headers/lib/c++/v1");
1139 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers");
1140 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos");
1141 builtInHeaderSearchPaths.push_back(vuoFrameworkPath +
"/Headers/macos/pthread");
1145 builtInHeaderSearchPaths.push_back(LLVM_ROOT
"/include/c++/v1");
1146 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/library");
1147 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/node");
1148 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type");
1149 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/type/list");
1150 builtInHeaderSearchPaths.push_back(VUO_SOURCE_DIR
"/runtime");
1151 builtInHeaderSearchPaths.push_back(JSONC_ROOT
"/include");
1154 return builtInHeaderSearchPaths;
1160vector<string> VuoCompiler::Environment::getBuiltInLibrarySearchPaths(
void)
1162 vector<string> builtInLibrarySearchPaths;
1164 string vuoFrameworkPath = getVuoFrameworkPath();
1165 if (! vuoFrameworkPath.empty())
1167 builtInLibrarySearchPaths.push_back(vuoFrameworkPath +
"/Modules");
1170 builtInLibrarySearchPaths.push_back(OPENSSL_ROOT
"/lib");
1174 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/library");
1175 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/node");
1176 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type");
1177 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/type/list");
1178 builtInLibrarySearchPaths.push_back(VUO_BUILD_DIR
"/runtime");
1181 builtInLibrarySearchPaths.insert(builtInLibrarySearchPaths.end(), conanLibDirs.begin(), conanLibDirs.end());
1184 return builtInLibrarySearchPaths;
1190vector<string> VuoCompiler::Environment::getBuiltInFrameworkSearchPaths(
void)
1192 vector<string> builtInFrameworkSearchPaths;
1194 string vuoFrameworkPath = getVuoFrameworkPath();
1195 if (! vuoFrameworkPath.empty())
1197 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Modules/");
1198 builtInFrameworkSearchPaths.push_back(vuoFrameworkPath +
"/Frameworks/");
1201 return builtInFrameworkSearchPaths;
1210void VuoCompiler::Environment::startWatchingModuleSearchPath(
const string &moduleSearchPath)
1213 moduleSearchPathWatchers.insert(watcher);
1221void VuoCompiler::Environment::stopWatchingModuleSearchPaths(
void)
1223 for (set<VuoFileWatcher *>::iterator i = moduleSearchPathWatchers.begin(); i != moduleSearchPathWatchers.end(); ++i)
1226 moduleSearchPathWatchers.clear();
1233void VuoCompiler::Environment::fileChanged(
const string &moduleSearchPath)
1235 dispatch_sync(moduleSearchPathContentsChangedQueue, ^{
1236 moduleSearchPathContentsChanged(moduleSearchPath);
1247void VuoCompiler::Environment::moduleSearchPathContentsChanged(
const string &moduleSearchPath)
1252 __block set<string> modulesAdded;
1253 __block set<string> modulesModifed;
1254 __block set<string> modulesRemoved;
1255 __block set<string> compositionsAdded;
1256 __block set<string> compositionsModifed;
1257 __block set<string> compositionsRemoved;
1259 dispatch_sync(environmentQueue, ^{
1263 map<string, ModuleInfo *> oldModules;
1264 map<string, ModuleInfo *> oldCompositions;
1266 map<string, map<string, ModuleInfo *> >::iterator mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1267 if (mf != moduleFilesAtSearchPath.end())
1269 for (map<string, ModuleInfo *>::iterator j = mf->second.begin(); j != mf->second.end(); ++j)
1271 oldModules[j->first] = j->second;
1274 moduleFilesAtSearchPath.erase(mf);
1277 map<string, map<string, ModuleInfo *> >::iterator cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1278 if (cf != sourceFilesAtSearchPath.end())
1280 for (map<string, ModuleInfo *>::iterator j = cf->second.begin(); j != cf->second.end(); ++j)
1282 oldCompositions[j->first] = j->second;
1284 VuoDirectedAcyclicGraph::Vertex *vertex = compositionDependencyGraph->findVertex(j->first);
1285 compositionDependencyGraph->removeVertex(vertex);
1288 sourceFilesAtSearchPath.erase(cf);
1293 updateModulesAtSearchPath(moduleSearchPath);
1294 updateSourceFilesAtSearchPath(moduleSearchPath);
1298 auto omf = moduleFilesAtSearchPath.find(getOverriddenCompiledModuleCachePath());
1299 if (omf != moduleFilesAtSearchPath.end())
1301 for (
auto oldComposition : oldCompositions)
1303 for (
auto i = omf->second.begin(); i != omf->second.end(); ++i)
1305 if (i->first == oldComposition.first)
1308 omf->second.erase(i);
1317 mf = moduleFilesAtSearchPath.find(moduleSearchPath);
1318 if (mf != moduleFilesAtSearchPath.end())
1320 for (map<string, ModuleInfo *>::iterator n = mf->second.begin(); n != mf->second.end(); ++n)
1322 string moduleKey = n->first;
1324 map<string, ModuleInfo *>::iterator o = oldModules.find(moduleKey);
1325 if (o != oldModules.end())
1327 if (n->second->isNewerThan(o->second))
1329 modulesModifed.insert(moduleKey);
1333 n->second->setAttempted(o->second->getAttempted());
1337 oldModules.erase(o);
1341 modulesAdded.insert(moduleKey);
1346 cf = sourceFilesAtSearchPath.find(moduleSearchPath);
1347 if (cf != sourceFilesAtSearchPath.end())
1349 for (map<string, ModuleInfo *>::iterator n = cf->second.begin(); n != cf->second.end(); ++n)
1351 string moduleKey = n->first;
1353 map<string, ModuleInfo *>::iterator o = oldCompositions.find(moduleKey);
1354 if (o != oldCompositions.end())
1356 if (n->second->isNewerThan(o->second))
1358 compositionsModifed.insert(moduleKey);
1362 n->second->setAttempted(o->second->getAttempted());
1363 n->second->setSourceCode(o->second->getSourceCode());
1367 oldCompositions.erase(o);
1371 compositionsAdded.insert(moduleKey);
1376 for (map<string, ModuleInfo *>::iterator o = oldModules.begin(); o != oldModules.end(); ++o)
1379 modulesRemoved.insert(o->first);
1382 for (map<string, ModuleInfo *>::iterator o = oldCompositions.begin(); o != oldCompositions.end(); ++o)
1385 compositionsRemoved.insert(o->first);
1388 compilerForLoading->loadModulesAndSources(modulesAdded, modulesModifed, modulesRemoved,
1389 compositionsAdded, compositionsModifed, compositionsRemoved,
1390 false,
false,
this,
nullptr,
nullptr,
"");
1393 delete compilerForLoading;
1402void VuoCompiler::Environment::moduleFileChanged(
const string &modulePath,
const string &moduleSourceCode,
1403 std::function<
void(
void)> moduleLoadedCallback,
1407 dispatch_sync(environmentQueue, ^{
1409 string moduleDir, moduleKey, ext;
1415 bool foundOldModule =
false;
1416 auto moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1417 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1419 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1420 if (moduleIter != moduleSearchPathIter->second.end())
1422 delete moduleIter->second;
1423 moduleSearchPathIter->second.erase(moduleIter);
1424 foundOldModule =
true;
1430 updateModuleAtSearchPath(moduleDir, moduleKey +
"." + ext);
1434 bool foundNewModule =
false;
1435 moduleSearchPathIter = moduleFilesAtSearchPath.find(moduleDir);
1436 if (moduleSearchPathIter != moduleFilesAtSearchPath.end())
1438 auto moduleIter = moduleSearchPathIter->second.find(moduleKey);
1439 if (moduleIter != moduleSearchPathIter->second.end())
1441 foundNewModule =
true;
1445 set<string> modulesAdded;
1446 set<string> modulesModified;
1447 set<string> modulesRemoved;
1451 modulesModified.insert(moduleKey);
1453 else if (! foundOldModule && foundNewModule)
1455 modulesAdded.insert(moduleKey);
1457 else if (foundOldModule && ! foundNewModule)
1459 modulesRemoved.insert(moduleKey);
1462 compiler->loadModulesAndSources(modulesAdded, modulesModified, modulesRemoved,
1463 set<string>(), set<string>(), set<string>(),
1464 false,
false,
this, issues, moduleLoadedCallback, moduleSourceCode);
1472void VuoCompiler::Environment::notifyCompilers(
const set<VuoCompilerModule *> &modulesAdded,
1473 const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
1475 bool oldModulesInvalidated)
1477 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()) )
1479 set< pair<VuoCompilerModule *, VuoCompilerModule *> > invalidatedModulesModified;
1480 set<VuoCompilerModule *> invalidatedModulesRemoved;
1481 if (oldModulesInvalidated)
1483 invalidatedModulesModified = modulesModified;
1484 invalidatedModulesRemoved = modulesRemoved;
1487 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(invalidatedModulesModified, invalidatedModulesRemoved, issues);
1489 map<string, VuoCompilerModule *> modulesAddedMap;
1490 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModifiedMap;
1491 map<string, VuoCompilerModule *> modulesRemovedMap;
1493 modulesAddedMap[m->getPseudoBase()->getModuleKey()] = m;
1494 for (pair<VuoCompilerModule *, VuoCompilerModule *> m : modulesModified)
1495 modulesModifiedMap[m.first->getPseudoBase()->getModuleKey()] = m;
1497 modulesRemovedMap[m->getPseudoBase()->getModuleKey()] = m;
1499 dispatch_sync(compilersToNotifyQueue, ^{
1500 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1501 delegateData->retain();
1503 for (set<VuoCompiler *>::iterator i = compilersToNotify.begin(); i != compilersToNotify.end(); ++i) {
1504 (*i)->loadedModules(modulesAddedMap, modulesModifiedMap, modulesRemovedMap, issues, delegateData, this);
1524set<VuoCompilerModule *> VuoCompiler::Environment::loadCompiledModules(
const set<string> &moduleKeys,
const map<string, string> &sourceCodeForModule)
1526 ModuleInfoIterator modulesToLoadIter = listModules(moduleKeys);
1527 set<VuoCompilerModule *> modulesLoaded;
1529 ModuleInfo *moduleInfo;
1530 while ((moduleInfo = modulesToLoadIter.next()))
1532 string moduleKey = moduleInfo->getModuleKey();
1536 if (moduleInfo->getEnvironment() !=
this || findModule(moduleKey) || moduleInfo->getAttempted())
1539 moduleInfo->setAttempted(
true);
1546 modulesLoaded.insert(module);
1547 addToDependencyGraph(module);
1551 string searchPath = moduleInfo->getSearchPath();
1558 ModuleInfo *sourceInfo = listSourceFile(moduleKey);
1562 auto sourceCodeIter = sourceCodeForModule.find(moduleKey);
1563 if (sourceCodeIter != sourceCodeForModule.end())
1570 return modulesLoaded;
1584set<dispatch_group_t> VuoCompiler::Environment::loadSpecializedModules(
const set<string> &moduleKeys,
1587 set<dispatch_group_t > loadingGroups;
1589 for (
string moduleKey : moduleKeys)
1593 if (moduleKey.find(
".") == string::npos ||
1600 if (findModule(moduleKey))
1605 map<string, dispatch_group_t>::iterator iter = specializedModulesLoading.find(moduleKey);
1606 if (iter != specializedModulesLoading.end())
1608 loadingGroups.insert(iter->second);
1609 dispatch_retain(iter->second);
1613 dispatch_group_t loadingGroup = dispatch_group_create();
1614 specializedModulesLoading[moduleKey] = loadingGroup;
1615 loadingGroups.insert(loadingGroup);
1621 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1622 dispatch_group_async(loadingGroup, queue, ^{
1636 compiler->loadNodeClassGeneratedAtRuntime(specNodeClass,
this);
1639 if (!dependencies.empty())
1640 compiler->loadModulesIfNeeded(dependencies);
1643 dispatch_sync(environmentQueue, ^{
1644 specializedModulesLoading.erase(moduleKey);
1649 return loadingGroups;
1664set<dispatch_group_t> VuoCompiler::Environment::compileModulesFromSourceCode(
const set<string> &moduleKeys, dispatch_group_t moduleSourceCompilersExist,
1665 bool shouldRecompileIfUnchanged)
1667 ModuleInfoIterator modulesToLoadIter = listSourceFiles(moduleKeys);
1669 int environmentIndex = sharedEnvironments[target].size();
1670 for (
int i = 0; i < sharedEnvironments[target].size(); ++i)
1671 if (
this == sharedEnvironments[target].at(i).at(0))
1672 environmentIndex = i;
1674 set<dispatch_group_t> sourcesLoading;
1675 int sourcesEnqueued = 0;
1676 ModuleInfo *sourceInfo;
1677 while ((sourceInfo = modulesToLoadIter.next()))
1679 string moduleKey = sourceInfo->getModuleKey();
1681 dispatch_group_t loadingGroup = sourceInfo->getLoadingGroup();
1682 sourcesLoading.insert(loadingGroup);
1687 if (sourceInfo->getAttempted())
1692 string sourceCode = sourceInfo->getSourceCode();
1694 if (! shouldRecompileIfUnchanged)
1697 if (existingNodeClass && existingNodeClass->
getSourceCode() == sourceCode)
1703 sourceInfo->setAttempted(
true);
1705 dispatch_group_enter(loadingGroup);
1706 dispatch_group_enter(moduleSourceCompilersExist);
1707 dispatch_group_enter(moduleSourceCompilersExistGlobally);
1711 queueItem->
sourcePath = sourceInfo->getFile()->path();
1713 queueItem->
sourceFile = sourceInfo->getFile();
1714 queueItem->
cachedModulesPath = sourceInfo->isSourceCodeOverridden() ? getOverriddenCompiledModuleCachePath() : getCompiledModuleCachePath();
1717 queueItem->
priority = { environmentIndex, sourceInfo->getLongestDownstreamPath() };
1718 moduleCompilationQueue->enqueue(queueItem);
1727 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1728 dispatch_async(queue, ^{
1729 for (
int i = 0; i < sourcesEnqueued; ++i)
1732 VUserLog(
"Compiling %s", queueItem->moduleKey.c_str());
1734 dispatch_async(queue, ^{
1743 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1750 auto moduleLoadedCallback = [=](){
1751 dispatch_group_leave(queueItemForCallback->
loadingGroup);
1752 moduleCompilationQueue->completed(queueItemForCallback);
1755 string ext = queueItem->sourceFile->extension();
1766 notifyCompilers(set<VuoCompilerModule *>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues,
false);
1773 auto getType = [&compiler] (
const string &moduleKey) {
return compiler->
getType(moduleKey); };
1780 setTargetForModule(module, target);
1781 writeModuleToBitcode(module, queueItem->compiledModulePath);
1789 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1792 moduleLoadedCallback();
1800 compiler->
compileModule(queueItem->sourcePath, queueItem->compiledModulePath, vector<string>());
1810 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1820 Module *module = compiler->compileCompositionToModule(composition, queueItem->moduleKey,
false, issues);
1825 setTargetForModule(module, target);
1826 writeModuleToBitcode(module, queueItem->compiledModulePath);
1831 delete baseComposition;
1841 moduleFileChanged(queueItem->compiledModulePath, queueItem->sourceCode, moduleLoadedCallback, compiler, issues);
1845 dispatch_group_leave(moduleSourceCompilersExist);
1846 dispatch_group_leave(moduleSourceCompilersExistGlobally);
1851 return sourcesLoading;
1862set<VuoCompilerModule *> VuoCompiler::Environment::unloadCompiledModules(
const set<string> &moduleKeys)
1864 set<VuoCompilerModule *> modulesUnloaded;
1866 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1868 string moduleKey = *i;
1871 map<string, VuoCompilerNodeClass *>::iterator nodeClassIter = nodeClasses.find(moduleKey);
1872 if (nodeClassIter != nodeClasses.end())
1874 module = nodeClassIter->second;
1875 nodeClasses.erase(nodeClassIter);
1879 map<string, VuoCompilerType *>::iterator typeIter = types.find(moduleKey);
1880 if (typeIter != types.end())
1882 module = typeIter->second;
1883 types.erase(typeIter);
1887 map<string, VuoCompilerModule *>::iterator libraryModuleIter = libraryModules.find(moduleKey);
1888 if (libraryModuleIter != libraryModules.end())
1890 module = libraryModuleIter->second;
1891 libraryModules.erase(libraryModuleIter);
1898 modulesUnloaded.insert(module);
1899 removeFromDependencyGraph(module);
1904 return modulesUnloaded;
1912void VuoCompiler::Environment::deleteModulesCompiledFromSourceCode(
const set<string> &moduleKeys)
1914 for (set<string>::const_iterator i = moduleKeys.begin(); i != moduleKeys.end(); ++i)
1916 string moduleKey = *i;
1918 map<string, ModuleInfo *>::iterator iter = moduleFilesAtSearchPath[getCompiledModuleCachePath()].find(moduleKey);
1919 if (iter != moduleFilesAtSearchPath[getCompiledModuleCachePath()].end())
1933 string moduleKey = moduleInfo->getModuleKey();
1947 __block
size_t inputDataBytes;
1948 __block
char *rawInputData;
1952 rawInputData = moduleInfo->getFile()->getContentsAsRawData(inputDataBytes);
1956 rawInputData = NULL;
1957 VUserLog(
"Warning: Couldn't load module '%s'. Its file may have been deleted. (%s)", moduleKey.c_str(), e.
what());
1963 char *processedInputData;
1965 processedInputData = loadModule_Pro0(moduleInfo, moduleKey, inputDataBytes, rawInputData);
1967 processedInputData = rawInputData;
1970 Module *module = NULL;
1971 set<string> moduleArchs;
1972 bool moduleParseError = !processedInputData;
1973 if (!moduleParseError)
1975 string moduleReadError;
1976 string arch = VuoCompiler::getTargetArch(target);
1977 VuoLog_status(
"Loading module \"%s\" (%s)", moduleKey.c_str(), arch.c_str());
1978 module = readModuleFromBitcodeData(processedInputData, inputDataBytes, arch, moduleArchs, moduleReadError);
1980 free(processedInputData);
1984 moduleParseError =
true;
1989 VUserLog(
"Error: Couldn't load module '%s' into %s environment: %s.", moduleKey.c_str(), arch.c_str(), moduleReadError.c_str());
1993 if (!moduleParseError)
1996 if (! moduleInfo->getFile()->isInArchive())
1997 modulePath = moduleInfo->getFile()->path();
2015 libraryModules[moduleKey] = compilerModule;
2020 map<string, VuoNodeSet *>::iterator nodeSetIter = nodeSetForName.find(nodeSet->
getName());
2021 if (nodeSetIter == nodeSetForName.end())
2023 nodeSetForName[nodeSet->
getName()] = nodeSet;
2028 nodeSet = nodeSetIter->second;
2030 compilerModule->getPseudoBase()->setNodeSet(nodeSet);
2034 loadModule_Pro1(rawInputData, processedInputData, compilerModule);
2037 compilerModule->setBuiltIn( isBuiltInOriginal() );
2039 return compilerModule;
2043 destroyLlvmModule(module);
2062 removeFromDependencyGraph(oldNodeClass);
2063 destroyModule(oldNodeClass);
2066 nodeClasses[moduleKey] = newNodeClass;
2067 addToDependencyGraph(newNodeClass);
2073 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
2074 dependencyGraph->addVertex(vertex);
2076 vertex->setEnvironment(
this);
2079 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
2081 DependencyGraphVertex *depVertex = DependencyGraphVertex::vertexForDependency(*i, dependencyGraph);
2082 dependencyGraph->addEdge(vertex, depVertex);
2086void VuoCompiler::Environment::removeFromDependencyGraph(
VuoCompilerModule *module)
2088 DependencyGraphVertex *vertex = DependencyGraphVertex::vertexForDependency(module->
getPseudoBase()->
getModuleKey(), dependencyGraph);
2089 dependencyGraph->removeVertex(vertex);
2102void VuoCompiler::Environment::reifyPortTypes(
const map<string, VuoCompilerType *> &inheritedTypes)
2104 map<string, VuoCompilerType *> availableTypes = inheritedTypes;
2105 availableTypes.insert(types.begin(), types.end());
2107 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
2113 vector<VuoPortClass *> portClasses;
2114 portClasses.insert(portClasses.end(), inputPortClasses.begin(), inputPortClasses.end());
2115 portClasses.insert(portClasses.end(), outputPortClasses.begin(), outputPortClasses.end());
2117 for (vector<VuoPortClass *>::iterator j = portClasses.begin(); j != portClasses.end(); ++j)
2137 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2138 if (reifiedTypeIter != availableTypes.end())
2141 reifiedType = reifiedTypeIter->second;
2152 for (vector<VuoCompilerTriggerDescription *>::iterator j = triggers.begin(); j != triggers.end(); ++j)
2160 map<string, VuoCompilerType *>::iterator reifiedTypeIter = availableTypes.find(typeName);
2161 if (reifiedTypeIter != availableTypes.end())
2182void VuoCompiler::Environment::getCacheableModulesAndDependencies(set<string> &cacheableModulesAndDependencies,
2183 set<string> &dylibsNeededToLinkToThisCache,
2184 set<string> &frameworksNeededToLinkToThisCache)
2186 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty)
2188 cacheableModulesAndDependencies = moduleCacheContents;
2189 dylibsNeededToLinkToThisCache = moduleCacheDylibs;
2190 frameworksNeededToLinkToThisCache = moduleCacheFrameworks;
2197 map<string, VuoCompilerModule *> allModules;
2198 allModules.insert(nodeClasses.begin(), nodeClasses.end());
2199 allModules.insert(types.begin(), types.end());
2200 allModules.insert(libraryModules.begin(), libraryModules.end());
2202 set<string> dependencies;
2203 for (map<string, VuoCompilerModule *>::iterator i = allModules.begin(); i != allModules.end(); ++i)
2205 string moduleKey = i->first;
2210 if (module->requiresPro())
2218 cacheableModulesAndDependencies.insert(moduleKey);
2221 dependencies.insert(moduleDependencies.begin(), moduleDependencies.end());
2225 if (builtIn && ! generated)
2227 vector<string> coreDependencies = getCoreVuoDependencies();
2228 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
2233 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
2235 string dependency = *i;
2236 if (allModules.find(dependency) == allModules.end())
2239 frameworksNeededToLinkToThisCache.insert(dependency);
2242 string dependencyPath = VuoCompiler::getLibraryPath(dependency, librarySearchPaths);
2243 if (! dependencyPath.empty())
2246 dylibsNeededToLinkToThisCache.insert(dependencyPath);
2248 cacheableModulesAndDependencies.insert(dependency);
2254 moduleCacheDylibs = dylibsNeededToLinkToThisCache;
2255 moduleCacheFrameworks = frameworksNeededToLinkToThisCache;
2262 if (!vuoFrameworkInProgressPath.empty())
2263 currentModuleCacheDylib +=
"-" + VuoCompiler::getTargetArch(target);
2287void VuoCompiler::Environment::useModuleCache(
bool shouldUseExistingCache,
VuoCompiler *compiler,
2288 set<string> cacheableModulesAndDependencies,
2289 set<string> dylibsNeededToLinkToCaches, set<string> frameworksNeededToLinkToCaches,
2290 unsigned long lastPrerequisiteModuleCacheRebuild)
2294 static dispatch_once_t checked = 0;
2295 static bool prelinkCache =
true;
2296 dispatch_once(&checked, ^{
2298 bool result = CFPreferencesGetAppBooleanValue(CFSTR(
"prelinkCache"), CFSTR(
"org.vuo.Editor"), &valid);
2300 prelinkCache = result;
2304 VDebugLog(
"Ignoring the module cache since the 'prelinkCache' preference is false.");
2310 if (moduleCachePath.empty())
2316 if (isModuleCacheInitialized && ! isModuleCacheableDataDirty &&
2317 (builtIn || lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild))
2319 VDebugLog(
"No need to recheck %s.", cacheDescription.c_str());
2325 VDebugLog(
"Checking if %s is up-to-date…", cacheDescription.c_str());
2327 bool isCacheUpToDate =
true;
2329 if (isModuleCacheInitialized && isModuleCacheableDataDirty)
2330 isCacheUpToDate =
false;
2332 isModuleCacheInitialized =
true;
2333 isModuleCacheableDataDirty =
false;
2336 if (!vuoFrameworkInProgressPath.empty())
2337 indexPath +=
"-" + VuoCompiler::getTargetArch(target);
2338 string dir, file, ext;
2340 string indexFileName = file +
"." + ext;
2347 if (shouldUseExistingCache)
2348 throw VuoException(
"Trying to use the existing cache, but the cache directory doesn't exist.",
false);
2351 isCacheUpToDate =
false;
2355 if (! indexFileExists)
2357 if (shouldUseExistingCache)
2358 throw VuoException(
"Trying to use the existing cache, but the cache index doesn't exist.",
false);
2361 isCacheUpToDate =
false;
2368 fileForLocking = moduleCacheFileForLocking[indexPath];
2369 if (! fileForLocking)
2372 moduleCacheFileForLocking[indexPath] = fileForLocking;
2376 VDebugLog(
"\tWarning: Couldn't lock for reading.");
2381 if (currentModuleCacheDylib.empty())
2384 if (shouldUseExistingCache && currentModuleCacheDylib.empty())
2385 throw VuoException(
"Trying to use the existing cache, but the cache dylib doesn't exist.",
false);
2389 if (isCacheUpToDate)
2390 isCacheUpToDate = lastModuleCacheRebuild >= lastPrerequisiteModuleCacheRebuild;
2394 if (isCacheUpToDate)
2399 if (shouldUseExistingCache)
2400 throw VuoException(
"Trying to use the existing cache, but the cache doesn't contain readable data.",
false);
2402 isCacheUpToDate =
false;
2408 const char separator =
'\n';
2409 if (isCacheUpToDate || shouldUseExistingCache)
2412 string index = indexFile.getContentsAsString();
2415 moduleCacheContents.clear();
2416 moduleCacheContents.insert(actualIndex.begin(), actualIndex.end());
2418 if (shouldUseExistingCache)
2420 isModuleCacheAvailable =
true;
2427 if (isCacheUpToDate)
2429 if (moduleCacheContents.size() != cacheableModulesAndDependencies.size())
2430 isCacheUpToDate =
false;
2433 set<string> contentsInBoth;
2434 std::set_intersection(moduleCacheContents.begin(), moduleCacheContents.end(),
2435 cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end(),
2436 std::inserter(contentsInBoth, contentsInBoth.begin()));
2438 if (contentsInBoth.size() != cacheableModulesAndDependencies.size())
2439 isCacheUpToDate =
false;
2445 if (isCacheUpToDate)
2449 for (map<
string, map<string, ModuleInfo *> >::iterator i = moduleFilesAtSearchPath.begin(); i != moduleFilesAtSearchPath.end(); ++i)
2451 for (map<string, ModuleInfo *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2453 if (! j->second->isOlderThan(cacheLastModified))
2455 isCacheUpToDate =
false;
2464 if (isCacheUpToDate)
2468 isModuleCacheAvailable =
true;
2479 gettimeofday(&t, NULL);
2480 lastModuleCacheRebuild = t.tv_sec;
2483 dispatch_async(moduleCacheBuildingQueue, ^{
2484 VUserLog(
"Rebuilding %s…", cacheDescription.c_str());
2486 set<Module *> modulesToLink;
2487 set<string> librariesToLink;
2488 set<string> frameworksToLink;
2490 compiler->getLinkerInputs(cacheableModulesAndDependencies, Optimization_SmallBinary, modulesToLink, librariesToLink, frameworksToLink);
2492 librariesToLink.insert(dylibsNeededToLinkToCaches.begin(), dylibsNeededToLinkToCaches.end());
2493 frameworksToLink.insert(frameworksNeededToLinkToCaches.begin(), frameworksNeededToLinkToCaches.end());
2496 bool gotLockForWriting =
false;
2501 if (! gotLockForWriting)
2502 throw VuoException(
"The cache file is being used by another process. "
2503 "If any composition windows are open from previous Vuo sessions, quit them. "
2504 "If any processes whose names start with \"VuoComposition\" or one of your composition file names appear in Activity Monitor, force-quit them.",
2508 string dir, file, ext;
2511 vector<string> rPaths = compiler->getRunPathSearchPaths(
this);
2513 compiler->link(tmpPath, modulesToLink, librariesToLink, frameworksToLink,
true, rPaths,
false, issues);
2516 VUserLog(
"Warning: May not have fully rebuilt %s for the \"faster build\" optimization:\n%s", cacheDescription.c_str(), issues->
getLongDescription(
false).c_str());
2523 getVuoFrameworkPath() +
"/Helpers/install_name_tool",
2525 currentModuleCacheDylib,
2526 currentModuleCacheDylib,
2532 if (vuoFrameworkInProgressPath.empty())
2533 adHocCodeSign(currentModuleCacheDylib);
2536 vector<string> expectedContents(cacheableModulesAndDependencies.begin(), cacheableModulesAndDependencies.end());
2545 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2547 dispatch_sync(environmentQueue, ^{
2548 moduleCacheContents = cacheableModulesAndDependencies;
2549 isModuleCacheAvailable =
true;
2555 if (gotLockForWriting)
2557 VDebugLog(
"\tWarning: Couldn't downgrade the lock back to reading.");
2559 VUserLog(
"Warning: Couldn't rebuild %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2567 if (vuoFrameworkInProgressPath.empty())
2568 VUserLog(
"Warning: Couldn't use %s for the \"faster build\" optimization: %s", cacheDescription.c_str(), e.
what());
2575void VuoCompiler::Environment::waitForModuleCachesToBuild(
void)
2577 dispatch_sync(moduleCacheBuildingQueue, ^{});
2589bool VuoCompiler::Environment::findInModuleCache(
const string &moduleOrDependency,
string &cachePath)
2591 if (isModuleCacheAvailable && moduleCacheContents.find(moduleOrDependency) != moduleCacheContents.end())
2593 cachePath = currentModuleCacheDylib;
2603string VuoCompiler::Environment::getCurrentModuleCacheDylib(
void)
2605 return currentModuleCacheDylib;
2612unsigned long VuoCompiler::Environment::getLastModuleCacheRebuild(
void)
2614 return lastModuleCacheRebuild;
2623void VuoCompiler::Environment::modulesChanged(
void)
2625 isModuleCacheableDataDirty =
true;
2626 isModuleCacheAvailable =
false;
2632bool VuoCompiler::Environment::isBuiltInOriginal()
2634 return builtIn && ! generated;
2640bool VuoCompiler::Environment::isBuiltIn()
2648bool VuoCompiler::Environment::isGenerated()
2656string VuoCompiler::Environment::getName()
2658 if (isBuiltInOriginal())
2660 else if (
this == sharedEnvironments[target][0][1])
2661 return "builtin (generated)";
2662 else if (
this == sharedEnvironments[target][1][0])
2664 else if (
this == sharedEnvironments[target][1][1])
2665 return "system (generated)";
2666 else if (
this == sharedEnvironments[target][2][0])
2668 else if (
this == sharedEnvironments[target][2][1])
2669 return "user (generated)";
2670 return "composition-local";
2676void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *))
2678 dispatch_sync(environmentQueue, ^{
2679 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2680 doForEnvironment((*i)[0]);
2688void VuoCompiler::applyToInstalledEnvironments(
void (^doForEnvironment)(Environment *,
bool *,
string),
bool *result,
string arg)
2690 dispatch_sync(environmentQueue, ^{
2691 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2692 doForEnvironment((*i)[0], result, arg);
2700void VuoCompiler::applyToAllEnvironments(
void (^doForEnvironment)(Environment *environment))
2702 dispatch_sync(environmentQueue, ^{
2703 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2704 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j) {
2705 doForEnvironment(*j);
2728 this->target = target = getProcessTarget();
2729 VDebugLog(
"%p target=%s (from current process)",
this, this->target.c_str());
2733 this->target = target;
2734 VDebugLog(
"%p target=%s",
this, this->target.c_str());
2741 shouldLoadAllModules =
true;
2742 hasLoadedAllModules =
false;
2743 modulesToLoadQueue = dispatch_queue_create(
"org.vuo.compiler.modules", NULL);
2744 moduleSourceCompilersExist = dispatch_group_create();
2745 moduleCacheBuilding = dispatch_group_create();
2746 dependencyGraph = NULL;
2747 compositionDependencyGraph = NULL;
2749 _shouldShowSplashWindow =
false;
2751 delegateQueue = dispatch_queue_create(
"org.vuo.compiler.delegate", NULL);
2754 if (! vuoFrameworkPath.empty())
2755 clangPath = vuoFrameworkPath +
"/Helpers/clang";
2757 clangPath = LLVM_ROOT
"/bin/clang";
2759 dispatch_sync(environmentQueue, ^{
2760 allCompilers.insert(
this);
2762 if (sharedEnvironments[target].empty())
2764 sharedEnvironments[target] = vector< vector<Environment *> >(3, vector<Environment *>(2, NULL));
2765 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2766 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2767 *j =
new Environment(this->target, i == sharedEnvironments[target].begin(), j != i->begin());
2769 vector<string> builtInModuleSearchPaths = Environment::getBuiltInModuleSearchPaths();
2770 for (vector<string>::iterator i = builtInModuleSearchPaths.begin(); i != builtInModuleSearchPaths.end(); ++i)
2771 sharedEnvironments[target][0][0]->addModuleSearchPath(*i,
false);
2773 vector<string> builtInHeaderSearchPaths = Environment::getBuiltInHeaderSearchPaths();
2774 for (vector<string>::iterator i = builtInHeaderSearchPaths.begin(); i != builtInHeaderSearchPaths.end(); ++i)
2775 sharedEnvironments[target][0][0]->addHeaderSearchPath(*i);
2777 vector<string> builtInLibrarySearchPaths = Environment::getBuiltInLibrarySearchPaths();
2778 for (vector<string>::iterator i = builtInLibrarySearchPaths.begin(); i != builtInLibrarySearchPaths.end(); ++i)
2779 sharedEnvironments[target][0][0]->addLibrarySearchPath(*i);
2781 vector<string> builtInFrameworkSearchPaths = Environment::getBuiltInFrameworkSearchPaths();
2782 for (vector<string>::iterator i = builtInFrameworkSearchPaths.begin(); i != builtInFrameworkSearchPaths.end(); ++i)
2783 sharedEnvironments[target][0][0]->addFrameworkSearchPath(*i);
2797 if (! vuoFrameworkPath.empty())
2799 vector<string> moduleCachePaths(3);
2800 moduleCachePaths[0] = vuoFrameworkPath +
"/Modules/Builtin";
2804 for (
size_t i = 0; i < moduleCachePaths.size(); ++i)
2806 string moduleCachePath = moduleCachePaths[i];
2808 sharedEnvironments[target][i][0]->setModuleCachePath(moduleCachePath,
true);
2809 sharedEnvironments[target][i][1]->setModuleCachePath(moduleCachePath,
false);
2827 dispatch_sync(environmentQueue, ^{
2828 allCompilers.erase(
this);
2831 dispatch_group_wait(moduleCacheBuilding, DISPATCH_TIME_FOREVER);
2832 dispatch_release(moduleCacheBuilding);
2834 dispatch_group_wait(moduleSourceCompilersExist, DISPATCH_TIME_FOREVER);
2835 dispatch_release(moduleSourceCompilersExist);
2837 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
2838 (*i)[0]->removeCompilerToNotify(
this);
2840 dispatch_sync(delegateQueue, ^{});
2842 dispatch_release(modulesToLoadQueue);
2843 dispatch_release(delegateQueue);
2845 delete dependencyGraph;
2846 delete compositionDependencyGraph;
2852void VuoCompiler::reset(
void)
2854 dispatch_group_wait(moduleSourceCompilersExistGlobally, DISPATCH_TIME_FOREVER);
2856 dispatch_sync(environmentQueue, ^{
2858 for (
auto e : sharedEnvironments)
2859 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2861 (*i)[0]->stopWatchingModuleSearchPaths();
2862 dispatch_sync((*i)[0]->moduleSearchPathContentsChangedQueue, ^{});
2865 for (
auto e : environmentsForCompositionFamily)
2866 for (map<
string, vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2868 (i->second)[0]->stopWatchingModuleSearchPaths();
2869 dispatch_sync((i->second)[0]->moduleSearchPathContentsChangedQueue, ^{});
2872 for (
auto e : sharedEnvironments)
2873 for (vector< vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2874 for (vector<Environment *>::iterator j = i->begin(); j != i->end(); ++j)
2877 for (
auto e : environmentsForCompositionFamily)
2878 for (map<
string, vector<Environment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
2879 for (vector<Environment *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
2882 allCompilers.clear();
2883 sharedEnvironments.clear();
2884 environmentsForCompositionFamily.clear();
2896 dispatch_async(delegateQueue, ^{
2897 this->delegate = delegate;
2912 string compositionModulesDir;
2913 string compositionBaseDir;
2914 lastCompositionIsSubcomposition =
false;
2915 if (! compositionPath.empty())
2923 string compositionDir;
2926 lastCompositionIsSubcomposition = (compositionDir == compositionModulesDir);
2931 dispatch_sync(environmentQueue, ^{
2932 if (! environments.empty() && compositionBaseDir == lastCompositionBaseDir) {
2935 lastCompositionBaseDir = compositionBaseDir;
2939 Environment *oldCompositionFamilyInstalledEnvironment =
nullptr;
2940 vector<Environment *> compositionEnvironments;
2941 if (! environments.empty())
2943 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
2944 (*i)[0]->removeCompilerToNotify(this);
2947 if (environments.size() >= 5) {
2948 oldCompositionFamilyInstalledEnvironment = environments[3][0];
2951 compositionEnvironments = environments.back();
2953 environments.clear();
2960 bool isCompositionInSharedEnvironment =
false;
2961 for (vector< vector<Environment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
2963 environments.push_back(*i);
2965 vector<string> moduleSearchPaths = (*i)[0]->getModuleSearchPaths();
2966 for (vector<string>::iterator j = moduleSearchPaths.begin(); j != moduleSearchPaths.end(); ++j)
2968 string moduleSearchPath = *j;
2969 VuoFileUtilities::canonicalizePath(moduleSearchPath);
2970 if (moduleSearchPath == compositionModulesDir)
2972 isCompositionInSharedEnvironment = true;
2977 if (isCompositionInSharedEnvironment) {
2984 Environment *newCompositionFamilyInstalledEnvironment =
nullptr;
2985 if (! isCompositionInSharedEnvironment && ! compositionPath.empty())
2987 vector<Environment *> compositionFamilyEnvironments = environmentsForCompositionFamily[target][compositionBaseDir];
2988 if (compositionFamilyEnvironments.empty())
2990 compositionFamilyEnvironments = vector<Environment *>(2, NULL);
2991 compositionFamilyEnvironments[0] = new Environment(this->target, false, false);
2992 compositionFamilyEnvironments[1] = new Environment(this->target, false, true);
2993 environmentsForCompositionFamily[target][compositionBaseDir] = compositionFamilyEnvironments;
2997 compositionFamilyEnvironments[0]->addModuleSearchPath(compositionModulesDir);
3001 string moduleCachePath = getCachePathForComposition(compositionBaseDir);
3003 compositionFamilyEnvironments[0]->setModuleCachePath(moduleCachePath, true);
3004 compositionFamilyEnvironments[1]->setModuleCachePath(moduleCachePath, false);
3006 environments.push_back(compositionFamilyEnvironments);
3008 newCompositionFamilyInstalledEnvironment = compositionFamilyEnvironments[0];
3013 if (compositionEnvironments.empty())
3015 compositionEnvironments = vector<Environment *>(2, NULL);
3016 compositionEnvironments[0] = new Environment(this->target, false, false);
3017 compositionEnvironments[1] = new Environment(this->target, false, true);
3019 environments.push_back(compositionEnvironments);
3021 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
3022 (*i)[0]->addCompilerToNotify(this);
3025 delete dependencyGraph;
3026 delete compositionDependencyGraph;
3027 dependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getDependencyGraph(); });
3028 compositionDependencyGraph = makeDependencyNetwork(environments, ^
VuoDirectedAcyclicGraph * (Environment *env) {
return env->getCompositionDependencyGraph(); });
3033 if (oldCompositionFamilyInstalledEnvironment != newCompositionFamilyInstalledEnvironment)
3035 auto getModules = [] (Environment *env)
3037 map<string, VuoCompilerModule *> modules;
3040 for (
auto i : env->getNodeClasses()) {
3043 for (
auto i : env->getTypes()) {
3046 for (
auto i : env->getLibraryModules()) {
3053 map<string, VuoCompilerModule *> modulesAdded = getModules(newCompositionFamilyInstalledEnvironment);
3054 map<string, VuoCompilerModule *> modulesRemoved = getModules(oldCompositionFamilyInstalledEnvironment);
3056 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified;
3057 for (map<string, VuoCompilerModule *>::iterator
add = modulesAdded.begin();
add != modulesAdded.end(); )
3059 map<string, VuoCompilerModule *>::iterator rem = modulesRemoved.find(
add->first);
3060 if (rem != modulesRemoved.end())
3062 modulesModified[
add->first] = make_pair(rem->second,
add->second);
3063 modulesAdded.erase(
add++);
3064 modulesRemoved.erase(rem);
3072 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty()) )
3075 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues);
3076 delegateData->retain();
3078 Environment *scopeEnvironment = newCompositionFamilyInstalledEnvironment;
3079 if (! scopeEnvironment) {
3080 scopeEnvironment = compositionEnvironments.at(0);
3083 loadedModules(modulesAdded, modulesModified, modulesRemoved, issues, delegateData, scopeEnvironment);
3097 if (!graphForEnvironment)
3102 for (vector< vector<Environment *> >::const_iterator i = environments.begin(); i != environments.end(); ++i)
3106 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(i->at(1)));
3110 for (vector< vector<Environment *> >::const_iterator ii = environments.begin(); ii != i; ++ii)
3112 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(ii->at(0)));
3113 network->
addEdge(graphForEnvironment(i->at(1)), graphForEnvironment(ii->at(0)));
3140void VuoCompiler::loadModulesIfNeeded(
const set<string> &moduleKeys)
3142 __block
bool willLoadAllModules =
false;
3143 if (moduleKeys.empty())
3145 dispatch_sync(modulesToLoadQueue, ^{
3146 if (shouldLoadAllModules && ! hasLoadedAllModules) {
3147 willLoadAllModules =
true;
3148 hasLoadedAllModules =
true;
3153 if (! willLoadAllModules && moduleKeys.empty())
3158 __block set<dispatch_group_t> sourcesLoading;
3159 dispatch_sync(environmentQueue, ^{
3160 sourcesLoading = loadModulesAndSources(moduleKeys, set<string>(), set<string>(),
3161 moduleKeys, set<string>(), set<string>(),
3162 willLoadAllModules,
false,
nullptr,
nullptr,
nullptr,
"");
3168 for (set<dispatch_group_t>::iterator i = sourcesLoading.begin(); i != sourcesLoading.end(); ++i)
3170 dispatch_group_wait(*i, DISPATCH_TIME_FOREVER);
3171 dispatch_release(*i);
3183set<dispatch_group_t> VuoCompiler::loadModulesAndSources(
const set<string> &modulesAddedKeys,
const set<string> &modulesModifiedKeys,
const set<string> &modulesRemovedKeys,
3184 const set<string> &sourcesAddedKeys,
const set<string> &sourcesModifiedKeys,
const set<string> &sourcesRemovedKeys,
3185 bool willLoadAllModules,
bool shouldRecompileSourcesIfUnchanged,
3186 Environment *currentEnvironment,
VuoCompilerIssues *issuesForCurrentEnvironment,
3187 std::function<
void(
void)> moduleLoadedCallback,
const string &moduleAddedOrModifiedSourceCode)
3199 map<Environment *, set<string> > modulesAdded;
3200 map<Environment *, set<string> > modulesModified;
3201 map<Environment *, set<string> > modulesRemoved;
3202 map<Environment *, set<string> > sourcesAdded;
3203 map<Environment *, set<string> > sourcesModified;
3204 map<Environment *, set<string> > sourcesRemoved;
3205 map<Environment *, set<string> > potentialSpecializedModules;
3207 if (currentEnvironment)
3209 modulesAdded[currentEnvironment] = modulesAddedKeys;
3210 modulesModified[currentEnvironment] = modulesModifiedKeys;
3211 modulesRemoved[currentEnvironment] = modulesRemovedKeys;
3212 sourcesAdded[currentEnvironment] = sourcesAddedKeys;
3213 sourcesModified[currentEnvironment] = sourcesModifiedKeys;
3214 sourcesRemoved[currentEnvironment] = sourcesRemovedKeys;
3218 Environment *genEnv =
nullptr;
3219 if (! willLoadAllModules)
3225 int scope = environments.size() - (lastCompositionIsSubcomposition ? 2 : 1);
3226 genEnv = environments.at(scope).at(1);
3227 potentialSpecializedModules[genEnv] = modulesAddedKeys;
3230 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3232 Environment *env = (*i).at(0);
3234 ModuleInfoIterator modulesAddedIter = (willLoadAllModules ? env->listAllModules() : env->listModules(modulesAddedKeys));
3235 ModuleInfoIterator sourcesAddedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesAddedKeys));
3236 ModuleInfoIterator sourcesModifiedIter = (willLoadAllModules ? env->listAllSourceFiles() : env->listSourceFiles(sourcesModifiedKeys));
3238 ModuleInfo *moduleInfo;
3239 while ((moduleInfo = modulesAddedIter.next()))
3241 string moduleKey = moduleInfo->getModuleKey();
3243 modulesAdded[env].insert(moduleKey);
3245 if (! willLoadAllModules)
3247 auto foundIter = potentialSpecializedModules[genEnv].find(moduleKey);
3248 if (foundIter != potentialSpecializedModules[genEnv].end())
3249 potentialSpecializedModules[genEnv].erase(foundIter);
3255 auto isCompiledModuleAtSameSearchPath = [&env] (ModuleInfo *sourceInfo)
3257 ModuleInfo *compiledModuleInfo = env->listModule(sourceInfo->getModuleKey());
3258 return (compiledModuleInfo && compiledModuleInfo->getSearchPath() == sourceInfo->getSearchPath());
3261 while ((moduleInfo = sourcesAddedIter.next()))
3263 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3266 sourcesAdded[env].insert( moduleInfo->getModuleKey() );
3269 while ((moduleInfo = sourcesModifiedIter.next()))
3271 if (isCompiledModuleAtSameSearchPath(moduleInfo))
3274 sourcesModified[env].insert( moduleInfo->getModuleKey() );
3279 map<Environment *, VuoCompilerIssues *> issues;
3280 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3282 Environment *env = (*i).at(0);
3283 issues[env] = (env == currentEnvironment && issuesForCurrentEnvironment ? issuesForCurrentEnvironment :
new VuoCompilerIssues());
3288 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3290 Environment *env = (*i).at(0);
3295 set<VuoDirectedAcyclicGraph::Vertex *> circularDependencies = env->getCompositionDependencyGraph()->getCycleVertices();
3297 set<string> sourcesAddedModified;
3298 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3299 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3301 for (set<string>::iterator j = sourcesAddedModified.begin(); j != sourcesAddedModified.end(); ++j)
3303 string moduleKey = *j;
3306 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator k = circularDependencies.begin(); k != circularDependencies.end(); ++k)
3308 DependencyGraphVertex *vertex =
static_cast<DependencyGraphVertex *
>(*k);
3309 if (vertex->getDependency() == moduleKey)
3318 sourcesAdded[env].erase(moduleKey);
3319 sourcesModified[env].erase(moduleKey);
3322 "Subcomposition contains itself",
3323 "%moduleKey contains an instance of itself, "
3324 "or contains another subcomposition that contains an instance of %moduleKey.");
3325 issue.setModuleKey(moduleKey);
3327 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3329 issue.setFilePath(sourceInfo->getFile()->path());
3331 issues[env]->append(issue);
3338 for (
const vector<Environment *> &envs : environments)
3340 Environment *env = envs.at(0);
3342 set<string> sourcesAddedModified;
3343 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3344 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3346 for (
const string &moduleKey : sourcesAddedModified)
3349 int pathLength = env->getCompositionDependencyGraph()->getLongestDownstreamPath(vertex);
3351 ModuleInfo *sourceInfo = env->listSourceFile(moduleKey);
3352 sourceInfo->setLongestDownstreamPath(pathLength);
3360 map<Environment *, set<string> > modulesDepOnModulesModified;
3361 map<Environment *, set<string> > sourcesDepOnModulesModified;
3362 map<Environment *, set<string> > modulesDepOnModulesRemoved;
3363 map<Environment *, set<string> > sourcesDepOnModulesRemoved;
3366 __block map<Environment *, set<string> > modulesDepOnModulesModified_otherCompiler;
3367 __block map<Environment *, set<string> > sourcesDepOnModulesModified_otherCompiler;
3368 __block map<Environment *, set<string> > modulesDepOnModulesRemoved_otherCompiler;
3369 __block map<Environment *, set<string> > sourcesDepOnModulesRemoved_otherCompiler;
3371 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3373 searchDependencyGraphs.push_back(compiler->dependencyGraph);
3375 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getDependencyGraph() :
nullptr);
3377 findDependentModulesAndSources(modulesModified, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3378 modulesDepOnModulesModified, modulesDepOnModulesModified_otherCompiler,
3379 sourcesDepOnModulesModified, sourcesDepOnModulesModified_otherCompiler);
3381 findDependentModulesAndSources(modulesRemoved, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3382 modulesDepOnModulesRemoved, modulesDepOnModulesRemoved_otherCompiler,
3383 sourcesDepOnModulesRemoved, sourcesDepOnModulesRemoved_otherCompiler);
3385 set<Environment *> otherEnvironments;
3386 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesModified_otherCompiler.begin(); i != modulesDepOnModulesModified_otherCompiler.end(); ++i)
3387 otherEnvironments.insert(i->first);
3388 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesModified_otherCompiler.begin(); i != sourcesDepOnModulesModified_otherCompiler.end(); ++i)
3389 otherEnvironments.insert(i->first);
3390 for (map<Environment *, set<string> >::iterator i = modulesDepOnModulesRemoved_otherCompiler.begin(); i != modulesDepOnModulesRemoved_otherCompiler.end(); ++i)
3391 otherEnvironments.insert(i->first);
3392 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesRemoved_otherCompiler.begin(); i != sourcesDepOnModulesRemoved_otherCompiler.end(); ++i)
3393 otherEnvironments.insert(i->first);
3395 for (Environment *env : otherEnvironments)
3399 for (
const vector<Environment *> &ee : c->environments)
3400 for (Environment *e : ee)
3404 goto foundOtherCompiler;
3408 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3409 dispatch_sync(environmentQueue, ^{
3410 otherCompiler->loadModulesAndSources(set<string>(), modulesDepOnModulesModified_otherCompiler[env], modulesDepOnModulesRemoved_otherCompiler[env],
3411 set<string>(), sourcesDepOnModulesModified_otherCompiler[env], sourcesDepOnModulesRemoved_otherCompiler[env],
3412 false,
true, env,
nullptr,
nullptr,
"");
3422 map<Environment *, set<VuoCompilerModule *> > actualModulesRemoved;
3423 for (
const vector<Environment *> &envs : environments)
3425 for (Environment *env : envs)
3427 set<string> modulesToUnload;
3428 modulesToUnload.insert(modulesRemoved[env].begin(), modulesRemoved[env].end());
3429 modulesToUnload.insert(modulesModified[env].begin(), modulesModified[env].end());
3430 modulesToUnload.insert(modulesDepOnModulesRemoved[env].begin(), modulesDepOnModulesRemoved[env].end());
3431 modulesToUnload.insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3433 actualModulesRemoved[env] = env->unloadCompiledModules(modulesToUnload);
3435 if (!env->isBuiltInOriginal() && !actualModulesRemoved[env].empty())
3437 set<string> actualModulesRemovedKeys;
3438 for (
auto m : actualModulesRemoved[env])
3439 actualModulesRemovedKeys.insert(m->getPseudoBase()->getModuleKey());
3452 map<Environment *, set<string> > modulesToLoad;
3453 map<Environment *, map<string, string> > modulesToLoadSourceCode;
3454 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3456 Environment *env = (*i).at(0);
3458 if (! modulesAdded[env].empty())
3459 modulesToLoad[env].insert(modulesAdded[env].begin(), modulesAdded[env].end());
3460 if (! modulesModified[env].empty())
3461 modulesToLoad[env].insert(modulesModified[env].begin(), modulesModified[env].end());
3462 if (! modulesDepOnModulesModified[env].empty())
3463 modulesToLoad[env].insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
3465 if (env == currentEnvironment && moduleLoadedCallback)
3467 if (modulesAdded[env].size() == 1)
3468 modulesToLoadSourceCode[env][*modulesAdded[env].begin()] = moduleAddedOrModifiedSourceCode;
3469 else if (modulesModified[env].size() == 1)
3470 modulesToLoadSourceCode[env][*modulesModified[env].begin()] = moduleAddedOrModifiedSourceCode;
3474 map<Environment *, set<VuoCompilerModule *> > actualModulesAdded;
3475 while (! modulesToLoad.empty())
3477 set<string> dependenciesToLoad;
3478 map<Environment *, set<string> > potentialSpecializedDependencies;
3479 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3481 Environment *env = (*i).at(0);
3482 Environment *genEnv = (*i).at(1);
3484 set<VuoCompilerModule *> actualModulesLoaded = env->loadCompiledModules(modulesToLoad[env], modulesToLoadSourceCode[env]);
3486 actualModulesAdded[env].insert(actualModulesLoaded.begin(), actualModulesLoaded.end());
3487 modulesToLoad.erase(env);
3489 for (set<VuoCompilerModule *>::iterator j = actualModulesLoaded.begin(); j != actualModulesLoaded.end(); ++j)
3491 set<string> dependencies = (*j)->getDependencies();
3492 dependenciesToLoad.insert(dependencies.begin(), dependencies.end());
3493 potentialSpecializedDependencies[genEnv].insert(dependencies.begin(), dependencies.end());
3496 if (!env->isBuiltInOriginal() && !actualModulesLoaded.empty())
3498 map<string, string> actualFilesAndHashesLoaded;
3499 for (
auto module : actualModulesLoaded)
3507 if (cnc && !cnc->getSourcePath().empty())
3510 if (!cnc->getSourceCode().empty())
3525 actualFilesAndHashesLoaded[path] = hash;
3528 for (pair<string, string> item : actualFilesAndHashesLoaded)
3529 VUserLog(
"Loaded into %s environment: [%8.8s] %s", env->getName().c_str(), item.second.c_str(), item.first.c_str());
3533 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3535 Environment *env = (*i).at(0);
3537 ModuleInfoIterator dependenciesInEnv = env->listModules(dependenciesToLoad);
3538 ModuleInfo *moduleInfo;
3539 while ((moduleInfo = dependenciesInEnv.next()))
3541 modulesToLoad[env].insert( moduleInfo->getModuleKey() );
3543 for (map<Environment *, set<string> >::iterator j = potentialSpecializedDependencies.begin(); j != potentialSpecializedDependencies.end(); ++j)
3545 auto foundIter = j->second.find( moduleInfo->getModuleKey() );
3546 if (foundIter != j->second.end())
3547 j->second.erase(foundIter);
3552 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3554 Environment *genEnv = (*i).at(1);
3555 potentialSpecializedModules[genEnv].insert(potentialSpecializedDependencies[genEnv].begin(), potentialSpecializedDependencies[genEnv].end());
3562 set<dispatch_group_t> specializedModulesLoading;
3563 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3565 Environment *genEnv = (*i).at(1);
3566 set<dispatch_group_t> s = genEnv->loadSpecializedModules(potentialSpecializedModules[genEnv],
this,
llvmQueue);
3567 specializedModulesLoading.insert(s.begin(), s.end());
3572 if (moduleLoadedCallback)
3573 moduleLoadedCallback();
3577 map<Environment *, set< pair<VuoCompilerModule *, VuoCompilerModule *> > > actualModulesModified;
3578 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3580 Environment *env = (*i).at(0);
3582 for (set<VuoCompilerModule *>::iterator
add = actualModulesAdded[env].begin();
add != actualModulesAdded[env].end(); )
3584 set<VuoCompilerModule *>::iterator rem;
3585 for (rem = actualModulesRemoved[env].begin(); rem != actualModulesRemoved[env].end(); ++rem)
3586 if ((*rem)->getPseudoBase()->getModuleKey() == (*add)->getPseudoBase()->getModuleKey())
3589 if (rem != actualModulesRemoved[env].end())
3591 actualModulesModified[env].insert( make_pair(*rem, *
add) );
3592 actualModulesRemoved[env].erase(rem);
3593 actualModulesAdded[env].erase(
add++);
3602 bool wereModulesAddedOrModified =
false;
3603 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3605 Environment *env = (*i).at(0);
3606 if (! (actualModulesAdded[env].empty() && actualModulesModified[env].empty()) )
3608 wereModulesAddedOrModified =
true;
3613 if (wereModulesAddedOrModified)
3615 map<string, VuoCompilerType *> inheritedTypes;
3616 for (
const vector<Environment *> &envs : environments)
3618 for (Environment *env : envs)
3620 env->reifyPortTypes(inheritedTypes);
3621 map<string, VuoCompilerType *> envTypes = env->getTypes();
3622 inheritedTypes.insert(envTypes.begin(), envTypes.end());
3631 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3633 Environment *env = (*i).at(0);
3635 set<string> sourcesToUnload;
3636 sourcesToUnload.insert(sourcesRemoved[env].begin(), sourcesRemoved[env].end());
3637 sourcesToUnload.insert(sourcesDepOnModulesRemoved[env].begin(), sourcesDepOnModulesRemoved[env].end());
3638 if (! sourcesToUnload.empty())
3640 string moduleSearchPath = env->getModuleSearchPaths().front();
3642 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3645 dispatch_sync(environmentQueue, ^{
3646 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), sourcesToUnload,
3647 set<string>(), set<string>(), set<string>(),
3648 false,
false, env,
nullptr,
nullptr,
"");
3651 delete otherCompiler;
3655 if (!env->isBuiltInOriginal() && !sourcesToUnload.empty())
3658 env->deleteModulesCompiledFromSourceCode(sourcesToUnload);
3666 map<Environment *, set<string> > sourcesDepOnModulesAdded;
3668 map<Environment *, set<string> > modulesDepOnModulesAdded;
3669 __block map<Environment *, set<string> > modulesDepOnModulesAdded_otherCompiler;
3670 __block map<Environment *, set<string> > sourcesDepOnModulesAdded_otherCompiler;
3672 map<Environment *, set<string> > actualModuleKeysAdded;
3673 for (
const vector<Environment *> &envs : environments)
3675 Environment *env = envs.at(0);
3680 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
3681 searchDependencyGraphs.push_back(compositionDependencyGraph);
3682 for (map<
string, vector<Environment *> >::iterator ii = environmentsForCompositionFamily[target].begin(); ii != environmentsForCompositionFamily[target].end(); ++ii)
3684 vector< vector<Environment *> > otherEnvs = sharedEnvironments[target];
3685 otherEnvs.push_back(ii->second);
3687 searchDependencyGraphs.push_back(other);
3690 VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph = (currentEnvironment ? currentEnvironment->getCompositionDependencyGraph() :
nullptr);
3692 findDependentModulesAndSources(actualModuleKeysAdded, searchDependencyGraphs, currentEnvironmentDependencyGraph,
3693 modulesDepOnModulesAdded, modulesDepOnModulesAdded_otherCompiler,
3694 sourcesDepOnModulesAdded, sourcesDepOnModulesAdded_otherCompiler);
3696 set<Environment *> otherEnvironments;
3697 for (map<Environment *, set<string> >::iterator i = sourcesDepOnModulesAdded_otherCompiler.begin(); i != sourcesDepOnModulesAdded_otherCompiler.end(); ++i)
3698 otherEnvironments.insert(i->first);
3700 for (Environment *env : otherEnvironments)
3702 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3703 string moduleSearchPath = env->getModuleSearchPaths().front();
3706 dispatch_sync(environmentQueue, ^{
3707 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), set<string>(),
3708 sourcesDepOnModulesAdded_otherCompiler[env], set<string>(), set<string>(),
3709 false,
true, env,
nullptr,
nullptr,
"");
3712 delete otherCompiler;
3717 set<dispatch_group_t> sourcesLoading;
3718 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3720 Environment *env = (*i).at(0);
3722 set<string> sourcesToCompile;
3723 sourcesToCompile.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
3724 sourcesToCompile.insert(sourcesModified[env].begin(), sourcesModified[env].end());
3726 if (sourcesToCompile.size() == 0)
3729 set<dispatch_group_t> s = env->compileModulesFromSourceCode(sourcesToCompile, moduleSourceCompilersExist, shouldRecompileSourcesIfUnchanged);
3730 sourcesLoading.insert(s.begin(), s.end());
3733 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3735 Environment *env = (*i).at(0);
3737 set<string> sourcesToCompile;
3738 sourcesToCompile.insert(sourcesDepOnModulesAdded[env].begin(), sourcesDepOnModulesAdded[env].end());
3739 sourcesToCompile.insert(sourcesDepOnModulesModified[env].begin(), sourcesDepOnModulesModified[env].end());
3741 if (sourcesToCompile.size() == 0)
3744 env->compileModulesFromSourceCode(sourcesToCompile, moduleSourceCompilersExist,
true);
3749 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
3751 Environment *env = (*i).at(0);
3752 env->notifyCompilers(actualModulesAdded[env], actualModulesModified[env], actualModulesRemoved[env], issues[env]);
3759 for (
const dispatch_group_t &group : sourcesLoading)
3760 dispatch_retain(group);
3762 set<dispatch_group_t> loadingGroups;
3763 loadingGroups.insert(specializedModulesLoading.begin(), specializedModulesLoading.end());
3764 loadingGroups.insert(sourcesLoading.begin(), sourcesLoading.end());
3765 return loadingGroups;
3779void VuoCompiler::findDependentModulesAndSources(map<Environment *, set<string> > &changedModules,
3780 const vector<VuoDirectedAcyclicNetwork *> &searchDependencyGraphs,
3782 map<Environment *, set<string> > &modulesDepOnChangedModules_this,
3783 map<Environment *, set<string> > &modulesDepOnChangedModules_other,
3784 map<Environment *, set<string> > &sourcesDepOnChangedModules_this,
3785 map<Environment *, set<string> > &sourcesDepOnChangedModules_other)
3787 for (
const vector<Environment *> &envs : environments)
3789 Environment *env = envs.at(0);
3791 for (
const string &module : changedModules[env])
3793 set<VuoDirectedAcyclicGraph::Vertex *> dependents;
3796 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices;
3797 if (currentEnvironmentDependencyGraph)
3803 moduleVertices.push_back(mv);
3806 moduleVertices = searchDependencyGraph->findVertex(module);
3810 DependencyGraphVertex *moduleVertex =
static_cast<DependencyGraphVertex *
>(moduleVertexRaw);
3811 if (moduleVertex->getEnvironment())
3813 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = searchDependencyGraph->getUpstreamVertices(moduleVertex);
3814 dependents.insert(upstream.begin(), upstream.end());
3819 set< pair<Environment *, string> > dependentsMap;
3822 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(dependentVertexRaw);
3823 Environment *dependentEnv = v->getEnvironment();
3827 string dependent = v->getDependency();
3829 dependentsMap.insert({dependentEnv, dependent});
3835 for (
auto i : envs.at(1)->getNodeClasses())
3839 dependentsMap.insert({envs.at(1), i.first});
3842 for (
auto i : dependentsMap)
3844 Environment *dependentEnv = i.first;
3845 string dependent = i.second;
3849 if (changedModules[dependentEnv].find(dependent) != changedModules[dependentEnv].end())
3852 ModuleInfo *foundSourceInfo = dependentEnv->listSourceFile(dependent);
3853 ModuleInfo *foundModuleInfo = dependentEnv->listModule(dependent);
3855 bool belongsToCurrentCompiler =
false;
3856 for (
const vector<Environment *> &envs2 : environments)
3858 if (find(envs2.begin(), envs2.end(), dependentEnv) != envs2.end())
3860 belongsToCurrentCompiler =
true;
3865 map<Environment *, set<string> > *whicheverDependents =
nullptr;
3866 ModuleInfo *moduleInfo =
nullptr;
3867 if (foundSourceInfo)
3869 moduleInfo = foundSourceInfo;
3870 whicheverDependents = (belongsToCurrentCompiler ? &sourcesDepOnChangedModules_this : &sourcesDepOnChangedModules_other);
3872 else if (foundModuleInfo)
3874 moduleInfo = foundModuleInfo;
3875 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3879 whicheverDependents = (belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other);
3882 (*whicheverDependents)[dependentEnv].insert(dependent);
3884 moduleInfo->setAttempted(
false);
3893void VuoCompiler::loadedModules(map<string, VuoCompilerModule *> modulesAdded,
3894 map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified,
3895 map<string, VuoCompilerModule *> modulesRemoved,
3896 VuoCompilerIssues *issues,
void *delegateDataV, Environment *currentEnvironment)
3908 auto findVersionsOfModule = [
this, currentEnvironment] (
const string &moduleKey)
3910 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions;
3911 for (
const vector<Environment *> &envs : environments)
3913 Environment *env = envs.at(0);
3915 if (module || env == currentEnvironment)
3916 moduleVersions.push_back( make_pair(env, module) );
3918 return moduleVersions;
3921 for (map<string, VuoCompilerModule *>::iterator i = modulesAdded.begin(); i != modulesAdded.end(); )
3923 string moduleKey = i->first;
3926 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3928 if (moduleVersions.size() > 1)
3930 modulesAdded.erase(i++);
3932 if (moduleVersions.back().second == moduleAdded)
3934 VuoCompilerModule *moduleSuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3935 modulesModified[moduleKey] = make_pair(moduleSuperseded, moduleAdded);
3942 for (map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); )
3944 string moduleKey = i->first;
3947 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3949 if (moduleVersions.size() > 1 && moduleVersions.back().second != moduleModified)
3950 modulesModified.erase(i++);
3955 for (map<string, VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); )
3957 string moduleKey = i->first;
3960 vector< pair<Environment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
3962 if (moduleVersions.size() > 1)
3964 modulesRemoved.erase(i++);
3966 if (moduleVersions.back().first == currentEnvironment)
3968 VuoCompilerModule *moduleUnsuperseded = moduleVersions.at(moduleVersions.size()-2).second;
3969 modulesModified[moduleKey] = make_pair(moduleRemoved, moduleUnsuperseded);
3976 dispatch_async(delegateQueue, ^{
3977 VuoCompilerDelegate::LoadedModulesData *delegateData =
static_cast<VuoCompilerDelegate::LoadedModulesData *
>(delegateDataV);
3979 if (delegate && ! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()))
3981 delegate->enqueueData(delegateData);
3982 delegate->
loadedModules(modulesAdded, modulesModified, modulesRemoved, issues);
3986 delegateData->release();
3996void VuoCompiler::loadNodeClassGeneratedAtRuntime(
VuoCompilerNodeClass *nodeClass, Environment *env)
3998 Module *module = nodeClass->
getModule();
4002 setTargetForModule(nodeClass->
getModule(), env->getTarget());
4006 dispatch_sync(environmentQueue, ^{
4007 env->replaceNodeClass(nodeClass);
4010 __block map<string, VuoCompilerType *> inheritedTypes;
4011 void (^envReifyPortTypes)(Environment *) = ^
void (Environment *env) {
4012 env->reifyPortTypes(inheritedTypes);
4013 map<string, VuoCompilerType *> currentTypes = env->getTypes();
4014 inheritedTypes.insert(currentTypes.begin(), currentTypes.end());
4016 applyToAllEnvironments(envReifyPortTypes);
4025 reifyGenericPortTypes(node->getBase());
4033void VuoCompiler::reifyGenericPortTypes(
VuoNode *node)
4043 vector<VuoPort *> ports;
4044 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
4045 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
4047 for (vector<VuoPort *>::iterator j = ports.begin(); j != ports.end(); ++j)
4094 vector<string> allIncludePaths = includePaths;
4095 string preprocessedInputPath = inputPath;
4097 string tmpPreprocessedInputDir;
4098 string dir, file, ext;
4103 string preprocessedInputContents = inputContents;
4105 if (inputContents != preprocessedInputContents)
4108 allIncludePaths.push_back(dir.empty() ?
"." : dir);
4110 preprocessedInputPath = tmpPreprocessedInputDir +
"/" + file +
"." + ext;
4115 else if (ext ==
"fs")
4121 auto getType = [
this] (
const string &moduleKey) {
return this->
getType(moduleKey); };
4126 setTargetForModule(module, target);
4127 writeModuleToBitcode(module, outputPath);
4129 string dependencyOutputPath = _dependencyOutput();
4130 if (!dependencyOutputPath.empty())
4132 string outputObjectPath = dependencyOutputPath.substr(0, dependencyOutputPath.length() - 2);
4145 vector<string> extraArgs;
4146 for (vector<string>::iterator i = allIncludePaths.begin(); i != allIncludePaths.end(); ++i)
4148 extraArgs.push_back(
"-I");
4149 extraArgs.push_back(*i);
4155 string buildTimeMacOSSDKFolder = MACOS_SDK_ROOT;
4158 extraArgs.push_back(
"-isysroot");
4159 extraArgs.push_back(buildTimeMacOSSDKFolder);
4163 __block vector<string> headerSearchPaths;
4164 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
4165 vector<string> result = env->getHeaderSearchPaths();
4166 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
4168 applyToInstalledEnvironments(envGetHeaderSearchPaths);
4171 __block Module *module;
4173 module = readModuleFromC(preprocessedInputPath, headerSearchPaths, extraArgs, issues);
4176 if (! tmpPreprocessedInputDir.empty())
4178 remove(tmpPreprocessedInputDir.c_str());
4187 if (! compilerModule)
4189 VUserLog(
"Error: Didn't recognize '%s' as a node class, type, or library.", inputPath.c_str());
4193 setTargetForModule(module, target);
4194 writeModuleToBitcode(module, outputPath);
4203Module * VuoCompiler::compileCompositionToModule(
VuoCompilerComposition *composition,
const string &moduleKey,
bool isTopLevelComposition,
4206 composition->
check(issues);
4208 reifyGenericPortTypes(composition);
4211 isTopLevelComposition,
4214 __block Module *module =
nullptr;
4219 setTargetForModule(module, target);
4249 Module *module = compileCompositionToModule(composition, moduleKey, isTopLevelComposition, issues);
4254 writeModuleToBitcode(module, outputPath);
4273 VUserLog(
"Compiling '%s' (%s)…", inputPath.c_str(), target.c_str());
4283 "",
"The composition file couldn't be read or was empty.");
4322 delete baseComposition;
4342 vector<string> rPaths = ! rPath.empty() ? vector<string>(1, rPath) : getRunPathSearchPaths(environments.back().front());
4343 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
false, rPaths, shouldAdHocCodeSign);
4365 vector<string> rPaths = getRunPathSearchPaths(environments.back().front());
4366 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
true, rPaths, shouldAdHocCodeSign);
4383void VuoCompiler::linkCompositionToCreateExecutableOrDynamicLibrary(
string compiledCompositionPath,
string linkedCompositionPath,
4384 Optimization optimization,
bool isDylib,
const vector<string> &rPaths,
4385 bool shouldAdHocCodeSign)
4390 if (optimization == Optimization_FastBuildExistingCache)
4391 shouldLoadAllModules =
false;
4393 set<string> dependencies = getDependenciesForComposition(compiledCompositionPath);
4394 dependencies.insert(getRuntimeDependency());
4396 dependencies.insert(getRuntimeMainDependency());
4398 set<Module *> modules;
4399 set<string> libraries;
4400 set<string> frameworks;
4401 getLinkerInputs(dependencies, optimization, modules, libraries, frameworks);
4403 libraries.insert(compiledCompositionPath);
4405 link(linkedCompositionPath, modules, libraries, frameworks, isDylib, rPaths, shouldAdHocCodeSign);
4428 bool shouldAdHocCodeSign =
false;
4430 shouldAdHocCodeSign =
true;
4436 set<string> allDependencies = getDependenciesForComposition(compiledCompositionPath);
4437 set<string> addedDependencies;
4438 std::set_difference(allDependencies.begin(), allDependencies.end(),
4439 carriedOverDependencies.begin(), carriedOverDependencies.end(),
4440 std::inserter(addedDependencies, addedDependencies.end()));
4446 set<string> carriedOverExternalLibraries = runningCompositionLibraries->
getExternalLibraries();
4451 string nonUnloadableResourcePath;
4452 string unloadableResourcePath;
4453 set<string> nonUnloadableDependencies;
4454 set<string> unloadableDependencies;
4455 map<string, set<string> > builtInCacheDependencies;
4456 map<string, set<string> > userCacheDependencies;
4457 set<string> builtInLibraries;
4458 set<string> userLibraries;
4459 set<string> addedExternalLibraries;
4460 set<string> addedFrameworks;
4461 set<string> allFrameworks;
4462 if (! addedDependencies.empty())
4466 set<string> builtInModuleAndLibraryDependencies;
4467 set<string> userModuleAndLibraryDependencies;
4468 set<Module *> builtInModules;
4469 set<Module *> userModules;
4472 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4473 builtInModules, userModules, builtInLibraries, userLibraries, addedExternalLibraries, addedFrameworks);
4475 allFrameworks.insert(carriedOverFrameworks.begin(), carriedOverFrameworks.end());
4476 allFrameworks.insert(addedFrameworks.begin(), addedFrameworks.end());
4478 string dir, linkedCompositionFile, ext;
4485 __block vector<string> currentCacheLibraries;
4486 applyToAllEnvironments(^
void (Environment *env) {
4487 currentCacheLibraries.push_back( env->getCurrentModuleCacheDylib() );
4490 for (
string cachePath : carriedOverUserCacheLibraries)
4492 for (
string currentCachePath : currentCacheLibraries)
4498 userCacheDependencies[currentCachePath].insert(dependenciesInCache.begin(), dependenciesInCache.end());
4500 auto cacheDependenciesIter = userCacheDependencies.find(cachePath);
4501 if (cacheDependenciesIter != userCacheDependencies.end())
4503 userCacheDependencies[currentCachePath].insert(cacheDependenciesIter->second.begin(), cacheDependenciesIter->second.end());
4504 userCacheDependencies.erase(cacheDependenciesIter);
4507 auto carriedOverIter = find(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(), cachePath);
4508 if (carriedOverIter != carriedOverUnloadableLibraries.end())
4509 *carriedOverIter = currentCachePath;
4517 if (wasModuleCacheRebuilt)
4521 vector<string> carriedOverUnloadableMinusResourceLibraries;
4522 std::set_difference(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end(),
4523 carriedOverResourceLibraries.begin(), carriedOverResourceLibraries.end(),
4524 std::back_inserter(carriedOverUnloadableMinusResourceLibraries));
4526 carriedOverUnloadableLibraries = carriedOverUnloadableMinusResourceLibraries;
4529 userModuleAndLibraryDependencies.insert(dependenciesInResourceLibraries.begin(), dependenciesInResourceLibraries.end());
4531 set<string> builtInModuleAndLibraryDependencies_tmp;
4532 set<string> userModuleAndLibraryDependencies_tmp;
4533 map<string, set<string> > builtInCacheDependencies_tmp;
4534 set<Module *> builtInModules_tmp;
4535 set<string> builtInLibraries_tmp;
4536 set<string> externalLibraries_tmp;
4537 set<string> externalFrameworks_tmp;
4540 builtInModuleAndLibraryDependencies_tmp, userModuleAndLibraryDependencies_tmp, builtInCacheDependencies_tmp, userCacheDependencies,
4541 builtInModules_tmp, userModules, builtInLibraries_tmp, userLibraries, externalLibraries_tmp, externalFrameworks_tmp);
4546 if (! builtInModules.empty() || builtInLibraries.size() > builtInCacheDependencies.size())
4549 nonUnloadableDependencies = builtInModuleAndLibraryDependencies;
4551 set<string> librariesForNonUnloadableResource = builtInLibraries;
4552 librariesForNonUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4553 librariesForNonUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4554 librariesForNonUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4556 vector<string> rPaths = getRunPathSearchPaths(environments.front().front());
4558 link(nonUnloadableResourcePath, builtInModules, librariesForNonUnloadableResource, allFrameworks,
true, rPaths, shouldAdHocCodeSign);
4560 for (set<string>::iterator i = builtInLibraries.begin(); i != builtInLibraries.end(); )
4563 builtInLibraries.erase(i++);
4568 for (set<string>::iterator i = addedExternalLibraries.begin(); i != addedExternalLibraries.end(); )
4571 addedExternalLibraries.erase(i++);
4579 if (! userModules.empty() || userLibraries.size() > userCacheDependencies.size() || wasModuleCacheRebuilt)
4582 unloadableDependencies = userModuleAndLibraryDependencies;
4584 set<string> librariesForUnloadableResource = userLibraries;
4585 librariesForUnloadableResource.insert(builtInLibraries.begin(), builtInLibraries.end());
4586 librariesForUnloadableResource.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4587 librariesForUnloadableResource.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4588 librariesForUnloadableResource.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4589 librariesForUnloadableResource.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4590 if (! nonUnloadableResourcePath.empty())
4591 librariesForUnloadableResource.insert(nonUnloadableResourcePath);
4596 vector<string> rPaths = getRunPathSearchPaths(environments.back().front());
4598 link(unloadableResourcePath, userModules, librariesForUnloadableResource, allFrameworks,
true, rPaths, shouldAdHocCodeSign);
4600 for (set<string>::iterator i = userLibraries.begin(); i != userLibraries.end(); )
4603 userLibraries.erase(i++);
4612 set<string> vuoRuntimePaths;
4614 set<Module *> modules;
4615 set<string> libraries;
4616 set<string> frameworks;
4618 set<string> dependencies;
4619 dependencies.insert(getRuntimeDependency());
4621 vuoRuntimePaths = libraries;
4627 set<Module *> modules;
4628 set<string> libraries;
4630 libraries.insert(compiledCompositionPath);
4631 libraries.insert(carriedOverExternalLibraries.begin(), carriedOverExternalLibraries.end());
4632 libraries.insert(addedExternalLibraries.begin(), addedExternalLibraries.end());
4633 libraries.insert(carriedOverNonUnloadableLibraries.begin(), carriedOverNonUnloadableLibraries.end());
4634 libraries.insert(carriedOverUnloadableLibraries.begin(), carriedOverUnloadableLibraries.end());
4635 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4636 libraries.insert(userLibraries.begin(), userLibraries.end());
4637 if (! nonUnloadableResourcePath.empty())
4638 libraries.insert(nonUnloadableResourcePath);
4639 if (! unloadableResourcePath.empty())
4640 libraries.insert(unloadableResourcePath);
4641 libraries.insert(vuoRuntimePaths.begin(), vuoRuntimePaths.end());
4642 vector<string> rPaths = getRunPathSearchPaths(environments.front().front());
4643 link(linkedCompositionPath, modules, libraries, allFrameworks,
true, rPaths, shouldAdHocCodeSign);
4648 if (! nonUnloadableResourcePath.empty())
4651 if (! unloadableResourcePath.empty())
4654 for (map<
string, set<string> >::iterator i = builtInCacheDependencies.begin(); i != builtInCacheDependencies.end(); ++i)
4657 for (map<
string, set<string> >::iterator i = userCacheDependencies.begin(); i != userCacheDependencies.end(); ++i)
4670set<string> VuoCompiler::getDependenciesForComposition(
const string &compiledCompositionPath)
4675 __block set<string> directDependencies;
4676 string moduleKey = getModuleKeyForPath(compiledCompositionPath);
4677 Module *module = readModuleFromBitcode(compiledCompositionPath, getTargetArch(target));
4681 delete compilerModule;
4687 auto deps = getDependenciesForComposition(directDependencies,
true);
4688 VUserLog(
"Gathering dependencies for '%s' took %5.2fs", compiledCompositionPath.c_str(),
VuoLogGetTime() - t0);
4706 set<string> directDependencies;
4715 vector<VuoPublishedPort *> publishedPorts;
4716 publishedPorts.insert(publishedPorts.end(), publishedInputPorts.begin(), publishedInputPorts.end());
4717 publishedPorts.insert(publishedPorts.end(), publishedOutputPorts.begin(), publishedOutputPorts.end());
4720 if (publishedPort->getClass()->hasCompiler())
4736 directDependencies.insert(dependency);
4741 return directDependencies;
4753 return getDependenciesForComposition(directDependencies,
false);
4763 __block vector<string> librarySearchPaths;
4764 applyToInstalledEnvironments(^
void (Environment *env) {
4765 vector<string> result = env->getLibrarySearchPaths();
4766 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
4769 set<string> dylibDeps;
4770 for (
string dep : getDependenciesForComposition(composition))
4772 string path = getLibraryPath(dep, librarySearchPaths);
4774 dylibDeps.insert(path);
4793set<string> VuoCompiler::getDependenciesForComposition(
const set<string> &directDependencies,
bool checkCompatibility)
4796 for (set<string>::const_iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4799 set<string> dependencies;
4800 for (set<string>::iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
4802 string moduleKey = *i;
4804 dependencies.insert(moduleKey);
4807 vector<VuoDirectedAcyclicGraph::Vertex *> firstPassVertices = dependencyGraph->
findVertex(moduleKey);
4808 set<VuoDirectedAcyclicGraph::Vertex *> firstPassDependencies(firstPassVertices.begin(), firstPassVertices.end());
4809 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassVertices.begin(); j != firstPassVertices.end(); ++j)
4812 firstPassDependencies.insert(downstream.begin(), downstream.end());
4816 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassDependencies.begin(); j != firstPassDependencies.end(); ++j)
4818 DependencyGraphVertex *v =
static_cast<DependencyGraphVertex *
>(*j);
4823 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
4824 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = moduleVertices.begin(); j != moduleVertices.end(); ++j)
4828 dependencies.insert(
static_cast<DependencyGraphVertex *
>(v)->getDependency() );
4833 if (checkCompatibility)
4841 set<VuoCompilerNodeClass *> nodeClassesReported;
4843 for (
string moduleKey : dependencies)
4848 vector<VuoCompilerNodeClass *> incompatibleNodeClasses;
4851 if (moduleAsNodeClass)
4852 incompatibleNodeClasses.push_back(moduleAsNodeClass);
4855 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
4858 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = dependencyGraph->
getUpstreamVertices(v);
4860 vector<string> upstreamModuleKeys;
4861 std::transform(upstream.begin(), upstream.end(),
4862 std::back_inserter(upstreamModuleKeys),
4865 vector<string> potentialNodeClassNames;
4866 std::set_intersection(directDependencies.begin(), directDependencies.end(),
4867 upstreamModuleKeys.begin(), upstreamModuleKeys.end(),
4868 std::back_inserter(potentialNodeClassNames));
4870 for (
string nodeClassName : potentialNodeClassNames)
4873 if (upstreamNodeClass)
4874 incompatibleNodeClasses.push_back(upstreamNodeClass);
4879 if (incompatibleNodeClasses.empty())
4882 "Dependencies incompatible with system",
4884 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4892 if (nodeClassesReported.find(nodeClass) != nodeClassesReported.end())
4895 nodeClassesReported.insert(nodeClass);
4898 "Nodes incompatible with system",
4900 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4911 "Dependencies incompatible with system",
4912 "Some dependencies of this composition are only compatible with " + actualCompatibility.
toString() +
4913 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
4922 vector<string> coreDependencies = getCoreVuoDependencies();
4923 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
4925 return dependencies;
4935 for (
string dependency : dependencies)
4942 return compatibility;
4949void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4950 set<Module *> &modules, set<string> &libraries, set<string> &frameworks)
4952 set<string> builtInModuleAndLibraryDependencies;
4953 set<string> userModuleAndLibraryDependencies;
4954 map<string, set<string> > builtInCacheDependencies;
4955 map<string, set<string> > userCacheDependencies;
4956 set<Module *> builtInModules;
4957 set<Module *> userModules;
4958 set<string> builtInLibraries;
4959 set<string> userLibraries;
4960 set<string> externalLibraries;
4962 getLinkerInputs(dependencies, optimization,
4963 builtInModuleAndLibraryDependencies, userModuleAndLibraryDependencies, builtInCacheDependencies, userCacheDependencies,
4964 builtInModules, userModules, builtInLibraries, userLibraries, externalLibraries, frameworks);
4966 modules.insert(builtInModules.begin(), builtInModules.end());
4967 modules.insert(userModules.begin(), userModules.end());
4968 libraries.insert(builtInLibraries.begin(), builtInLibraries.end());
4969 libraries.insert(userLibraries.begin(), userLibraries.end());
4970 libraries.insert(externalLibraries.begin(), externalLibraries.end());
4986void VuoCompiler::getLinkerInputs(
const set<string> &dependencies, Optimization optimization,
4987 set<string> &builtInModuleAndLibraryDependencies, set<string> &userModuleAndLibraryDependencies,
4988 map<
string, set<string> > &builtInCacheDependencies, map<
string, set<string> > &userCacheDependencies,
4989 set<Module *> &builtInModules, set<Module *> &userModules,
4990 set<string> &builtInLibraries, set<string> &userLibraries,
4991 set<string> &externalLibraries, set<string> &externalFrameworks)
4994 if (shouldUseModuleCache)
4995 useModuleCache(
true, optimization == Optimization_FastBuildExistingCache);
4997 __block vector<string> librarySearchPaths;
4998 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
4999 vector<string> result = env->getLibrarySearchPaths();
5000 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
5002 applyToInstalledEnvironments(envGetLibrarySearchPaths);
5004 for (set<string>::iterator i = dependencies.begin(); i != dependencies.end(); ++i)
5006 string dependency = *i;
5008 bool foundInCache =
false;
5009 string moduleCachePath;
5010 bool isInBuiltInModuleCache =
false;
5011 if (shouldUseModuleCache)
5012 foundInCache = findInModuleCache(dependency, moduleCachePath, isInBuiltInModuleCache);
5016 if (isInBuiltInModuleCache)
5018 builtInLibraries.insert(moduleCachePath);
5019 builtInCacheDependencies[moduleCachePath].insert(dependency);
5023 userLibraries.insert(moduleCachePath);
5024 userCacheDependencies[moduleCachePath].insert(dependency);
5030 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
5035 applyToAllEnvironments(envFindModule);
5045 if (module->isBuiltIn())
5046 builtInLibraries.insert(modulePath);
5048 userLibraries.insert(modulePath);
5052 if (module->isBuiltIn())
5053 builtInModules.insert(module->getModule());
5055 userModules.insert(module->getModule());
5058 if (module->isBuiltIn())
5059 builtInModuleAndLibraryDependencies.insert(dependency);
5061 userModuleAndLibraryDependencies.insert(dependency);
5067 externalFrameworks.insert(dependency);
5070 string dependencyPath = getLibraryPath(dependency, librarySearchPaths);
5071 if (! dependencyPath.empty())
5072 externalLibraries.insert(dependencyPath);
5076 else if (dependency !=
"c"
5077 && dependency !=
"objc")
5078 VUserLog(
"Warning: Could not locate dependency '%s'.", dependency.c_str());
5090string VuoCompiler::getLibraryPath(
const string &dependency, vector<string> librarySearchPaths)
5097 if (dependency !=
"crypto"
5098 && dependency !=
"ssl")
5099 librarySearchPaths.push_back(
"/usr/lib");
5101 for (
auto &path : librarySearchPaths)
5103 vector<string> variations;
5104 variations.push_back(path +
"/" + dependency);
5105 variations.push_back(path +
"/lib" + dependency);
5106 variations.push_back(path +
"/lib" + dependency +
".dylib");
5107 variations.push_back(path +
"/lib" + dependency +
".a");
5108 for (
auto &variation : variations)
5123void VuoCompiler::useModuleCache(
bool shouldUseExistingBuiltInCaches,
bool shouldUseExistingOtherCaches)
5125 loadModulesIfNeeded();
5126 dispatch_group_wait(moduleSourceCompilersExist, DISPATCH_TIME_FOREVER);
5130 dispatch_sync(environmentQueue, ^{
5131 set<string> dylibsForCachesOfInstalledModules;
5132 set<string> frameworksForCachesOfInstalledModules;
5133 unsigned long lastPrerequisiteModuleCacheRebuild = 0;
5134 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
5136 set<string> dylibsForCacheOfGeneratedModules;
5137 set<string> frameworksForCacheOfGeneratedModules;
5139 for (int j = i->size() - 1; j >= 0; --j)
5141 Environment *env = i->at(j);
5142 bool installed = (j == 0);
5144 set<string> cacheableModulesAndDependencies;
5145 set<string> dylibsNeededToLinkToThisCache;
5146 set<string> frameworksNeededToLinkToThisCache;
5147 env->getCacheableModulesAndDependencies(cacheableModulesAndDependencies,
5148 dylibsNeededToLinkToThisCache, frameworksNeededToLinkToThisCache);
5150 set<string> accumulatedDylibs;
5151 accumulatedDylibs.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5152 accumulatedDylibs.insert(dylibsForCachesOfInstalledModules.begin(), dylibsForCachesOfInstalledModules.end());
5153 accumulatedDylibs.insert(dylibsForCacheOfGeneratedModules.begin(), dylibsForCacheOfGeneratedModules.end());
5155 set<string> accumulatedFrameworks;
5156 accumulatedFrameworks.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5157 accumulatedFrameworks.insert(frameworksForCachesOfInstalledModules.begin(), frameworksForCachesOfInstalledModules.end());
5158 accumulatedFrameworks.insert(frameworksForCacheOfGeneratedModules.begin(), frameworksForCacheOfGeneratedModules.end());
5160 bool shouldUseExistingCache = (env->isBuiltIn() ? shouldUseExistingBuiltInCaches : shouldUseExistingOtherCaches);
5161 env->useModuleCache(shouldUseExistingCache, this, cacheableModulesAndDependencies,
5162 accumulatedDylibs, accumulatedFrameworks, lastPrerequisiteModuleCacheRebuild);
5164 string cacheDylib = env->getCurrentModuleCacheDylib();
5165 accumulatedDylibs.insert(cacheDylib);
5166 dylibsForCachesOfInstalledModules.insert(cacheDylib);
5168 lastPrerequisiteModuleCacheRebuild = max(lastPrerequisiteModuleCacheRebuild, env->getLastModuleCacheRebuild());
5172 dylibsForCachesOfInstalledModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5173 frameworksForCachesOfInstalledModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5177 dylibsForCacheOfGeneratedModules.insert(dylibsNeededToLinkToThisCache.begin(), dylibsNeededToLinkToThisCache.end());
5178 frameworksForCacheOfGeneratedModules.insert(frameworksNeededToLinkToThisCache.begin(), frameworksNeededToLinkToThisCache.end());
5184 Environment::waitForModuleCachesToBuild();
5195bool VuoCompiler::findInModuleCache(
const string &moduleOrDependency,
string &cachePath,
bool &isBuiltinCache)
5197 __block
bool found =
false;
5198 __block
string outPath;
5199 __block
bool outBuiltin;
5200 dispatch_sync(environmentQueue, ^{
5201 for (vector< vector<Environment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
5203 bool builtin = (i == environments.begin());
5205 for (int j = i->size() - 1; j >= 0; --j)
5207 Environment *env = i->at(j);
5210 bool resultFound = env->findInModuleCache(moduleOrDependency, resultPath);
5214 outPath = resultPath;
5215 outBuiltin = builtin;
5221 cachePath = outPath;
5222 isBuiltinCache = outBuiltin;
5235 dispatch_group_async(moduleCacheBuilding, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
5236 useModuleCache(
true,
false);
5255 return getTargetArch(target);
5273 vuoFrameworkInProgressPath = vuoFrameworkPath;
5276 compiler.useModuleCache(
false,
true);
5288 unsigned long maxSeconds = 30 * 24 * 60 * 60;
5291 for (set<VuoFileUtilities::File *>::iterator i = cacheDirs.begin(); i != cacheDirs.end(); ++i)
5293 string path = (*i)->path();
5295 string file = (*i)->basename();
5296 if (file !=
"Builtin" && file !=
"System" && file !=
"User")
5299 if (fileSeconds > maxSeconds)
5305 string pidAsString = file.substr(Environment::pidCacheDirPrefix.length());
5306 int pid = atoi(pidAsString.c_str());
5307 if (kill(pid, 0) != 0)
5321 dispatch_sync(modulesToLoadQueue, ^{
5322 this->shouldLoadAllModules = shouldLoadAllModules;
5338void VuoCompiler::link(
string outputPath,
const set<Module *> &modules,
const set<string> &libraries,
const set<string> &frameworks,
bool isDylib,
const vector<string> &rPaths,
bool shouldAdHocCodeSign,
VuoCompilerIssues *issues)
5340 VUserLog(
"Linking '%s' (%s)…", outputPath.c_str(), getTargetArch(target).c_str());
5343 bool ownsIssues =
false;
5355 unique_ptr<Module> compositeModule(
new Module(
"composite", *globalLLVMContext));
5356 Linker linker(*compositeModule);
5357 setTargetForModule(compositeModule.get(), target);
5359 for (
auto i : modules)
5361 unique_ptr<Module> upi = llvm::CloneModule(i);
5362 if (linker.linkInModule(std::move(upi)))
5365 "",
"Failed to link in the module with ID '" + i->getModuleIdentifier() +
"'");
5370 writeModuleToBitcode(compositeModule.get(), compositeModulePath);
5379 string clangPath(getClangPath() +
"++");
5381 vector<const char *> args;
5382 vector<char *> argsToFree;
5383 args.push_back(clangPath.c_str());
5386 char *outputPathZ = strdup((
"-o" + outputPath).c_str());
5387 args.push_back(outputPathZ);
5388 argsToFree.push_back(outputPathZ);
5391 args.push_back(compositeModulePath.c_str());
5393 vector<string> coreDependencies = getCoreVuoDependencies();
5394 for (set<string>::const_iterator i = libraries.begin(); i != libraries.end(); ++i)
5396 string library = *i;
5398 for (vector<string>::iterator j = coreDependencies.begin(); j != coreDependencies.end(); ++j)
5400 string coreDependency = *j;
5402 args.push_back(
"-force_load");
5410 library = libraryObject;
5413 char *libraryZ = strdup(library.c_str());
5414 args.push_back(libraryZ);
5415 argsToFree.push_back(libraryZ);
5419 vector<string> frameworkArguments;
5421 __block vector<string> frameworkSearchPaths;
5422 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
5423 vector<string> result = env->getFrameworkSearchPaths();
5424 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
5426 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
5428 for (vector<string>::const_iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
5432 frameworkArguments.push_back(a);
5433 char *frameworkArgument = strdup(a.c_str());
5434 args.push_back(frameworkArgument);
5435 argsToFree.push_back(frameworkArgument);
5438 for (set<string>::const_iterator i = frameworks.begin(); i != frameworks.end(); ++i)
5440 args.push_back(
"-framework");
5442 string frameworkName = *i;
5443 frameworkName = frameworkName.substr(0, frameworkName.length() -
string(
".framework").length());
5444 char *frameworkNameZ = strdup(frameworkName.c_str());
5445 args.push_back(frameworkNameZ);
5446 argsToFree.push_back(frameworkNameZ);
5452 string frameworkMacOSSDKFolder = vuoFrameworkPath +
"/SDKs/MacOSX.sdk";
5456 args.push_back(
"-Xlinker");
5457 args.push_back(
"-syslibroot");
5458 args.push_back(
"-Xlinker");
5459 char *frameworkMacOSSDKFolderZ = strdup(frameworkMacOSSDKFolder.c_str());
5460 args.push_back(frameworkMacOSSDKFolderZ);
5461 argsToFree.push_back(frameworkMacOSSDKFolderZ);
5463 args.push_back(
"-Xlinker");
5464 args.push_back(
"-platform_version");
5465 args.push_back(
"-Xlinker");
5466 args.push_back(
"macos");
5467 args.push_back(
"-Xlinker");
5468 char *deploymentTargetZ = strdup(MACOS_DEPLOYMENT_TARGET);
5469 args.push_back(deploymentTargetZ);
5470 argsToFree.push_back(deploymentTargetZ);
5471 args.push_back(
"-Xlinker");
5472 char *sdkVersionZ = strdup(MACOS_SDK_VERSION);
5473 args.push_back(sdkVersionZ);
5474 argsToFree.push_back(sdkVersionZ);
5477 args.push_back(
"-Xlinker");
5478 args.push_back(
"--no-demangle");
5481 args.push_back(
"-v");
5484 args.push_back(
"-dynamiclib");
5486 args.push_back(
"-Xlinker");
5487 args.push_back(
"-headerpad_max_install_names");
5490 for (
const string &rPath : rPaths)
5492 args.push_back(
"-rpath");
5493 args.push_back(rPath.c_str());
5497 args.push_back(
"-rpath");
5498 args.push_back(LLVM_ROOT
"/lib");
5501 args.push_back(
"-target");
5502 args.push_back(target.c_str());
5504 args.push_back(
"-std=c++14");
5505 args.push_back(
"-stdlib=libc++");
5506 args.push_back(
"-mmacosx-version-min=10.10");
5510 clang::DiagnosticOptions *diagOptions =
new clang::DiagnosticOptions();
5511 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5512 clang::DiagnosticsEngine Diags(DiagID, diagOptions, diagnosticConsumer);
5517 for (vector<const char *>::iterator i = args.begin(); i != args.end(); ++i)
5524 const StringRef stdoutPath(stdoutFile);
5525 const StringRef *redirects[] = {
5532 const char **argsz = (
const char **)malloc(
sizeof(
char *) * args.size() + 1);
5533 for (
int i = 0; i < args.size(); ++i)
5535 argsz[args.size()] =
nullptr;
5538 bool executionFailed;
5540 int ret = llvm::sys::ExecuteAndWait(args[0], argsz,
nullptr, redirects, 0, 0, &errMsg, &executionFailed);
5542 for (
auto i : argsToFree)
5546 remove(compositeModulePath.c_str());
5552 chmod(outputPath.c_str(), 0755);
5557 if (!errMsg.empty())
5560 details +=
"\n" + errMsg +
"\n";
5563 if (!stdoutFileContents.empty())
5565 VUserLog(
"%s", stdoutFileContents.c_str());
5566 details +=
"\n" + stdoutFileContents +
"\n";
5578 if (shouldAdHocCodeSign)
5579 adHocCodeSign(outputPath);
5585void VuoCompiler::adHocCodeSign(
string path)
5589 "CODESIGN_ALLOCATE=" + getCodesignAllocatePath(),
5599Module *VuoCompiler::readModuleFromC(
string inputPath,
const vector<string> &headerSearchPaths,
const vector<string> &extraArgs,
VuoCompilerIssues *issues)
5603 vector<const char *> args;
5604 vector<char *> argsToFree;
5606 args.push_back(inputPath.c_str());
5607 args.push_back(
"-DVUO_COMPILER");
5608 args.push_back(
"-fblocks");
5614 args.push_back(
"-mdisable-fp-elim");
5617 args.push_back(
"-Wall");
5618 args.push_back(
"-Wextra");
5619 args.push_back(
"-Wimplicit-fallthrough");
5620 args.push_back(
"-Wno-unused-parameter");
5621 args.push_back(
"-Wno-sign-compare");
5622 args.push_back(
"-Werror=implicit");
5626 args.push_back(
"-std=c++14");
5627 args.push_back(
"-stdlib=libc++");
5628 args.push_back(
"-fexceptions");
5629 args.push_back(
"-fcxx-exceptions");
5632 for (vector<string>::const_iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
5634 args.push_back(
"-I");
5635 args.push_back(i->c_str());
5639 string dependencyOutputPath = _dependencyOutput();
5640 if (!dependencyOutputPath.empty())
5642 char *outputObjectPath = strdup(dependencyOutputPath.substr(0, dependencyOutputPath.length() - 2).c_str());
5643 argsToFree.push_back(outputObjectPath);
5647 args.push_back(
"-MT");
5648 args.push_back(outputObjectPath);
5649 args.push_back(
"-dependency-file");
5650 args.push_back(dependencyOutputPath.c_str());
5655 args.push_back(
"-v");
5657 for (vector<string>::const_iterator i = extraArgs.begin(); i != extraArgs.end(); ++i)
5658 args.push_back(i->c_str());
5661 clang::DiagnosticOptions * diagOptions =
new clang::DiagnosticOptions();
5662 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
5663 clang::DiagnosticsEngine *diags =
new clang::DiagnosticsEngine(DiagID, diagOptions, diagnosticConsumer);
5666 shared_ptr<clang::CompilerInvocation> compilerInvocation(
new clang::CompilerInvocation);
5667 clang::CompilerInvocation::CreateFromArgs(*compilerInvocation, &args[0], &args[0] + args.size(), *diags);
5668 compilerInvocation->TargetOpts->Triple = target;
5670 clang::CompilerInstance Clang;
5671 Clang.setInvocation(compilerInvocation);
5673 Clang.setDiagnostics(diags);
5674 if (!Clang.hasDiagnostics())
5678 string builtinHeaderSearchPath;
5680 if (vuoFrameworkPath.empty())
5682 builtinHeaderSearchPath = getClangPath();
5687 builtinHeaderSearchPath +=
"lib/clang/" CLANG_VERSION_STRING;
5690 builtinHeaderSearchPath = vuoFrameworkPath +
"/Frameworks/llvm.framework/Versions/A/lib/clang/" CLANG_VERSION_STRING;
5691 Clang.getHeaderSearchOpts().ResourceDir = builtinHeaderSearchPath;
5694 clang::CodeGenAction *Act =
new clang::EmitLLVMOnlyAction();
5695 if (!Clang.ExecuteAction(*Act))
5698 for (
auto i : argsToFree)
5701 unique_ptr<Module> module = Act->takeModule();
5703 VUserLog(
"Error compiling %s: module is null.", inputPath.c_str());
5704 return module.release();
5712Module *VuoCompiler::readModuleFromBitcode(
string inputPath,
string arch)
5714 string dir, file, ext;
5717 return readModuleFromBitcode(&inputFile, arch);
5729 size_t inputDataBytes;
5733 set<string> availableArchs;
5735 Module *module = readModuleFromBitcodeData(inputData, inputDataBytes, arch, availableArchs, error);
5738 VUserLog(
"Error: Couldn't parse module '%s' (%s): %s.", inputFile->
getRelativePath().c_str(), arch.c_str(), error.c_str());
5750Module *VuoCompiler::readModuleFromBitcodeData(
char *inputData,
size_t inputDataBytes,
string arch,
5751 set<string> &availableArchs,
string &error)
5753 if (inputDataBytes <
sizeof(
unsigned int))
5756 __block Module *module =
nullptr;
5758 StringRef inputDataAsStringRef(inputData, inputDataBytes);
5759 auto mb = MemoryBuffer::getMemBuffer(inputDataAsStringRef,
"",
false);
5762 error =
"Couldn't create MemoryBuffer";
5766 MemoryBufferRef bitcodeBuffer;
5768 unsigned int fileID = *(
unsigned int *)inputData;
5769 if (fileID == 0x0b17c0de)
5771 bitcodeBuffer = mb.get()->getMemBufferRef();
5773 else if (fileID == 0xdec04342)
5776 bitcodeBuffer = mb.get()->getMemBufferRef();
5777 moduleArch =
"x86_64";
5778 availableArchs.insert(moduleArch);
5781 else if (fileID == 0xbebafeca)
5785 error =
"It's a Mach-O universal binary, but this compiler instance's LLVM target isn't set";
5791 auto binary = llvm::object::MachOUniversalBinary::create(mb.get()->getMemBufferRef());
5794 error =
"Couldn't read Mach-O universal binary:";
5795 handleAllErrors(binary.takeError(), [&error](
const ErrorInfoBase &ei) {
5796 error +=
" " + ei.message();
5801 for (
auto &o : binary.get()->objects())
5803 if (o.getArchFlagName() == arch)
5804 bitcodeBuffer = MemoryBufferRef(mb.get()->getMemBufferRef().getBuffer().slice(o.getOffset(), o.getOffset() + o.getSize()),
"");
5806 availableArchs.insert(o.getArchFlagName());
5809 if (!bitcodeBuffer.getBufferSize())
5811 error =
"The Mach-O universal binary doesn't have an \"" + arch +
"\" slice";
5816 auto wrappedModule = llvm::parseBitcodeFile(bitcodeBuffer, *globalLLVMContext);
5819 error =
"Couldn't parse bitcode file:";
5820 handleAllErrors(wrappedModule.takeError(), [&error](
const ErrorInfoBase &ei) {
5821 error +=
" " + ei.message();
5826 module = wrappedModule.get().release();
5828 if (moduleArch.empty())
5829 moduleArch = getTargetArch(module->getTargetTriple());
5831 if (availableArchs.empty())
5832 availableArchs.insert(moduleArch);
5834 if (moduleArch != arch)
5836 error =
"The module's CPU architecture \"" + moduleArch +
"\" doesn't match the compiler's CPU architecture \"" + arch +
"\"";
5852bool VuoCompiler::writeModuleToBitcode(Module *module,
string outputPath)
5855 raw_string_ostream verifyOut(str);
5856 if (llvm::verifyModule(*module, &verifyOut))
5858 VUserLog(
"Error: Module verification failed:\n%s", verifyOut.str().c_str());
5863 if (module->getTargetTriple().empty())
5864 setTargetForModule(module, getProcessTarget());
5866 std::error_code err;
5867 raw_fd_ostream out(outputPath.c_str(), err, sys::fs::F_None);
5870 VUserLog(
"Error: Couldn't open file '%s' for writing: %s", outputPath.c_str(), err.message().c_str());
5873 llvm::WriteBitcodeToFile(module, out);
5884void VuoCompiler::setTargetForModule(Module *module,
string targetTriple)
5887 llvm::Triple triple(targetTriple);
5888 if (triple.isMacOSX())
5889 triple.setOSName(
"macosx10.10.0");
5891 module->setTargetTriple(triple.str());
5894 auto target = TargetRegistry::lookupTarget(module->getTargetTriple(), error);
5897 VUserLog(
"Error: Couldn't look up target: %s", error.c_str());
5901 auto targetMachine = target->createTargetMachine(module->getTargetTriple(),
"",
"", TargetOptions(), Optional<Reloc::Model>());
5904 VUserLog(
"Error: Couldn't create targetMachine.");
5908 module->setDataLayout(targetMachine->createDataLayout());
5910 delete targetMachine;
5917string VuoCompiler::getTargetArch(
string target)
5919 auto hyphen = target.find(
'-');
5920 if (hyphen == string::npos)
5923 return target.substr(0, hyphen);
5929string VuoCompiler::getProcessTarget(
void)
5935 llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
5938 if (triple.isMacOSX())
5940 unsigned int major, minor, micro;
5941 if (triple.getMacOSXVersion(major, minor, micro))
5943 ostringstream osVersion;
5944 osVersion <<
"macosx" << major <<
"." << minor <<
"." << micro;
5945 triple.setOSName(osVersion.str());
5949 return triple.str();
5960 Module *llvmModule = module->
getModule();
5989 delete baseNodeClass;
6022 if (nodeClassForNode)
6023 return nodeClassForNode->
newNode(title, x, y);
6037 if (nodeClassForNode)
6038 return nodeClassForNode->
newNode(nodeToCopyMetadataFrom);
6049 return createPublishedNode(nodeClassName, publishedInputPorts);
6058 return createPublishedNode(nodeClassName, publishedOutputPorts);
6064VuoNode * VuoCompiler::createPublishedNode(
const string &nodeClassName,
const vector<VuoPublishedPort *> &publishedPorts)
6067 VuoNode *node = createNode(nodeClass);
6072 for (
size_t i = 0; i < publishedPorts.size(); ++i)
6074 VuoType *publishedPortType =
static_cast<VuoCompilerPort *
>(publishedPorts[i]->getCompiler())->getDataVuoType();
6078 set<VuoPort *> nodePorts;
6082 nodePorts.insert(inputPort);
6085 nodePorts.insert(outputPort);
6090 nodePorts.insert(inputPort);
6093 for (
VuoPort *port : nodePorts)
6100 reifyGenericPortTypes(node);
6111 dispatch_sync(environmentQueue, ^{
6112 if (environments.size() >= 5)
6113 environments.at(3).at(0)->addExpatriateSourceFile(sourcePath);
6123 dispatch_sync(environmentQueue, ^{
6124 if (environments.size() >= 5)
6126 environments.at(3).at(0)->removeExpatriateSourceFile(sourcePath);
6128 set<string> sourcesRemoved;
6129 sourcesRemoved.insert(getModuleKeyForPath(sourcePath));
6130 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), set<string>(), sourcesRemoved,
6131 false, false, environments.at(3).at(0), nullptr, nullptr,
"");
6154 string sourcePathCopy = sourcePath;
6155 string sourceCodeCopy = sourceCode;
6157 dispatch_async(environmentQueue, ^{
6159 ModuleInfo *sourceInfo = NULL;
6161 for (
const vector<Environment *> &envs : environments)
6163 for (Environment *env : envs)
6165 ModuleInfo *potentialSourceInfo = env->listSourceFile(nodeClassName);
6168 sourceInfo = potentialSourceInfo;
6177 bool shouldRecompileSourcesIfUnchanged;
6178 if (! sourceCodeCopy.empty())
6180 sourceInfo->setSourceCode(sourceCodeCopy);
6181 sourceInfo->setSourceCodeOverridden(
true);
6183 shouldRecompileSourcesIfUnchanged =
false;
6187 sourceInfo->revertSourceCode();
6188 sourceInfo->setSourceCodeOverridden(
false);
6190 shouldRecompileSourcesIfUnchanged =
true;
6192 sourceInfo->setAttempted(
false);
6193 sourceInfo->setLastModifiedToNow();
6195 set<string> sourcesModified;
6196 sourcesModified.insert(nodeClassName);
6198 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), sourcesModified, set<string>(),
6199 false, shouldRecompileSourcesIfUnchanged,
nullptr,
nullptr,
nullptr,
"");
6238 set<string> nodeClassNameSet;
6239 nodeClassNameSet.insert(nodeClassName);
6240 loadModulesIfNeeded(nodeClassNameSet);
6245 void (^envGetNodeClass)(Environment *) = ^
void (Environment *env) {
6250 applyToAllEnvironments(envGetNodeClass);
6261 loadModulesIfNeeded();
6263 __block map<string, VuoCompilerNodeClass *> nodeClasses;
6264 void (^envGetNodeClasses)(Environment *) = ^
void (Environment *env) {
6265 map<string, VuoCompilerNodeClass *> result = env->getNodeClasses();
6266 nodeClasses.insert(result.begin(), result.end());
6268 applyToInstalledEnvironments(envGetNodeClasses);
6279 set<string> typeNameSet;
6280 typeNameSet.insert(typeName);
6281 loadModulesIfNeeded(typeNameSet);
6284 void (^envGetType)(Environment *) = ^
void (Environment *env) {
6289 applyToInstalledEnvironments(envGetType);
6311 loadModulesIfNeeded();
6313 __block map<string, VuoCompilerType *> types;
6314 void (^envGetTypes)(Environment *) = ^
void (Environment *env) {
6315 map<string, VuoCompilerType *> result = env->getTypes();
6316 types.insert(result.begin(), result.end());
6318 applyToInstalledEnvironments(envGetTypes);
6329 set<string> libraryNameSet;
6330 libraryNameSet.insert(libraryModuleName);
6331 loadModulesIfNeeded(libraryNameSet);
6334 void (^envGetLibraryModule)(Environment *) = ^
void (Environment *env) {
6339 applyToInstalledEnvironments(envGetLibraryModule);
6351 loadModulesIfNeeded();
6353 __block map<string, VuoCompilerModule *> libraryModules;
6354 void (^envGetLibraryModules)(Environment *) = ^
void (Environment *env) {
6355 map<string, VuoCompilerModule *> result = env->getLibraryModules();
6356 libraryModules.insert(result.begin(), result.end());
6358 applyToInstalledEnvironments(envGetLibraryModules);
6359 return libraryModules;
6369 loadModulesIfNeeded();
6371 __block map<string, VuoNodeSet *> nodeSets;
6372 void (^envGetNodeSets)(Environment *) = ^
void (Environment *env) {
6373 map<string, VuoNodeSet *> result = env->getNodeSets();
6374 nodeSets.insert(result.begin(), result.end());
6376 applyToInstalledEnvironments(envGetNodeSets);
6387 loadModulesIfNeeded();
6390 void (^envFindNodeSet)(Environment *) = ^
void (Environment *env) {
6395 applyToInstalledEnvironments(envFindNodeSet);
6405 void (^envFindModule)(Environment *) = ^
void (Environment *env) {
6410 applyToAllEnvironments(envFindModule);
6427 map<string, VuoCompilerNodeClass *> nodeClasses =
getNodeClasses();
6428 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
6435 else if (format ==
"path")
6439 else if (format ==
"dot")
6461vector<string> VuoCompiler::getRunPathSearchPaths(Environment *narrowestScope)
6463 vector<string> rPaths;
6464 for (
size_t i = 0; i < environments.size(); ++i)
6468 string vuoFrameworkPath = getVuoFrameworkPath();
6469 if (! vuoFrameworkPath.empty())
6470 rPaths.push_back(vuoFrameworkPath +
"/..");
6479 if (! localModulesPath.empty())
6480 rPaths.push_back(localModulesPath);
6483 if (std::find(environments[i].begin(), environments[i].end(), narrowestScope) != environments[i].end())
6487 std::reverse(rPaths.begin(), rPaths.end());
6497vector<string> VuoCompiler::getCoreVuoDependencies(
void)
6499 vector<string> dependencies;
6501 dependencies.push_back(
"VuoHeap");
6502 dependencies.push_back(
"VuoApp");
6504 dependencies.push_back(
"zmq");
6505 dependencies.push_back(
"json-c");
6506 dependencies.push_back(
"objc");
6507 dependencies.push_back(
"c");
6508 dependencies.push_back(
"AppKit.framework");
6511 dependencies.push_back(LLVM_ROOT
"/lib/libprofile_rt.dylib");
6513 return dependencies;
6519string VuoCompiler::getRuntimeMainDependency(
void)
6521 return "VuoRuntimeMain.o";
6531string VuoCompiler::getRuntimeDependency(
void)
6533 return "VuoRuntime.o";
6544 if (! vuoFrameworkInProgressPath.empty())
6545 return vuoFrameworkInProgressPath;
6553string VuoCompiler::getClangPath(
void)
6564 string dir, moduleKey, ext;
6572 while (nodeClassNameParts.size() > 1 && nodeClassNameParts.back() == ext)
6573 nodeClassNameParts.pop_back();
6576 for (
string &part : nodeClassNameParts)
6580 if (nodeClassNameParts.size() == 1)
6581 nodeClassNameParts.insert(nodeClassNameParts.begin(),
"isf");
6595 __block
bool isLocal =
false;
6597 dispatch_sync(environmentQueue, ^{
6598 if (environments.size() >= 5)
6599 isLocal = environments.at(3).at(0)->findModule(moduleKey);
6613 return lastCompositionBaseDir.empty() ?
"" : lastCompositionBaseDir +
"/Modules";
6628 return lastCompositionBaseDir;
6634void VuoCompiler::addModuleSearchPath(
string path)
6636 dispatch_sync(environmentQueue, ^{
6637 environments.back().at(0)->addModuleSearchPath(path);
6638 environments.back().at(0)->addLibrarySearchPath(path);
6647 dispatch_sync(environmentQueue, ^{
6657 dispatch_sync(environmentQueue, ^{
6667 dispatch_sync(environmentQueue, ^{
6677 this->isVerbose = isVerbose;
6687 if (VuoPro::getProAccess())
6689 _shouldShowSplashWindow =
false;
6694 _shouldShowSplashWindow = potentiallyShow;
6705 _setDependencyOutput(path);
6714 return _shouldShowSplashWindow;
6720void VuoCompiler::setClangPath(
const string &clangPath)
6722 this->clangPath = clangPath;
6731 return (vuoFrameworkPath.empty() ?
6732 VUO_BUILD_DIR
"/bin/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader" :
6733 vuoFrameworkPath +
"/Helpers/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader");
6739string VuoCompiler::getCompositionStubPath(
void)
6741 string vuoFrameworkPath = getVuoFrameworkPath();
6742 return (vuoFrameworkPath.empty() ?
6743 VUO_BUILD_DIR
"/lib/libVuoCompositionStub.dylib" :
6744 vuoFrameworkPath +
"/Modules/libVuoCompositionStub.dylib");
6750string VuoCompiler::getCachePathForComposition(
const string compositionDir)
6752 string modifierLetterColon(
"꞉");
6753 string cachedModulesName = compositionDir;
6763 __block vector<string> moduleSearchPaths;
6764 void (^envGetModuleSearchPaths)(Environment *) = ^
void (Environment *env) {
6765 vector<string> result = env->getModuleSearchPaths();
6766 moduleSearchPaths.insert(moduleSearchPaths.end(), result.begin(), result.end());
6768 applyToInstalledEnvironments(envGetModuleSearchPaths);
6770 __block vector<string> headerSearchPaths;
6771 void (^envGetHeaderSearchPaths)(Environment *) = ^
void (Environment *env) {
6772 vector<string> result = env->getHeaderSearchPaths();
6773 headerSearchPaths.insert(headerSearchPaths.end(), result.begin(), result.end());
6775 applyToInstalledEnvironments(envGetHeaderSearchPaths);
6777 __block vector<string> librarySearchPaths;
6778 void (^envGetLibrarySearchPaths)(Environment *) = ^
void (Environment *env) {
6779 vector<string> result = env->getLibrarySearchPaths();
6780 librarySearchPaths.insert(librarySearchPaths.end(), result.begin(), result.end());
6782 applyToInstalledEnvironments(envGetLibrarySearchPaths);
6784 __block vector<string> frameworkSearchPaths;
6785 void (^envGetFrameworkSearchPaths)(Environment *) = ^
void (Environment *env) {
6786 vector<string> result = env->getFrameworkSearchPaths();
6787 frameworkSearchPaths.insert(frameworkSearchPaths.end(), result.begin(), result.end());
6789 applyToInstalledEnvironments(envGetFrameworkSearchPaths);
6791 fprintf(stderr,
"Module (node class, type, library) search paths:\n");
6792 for (vector<string>::iterator i = moduleSearchPaths.begin(); i != moduleSearchPaths.end(); ++i)
6793 fprintf(stderr,
" %s\n", (*i).c_str());
6794 fprintf(stderr,
"Header search paths:\n");
6795 for (vector<string>::iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
6796 fprintf(stderr,
" %s\n", (*i).c_str());
6797 fprintf(stderr,
"Other library search paths:\n");
6798 for (vector<string>::iterator i = librarySearchPaths.begin(); i != librarySearchPaths.end(); ++i)
6799 fprintf(stderr,
" %s\n", (*i).c_str());
6800 fprintf(stderr,
"Other framework search paths:\n");
6801 for (vector<string>::iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
6802 fprintf(stderr,
" %s\n", (*i).c_str());
6803 fprintf(stderr,
"Framework path:\n");
6806 fprintf(stderr,
"Clang path:\n");
6807 if (! getClangPath().empty())
6808 fprintf(stderr,
" %s\n", getClangPath().c_str());
6824 string directory, file, extension;
6828 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6830 remove(compiledCompositionPath.c_str());
6859 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/" + processName +
".vuo";
6865 remove(compiledCompositionPath.c_str());
6889 string directory, file, extension;
6892 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
6895 remove(compiledCompositionPath.c_str());
6924 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/UntitledComposition.vuo";
6930 remove(compiledCompositionPath.c_str());
6943 pendingDataQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.pending", 0);
6948 LoadedModulesData *data = dequeueData();
6955void VuoCompilerDelegate::enqueueData(LoadedModulesData *data)
6957 dispatch_sync(pendingDataQueue, ^{
6958 pendingData.push_back(data);
6965VuoCompilerDelegate::LoadedModulesData * VuoCompilerDelegate::dequeueData(
void)
6967 __block LoadedModulesData *ret;
6968 dispatch_sync(pendingDataQueue, ^{
6969 ret = pendingData.front();
6970 pendingData.pop_front();
6979VuoCompilerDelegate::LoadedModulesData::LoadedModulesData(
const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
6982 referenceCountQueue = dispatch_queue_create(
"org.vuo.compiler.delegate.reference", 0);
6985 this->modulesModified = modulesModified;
6986 this->modulesRemoved = modulesRemoved;
6987 this->issues = issues;
6993VuoCompilerDelegate::LoadedModulesData::~LoadedModulesData(
void)
6997 for (set< pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); ++i)
7000 for (set<VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); ++i)
7007void VuoCompilerDelegate::LoadedModulesData::retain(
void)
7009 dispatch_sync(referenceCountQueue, ^{
7017void VuoCompilerDelegate::LoadedModulesData::release(
void)
7019 dispatch_sync(referenceCountQueue, ^{
7021 if (referenceCount == 0) {