17#include <CoreFoundation/CoreFoundation.h>
59set<VuoCompiler *> VuoCompiler::allCompilers;
60dispatch_queue_t VuoCompiler::environmentQueue = dispatch_queue_create(
"org.vuo.compiler.environment", NULL);
61map<string, vector< vector<VuoCompilerEnvironment *> > > VuoCompiler::sharedEnvironments;
62map<string, map<string, vector<VuoCompilerEnvironment *> > > VuoCompiler::environmentsForCompositionFamily;
63map<VuoCompilerEnvironment *, map<string, pair<VuoCompilerModule *, dispatch_group_t>>> VuoCompiler::invalidatedModulesAwaitingRecompilation;
64map<VuoCompilerEnvironment *, set<VuoCompilerModule *>> VuoCompiler::addedModulesAwaitingReification;
65map<VuoCompilerEnvironment *, set<pair<VuoCompilerModule *, VuoCompilerModule *>>> VuoCompiler::modifiedModulesAwaitingReification;
66dispatch_group_t VuoCompiler::moduleSourceCompilersExistGlobally = dispatch_group_create();
67string VuoCompiler::vuoFrameworkInProgressPath;
76static void __attribute__((constructor)) VuoCompiler_init(
void)
79 struct rlimit rl{OPEN_MAX, OPEN_MAX};
80 getrlimit(RLIMIT_NOFILE, &rl);
81 rl.rlim_cur =
MIN(OPEN_MAX, rl.rlim_max);
82 if (setrlimit(RLIMIT_NOFILE, &rl))
83 VUserLog(
"Warning: Couldn't set open-files limit: %s", strerror(errno));
86 llvmQueue = dispatch_queue_create(
"org.vuo.compiler.llvm", NULL);
90 llvm::InitializeAllTargetMCs();
91 llvm::InitializeAllTargets();
100 raw_string_ostream stream(message);
101 DiagnosticPrinterRawOStream printer(stream);
104 if (! message.empty())
106 const char *severityName;
107 if (DI.getSeverity() == DS_Error)
108 severityName =
"error";
109 else if (DI.getSeverity() == DS_Warning)
110 severityName =
"warning";
112 severityName =
"note";
114 VuoLog(
VuoLog_moduleName, __FILE__, __LINE__,
"llvmDiagnosticHandler",
"%s: %s", severityName, message.c_str());
148void VuoCompiler::applyToInstalledEnvironments(std::function<
void(
VuoCompilerEnvironment *)> doForEnvironment)
150 dispatch_sync(environmentQueue, ^{
151 for (vector< vector<VuoCompilerEnvironment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
152 doForEnvironment((*i)[0]);
162 dispatch_sync(environmentQueue, ^{
163 for (vector< vector<VuoCompilerEnvironment *> >::iterator i = environments.begin(); i != environments.end(); ++i) {
164 for (vector<VuoCompilerEnvironment *>::iterator j = i->begin(); j != i->end(); ++j) {
165 doForEnvironment(*j);
177 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
179 if (find(environmentsAtScope.begin(), environmentsAtScope.end(), envA) != environmentsAtScope.end())
181 if (find(environmentsAtScope.begin(), environmentsAtScope.end(), envB) != environmentsAtScope.end())
193 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
194 if (find(environmentsAtScope.begin(), environmentsAtScope.end(), env) != environmentsAtScope.end())
195 return environmentsAtScope.back();
218 target = getProcessTarget();
221 llvm::Triple triple(target);
222 triple.setOSName(
"macosx10.10.0");
223 target = triple.str();
225 VDebugLog(
"%p target=%s (from current process)",
this, target.c_str());
229 requestedTarget = target;
230 VDebugLog(
"%p target=%s",
this, target.c_str());
232 this->target = target;
238 shouldLoadAllModules =
true;
239 hasLoadedAllModules =
false;
240 modulesToLoadQueue = dispatch_queue_create(
"org.vuo.compiler.modules", NULL);
241 modulesLoading = dispatch_group_create();
242 moduleSourceCompilersExist = dispatch_group_create();
243 moduleCacheBuilding = dispatch_group_create();
244 dependencyGraph = NULL;
245 compositionDependencyGraph = NULL;
247 _shouldShowSplashWindow =
false;
249 delegateQueue = dispatch_queue_create(
"org.vuo.compiler.delegate", NULL);
252 if (! vuoFrameworkPath.empty())
253 clangPath = vuoFrameworkPath +
"/Helpers/clang";
255 clangPath = LLVM_ROOT
"/bin/clang";
257 dispatch_sync(environmentQueue, ^{
258 allCompilers.insert(
this);
260 if (sharedEnvironments[target].empty())
262 sharedEnvironments[target] = vector< vector<VuoCompilerEnvironment *> >(3, vector<VuoCompilerEnvironment *>(2, NULL));
263 for (vector< vector<VuoCompilerEnvironment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
264 for (vector<VuoCompilerEnvironment *>::iterator j = i->begin(); j != i->end(); ++j)
268 for (vector<string>::iterator i = builtInModuleSearchPaths.begin(); i != builtInModuleSearchPaths.end(); ++i)
269 sharedEnvironments[target][0][0]->addModuleSearchPath(*i,
false);
272 for (vector<string>::iterator i = builtInLibrarySearchPaths.begin(); i != builtInLibrarySearchPaths.end(); ++i)
276 for (vector<string>::iterator i = builtInFrameworkSearchPaths.begin(); i != builtInFrameworkSearchPaths.end(); ++i)
291 if (! vuoFrameworkPath.empty())
297 sharedEnvironments[target][0][0]->setModuleCache(builtInCache);
298 sharedEnvironments[target][0][1]->setModuleCache(builtInCache);
299 sharedEnvironments[target][1][0]->setModuleCache(systemCache);
300 sharedEnvironments[target][1][1]->setModuleCache(systemCache);
301 sharedEnvironments[target][2][0]->setModuleCache(userCache);
302 sharedEnvironments[target][2][1]->setModuleCache(userCache);
319 dispatch_sync(environmentQueue, ^{
320 allCompilers.erase(
this);
323 dispatch_group_wait(moduleCacheBuilding, DISPATCH_TIME_FOREVER);
324 dispatch_release(moduleCacheBuilding);
326 dispatch_group_wait(moduleSourceCompilersExist, DISPATCH_TIME_FOREVER);
327 dispatch_release(moduleSourceCompilersExist);
329 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
333 dispatch_sync(delegateQueue, ^{});
335 dispatch_release(modulesToLoadQueue);
336 dispatch_release(delegateQueue);
337 dispatch_release(modulesLoading);
339 delete dependencyGraph;
340 delete compositionDependencyGraph;
346void VuoCompiler::reset(
void)
348 dispatch_group_wait(moduleSourceCompilersExistGlobally, DISPATCH_TIME_FOREVER);
350 dispatch_sync(environmentQueue, ^{
352 for (
auto e : sharedEnvironments)
355 (*i)[0]->stopWatchingModuleSearchPaths();
356 dispatch_sync((*i)[0]->moduleSearchPathContentsChangedQueue, ^{});
359 for (
auto e : environmentsForCompositionFamily)
360 for (map< string, vector<
VuoCompilerEnvironment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
362 (i->second)[0]->stopWatchingModuleSearchPaths();
363 dispatch_sync((i->second)[0]->moduleSearchPathContentsChangedQueue, ^{});
366 for (
auto e : sharedEnvironments)
368 for (vector<VuoCompilerEnvironment *>::iterator j = i->begin(); j != i->end(); ++j)
371 for (
auto e : environmentsForCompositionFamily)
372 for (map< string, vector<
VuoCompilerEnvironment *> >::iterator i = e.second.begin(); i != e.second.end(); ++i)
373 for (vector<VuoCompilerEnvironment *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
376 allCompilers.clear();
377 sharedEnvironments.clear();
378 environmentsForCompositionFamily.clear();
390 dispatch_async(delegateQueue, ^{
391 this->delegate = delegate;
406 string compositionModulesDir;
407 string compositionBaseDir;
408 bool isSubcomposition =
false;
409 string compositionPath = compositionPathOrig;
410 if (! compositionPath.empty())
421 string compositionDir;
424 isSubcomposition = (compositionDir == compositionModulesDir);
429 dispatch_sync(environmentQueue, ^{
430 if (! environments.empty() && compositionBaseDir == lastCompositionBaseDir) {
433 lastCompositionBaseDir = compositionBaseDir;
438 vector<VuoCompilerEnvironment *> compositionEnvironments;
439 if (! environments.empty())
441 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
445 if (environments.size() >= 5) {
446 oldCompositionFamilyInstalledEnvironment = environments[3][0];
449 compositionEnvironments = environments.back();
451 environments.clear();
458 bool isCompositionInSharedEnvironment =
false;
459 for (vector< vector<VuoCompilerEnvironment *> >::iterator i = sharedEnvironments[target].begin(); i != sharedEnvironments[target].end(); ++i)
461 environments.push_back(*i);
463 vector<string> moduleSearchPaths = (*i)[0]->getModuleSearchPaths();
464 for (vector<string>::iterator j = moduleSearchPaths.begin(); j != moduleSearchPaths.end(); ++j)
466 string moduleSearchPath = *j;
468 if (moduleSearchPath == compositionModulesDir)
470 isCompositionInSharedEnvironment =
true;
475 if (isCompositionInSharedEnvironment) {
483 if (! isCompositionInSharedEnvironment && ! compositionPath.empty())
485 vector<VuoCompilerEnvironment *> compositionFamilyEnvironments = environmentsForCompositionFamily[target][compositionBaseDir];
486 if (compositionFamilyEnvironments.empty())
488 compositionFamilyEnvironments = vector<VuoCompilerEnvironment *>(2, NULL);
491 environmentsForCompositionFamily[target][compositionBaseDir] = compositionFamilyEnvironments;
495 compositionFamilyEnvironments[0]->addModuleSearchPath(compositionModulesDir);
498 compositionFamilyEnvironments[0]->setModuleCache(moduleCache);
499 compositionFamilyEnvironments[1]->setModuleCache(moduleCache);
501 environments.push_back(compositionFamilyEnvironments);
503 newCompositionFamilyInstalledEnvironment = compositionFamilyEnvironments[0];
508 if (compositionEnvironments.empty())
510 compositionEnvironments = vector<VuoCompilerEnvironment *>(2, NULL);
515 compositionEnvironments[0]->setModuleCache(moduleCache);
516 compositionEnvironments[1]->setModuleCache(moduleCache);
518 environments.push_back(compositionEnvironments);
525 int generatedModulesScope = isCompositionInSharedEnvironment || isSubcomposition ? environments.size() - 2 : environments.size() - 1;
526 generatedEnvironment = environments[generatedModulesScope][1];
528 for (
auto i : environments)
532 delete dependencyGraph;
533 delete compositionDependencyGraph;
540 if (oldCompositionFamilyInstalledEnvironment != newCompositionFamilyInstalledEnvironment)
544 map<string, VuoCompilerModule *> modules;
560 map<string, VuoCompilerModule *> modulesAdded = getModules(newCompositionFamilyInstalledEnvironment);
561 map<string, VuoCompilerModule *> modulesRemoved = getModules(oldCompositionFamilyInstalledEnvironment);
563 map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified;
564 for (map<string, VuoCompilerModule *>::iterator
add = modulesAdded.begin();
add != modulesAdded.end(); )
566 map<string, VuoCompilerModule *>::iterator rem = modulesRemoved.find(
add->first);
567 if (rem != modulesRemoved.end())
569 modulesModified[
add->first] = make_pair(rem->second,
add->second);
570 modulesAdded.erase(
add++);
571 modulesRemoved.erase(rem);
579 if (! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty()) )
582 VuoCompilerDelegate::LoadedModulesData *delegateData =
new VuoCompilerDelegate::LoadedModulesData(set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), set<VuoCompilerModule *>(), issues);
583 delegateData->retain();
586 if (! scopeEnvironment) {
587 scopeEnvironment = compositionEnvironments.at(0);
590 loadedModules(modulesAdded, modulesModified, modulesRemoved, issues, delegateData, scopeEnvironment);
601VuoDirectedAcyclicNetwork * VuoCompiler::makeDependencyNetwork(
const vector< vector<VuoCompilerEnvironment *> > &environments,
604 if (!graphForEnvironment)
609 for (vector< vector<VuoCompilerEnvironment *> >::const_iterator i = environments.begin(); i != environments.end(); ++i)
613 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(i->at(1)));
617 for (vector< vector<VuoCompilerEnvironment *> >::const_iterator ii = environments.begin(); ii != i; ++ii)
619 network->
addEdge(graphForEnvironment(i->at(0)), graphForEnvironment(ii->at(0)));
620 network->
addEdge(graphForEnvironment(i->at(1)), graphForEnvironment(ii->at(0)));
637 bool foundModuleInfoInNarrowerEnvironment =
false;
639 auto envGetModule = [&moduleKey, &module, &foundModuleInfoInNarrowerEnvironment] (
VuoCompilerEnvironment *env)
644 module = foundModule;
645 foundModuleInfoInNarrowerEnvironment =
false;
647 else if (module && ! foundModuleInfoInNarrowerEnvironment && (env->
listModule(moduleKey) || env->
listSourceFile(moduleKey)))
649 foundModuleInfoInNarrowerEnvironment =
true;
653 applyToAllEnvironments(envGetModule);
657 if (! module || foundModuleInfoInNarrowerEnvironment)
659 loadModulesIfNeeded({moduleKey});
660 applyToAllEnvironments(envGetModule);
686void VuoCompiler::loadModulesIfNeeded(
const set<string> &moduleKeys)
688 dispatch_group_enter(modulesLoading);
689 VuoDefer(^{ dispatch_group_leave(modulesLoading); });
691 __block
bool willLoadAllModules =
false;
692 dispatch_sync(modulesToLoadQueue, ^{
693 if (shouldLoadAllModules && ! hasLoadedAllModules) {
694 willLoadAllModules =
true;
695 hasLoadedAllModules =
true;
699 if (! willLoadAllModules && moduleKeys.empty())
704 __block set<dispatch_group_t> sourcesLoading;
705 dispatch_sync(environmentQueue, ^{
706 sourcesLoading = loadModulesAndSources(moduleKeys, set<string>(), set<string>(),
707 moduleKeys, set<string>(), set<string>(),
708 willLoadAllModules,
false,
nullptr,
nullptr,
nullptr,
"");
714 for (set<dispatch_group_t>::iterator i = sourcesLoading.begin(); i != sourcesLoading.end(); ++i)
716 dispatch_group_wait(*i, DISPATCH_TIME_FOREVER);
717 dispatch_release(*i);
729set<dispatch_group_t> VuoCompiler::loadModulesAndSources(
const set<string> &modulesAddedKeys,
const set<string> &modulesModifiedKeys,
const set<string> &modulesRemovedKeys,
730 const set<string> &sourcesAddedKeys,
const set<string> &sourcesModifiedKeys,
const set<string> &sourcesRemovedKeys,
731 bool willLoadAllModules,
bool shouldRecompileSourcesIfUnchanged,
733 std::function<
void(
void)> moduleLoadedCallback,
const string &moduleAddedOrModifiedSourceCode)
745 map<VuoCompilerEnvironment *, set<string> > modulesAdded;
746 map<VuoCompilerEnvironment *, set<string> > modulesModified;
747 map<VuoCompilerEnvironment *, set<string> > modulesRemoved;
748 map<VuoCompilerEnvironment *, set<string> > sourcesAdded;
749 map<VuoCompilerEnvironment *, set<string> > sourcesModified;
750 map<VuoCompilerEnvironment *, set<string> > sourcesRemoved;
752 if (currentEnvironment)
754 modulesAdded[currentEnvironment] = modulesAddedKeys;
755 modulesModified[currentEnvironment] = modulesModifiedKeys;
756 modulesRemoved[currentEnvironment] = modulesRemovedKeys;
757 sourcesAdded[currentEnvironment] = sourcesAddedKeys;
758 sourcesModified[currentEnvironment] = sourcesModifiedKeys;
759 sourcesRemoved[currentEnvironment] = sourcesRemovedKeys;
763 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
767 bool willLoadAllModulesInEnv = willLoadAllModules && ! env->
isGenerated();
774 while ((moduleInfo = modulesAddedIter.
next()))
778 modulesAdded[env].insert(moduleKey);
783 auto isCompiledModuleAtSameSearchPath = [&env] (
VuoModuleInfo *sourceInfo)
786 return (compiledModuleInfo && compiledModuleInfo->
getSearchPath() == sourceInfo->getSearchPath());
789 while ((moduleInfo = sourcesAddedIter.
next()))
791 if (isCompiledModuleAtSameSearchPath(moduleInfo))
797 while ((moduleInfo = sourcesModifiedIter.
next()))
799 if (isCompiledModuleAtSameSearchPath(moduleInfo))
802 sourcesModified[env].insert( moduleInfo->
getModuleKey() );
808 map<VuoCompilerEnvironment *, VuoCompilerIssues *> issues;
809 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
811 issues[env] = (env == currentEnvironment && issuesForCurrentEnvironment ? issuesForCurrentEnvironment : new
VuoCompilerIssues());
815 for (vector< vector<VuoCompilerEnvironment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
824 set<string> sourcesAddedModified;
825 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
826 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
828 for (set<string>::iterator j = sourcesAddedModified.begin(); j != sourcesAddedModified.end(); ++j)
830 string moduleKey = *j;
833 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator k = circularDependencies.begin(); k != circularDependencies.end(); ++k)
845 sourcesAdded[env].erase(moduleKey);
846 sourcesModified[env].erase(moduleKey);
849 "Subcomposition contains itself",
850 "%moduleKey contains an instance of itself, "
851 "or contains another subcomposition that contains an instance of %moduleKey.");
852 issue.setModuleKey(moduleKey);
858 issues[env]->append(issue);
865 for (
const vector<VuoCompilerEnvironment *> &envs : environments)
869 set<string> sourcesAddedModified;
870 sourcesAddedModified.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
871 sourcesAddedModified.insert(sourcesModified[env].begin(), sourcesModified[env].end());
873 for (
const string &moduleKey : sourcesAddedModified)
887 map<VuoCompilerEnvironment *, set<string> > modulesDepOnModulesModified;
888 map<VuoCompilerEnvironment *, set<string> > modulesDepOnModulesRemoved;
889 map<VuoCompilerEnvironment *, set<string> > sourcesDepOnModulesRemoved;
891 map<VuoCompilerEnvironment *, set<string> > sourcesDirectDepOnModulesModified;
894 map<VuoCompilerEnvironment *, set<string> > sourcesDepOnModulesModified;
896 __block map<VuoCompilerEnvironment *, set<string> > modulesDepOnModulesModified_otherCompiler;
897 __block map<VuoCompilerEnvironment *, set<string> > sourcesDepOnModulesModified_otherCompiler;
898 __block map<VuoCompilerEnvironment *, set<string> > modulesDepOnModulesRemoved_otherCompiler;
899 __block map<VuoCompilerEnvironment *, set<string> > sourcesDepOnModulesRemoved_otherCompiler;
901 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
903 searchDependencyGraphs.push_back(compiler->dependencyGraph);
907 findDependentModulesAndSources(modulesModified, searchDependencyGraphs, currentEnvironmentDependencyGraph,
true,
908 modulesDepOnModulesModified, modulesDepOnModulesModified_otherCompiler,
909 sourcesDepOnModulesModified, sourcesDepOnModulesModified_otherCompiler);
911 findDependentModulesAndSources(modulesRemoved, searchDependencyGraphs, currentEnvironmentDependencyGraph,
true,
912 modulesDepOnModulesRemoved, modulesDepOnModulesRemoved_otherCompiler,
913 sourcesDepOnModulesRemoved, sourcesDepOnModulesRemoved_otherCompiler);
915 map<VuoCompilerEnvironment *, set<string> > modulesDirectDepOnModulesModified;
916 map<VuoCompilerEnvironment *, set<string> > modulesDirectDepOnModulesRemoved;
917 map<VuoCompilerEnvironment *, set<string> > sourcesDirectDepOnModulesRemoved;
919 __block map<VuoCompilerEnvironment *, set<string> > modulesDirectDepOnModulesModified_otherCompiler;
920 __block map<VuoCompilerEnvironment *, set<string> > sourcesDirectDepOnModulesModified_otherCompiler;
921 __block map<VuoCompilerEnvironment *, set<string> > modulesDirectDepOnModulesRemoved_otherCompiler;
922 __block map<VuoCompilerEnvironment *, set<string> > sourcesDirectDepOnModulesRemoved_otherCompiler;
924 findDependentModulesAndSources(modulesModified, searchDependencyGraphs, currentEnvironmentDependencyGraph,
false,
925 modulesDirectDepOnModulesModified, modulesDirectDepOnModulesModified_otherCompiler,
926 sourcesDirectDepOnModulesModified, sourcesDirectDepOnModulesModified_otherCompiler);
928 findDependentModulesAndSources(modulesRemoved, searchDependencyGraphs, currentEnvironmentDependencyGraph,
false,
929 modulesDirectDepOnModulesRemoved, modulesDirectDepOnModulesRemoved_otherCompiler,
930 sourcesDirectDepOnModulesRemoved, sourcesDirectDepOnModulesRemoved_otherCompiler);
932 auto insertInvalidatedModulesAwaitingRecompilation = [](
const map<VuoCompilerEnvironment *, set<string> > &modulesToInsert)
934 for (
auto i : modulesToInsert)
937 for (
const string &moduleKey : i.second)
940 invalidatedModulesAwaitingRecompilation[env][moduleKey] = { module,
nullptr };
945 insertInvalidatedModulesAwaitingRecompilation(sourcesDepOnModulesModified);
946 insertInvalidatedModulesAwaitingRecompilation(sourcesDepOnModulesModified_otherCompiler);
948 set<VuoCompilerEnvironment *> otherEnvironments;
949 for (
auto i : modulesDepOnModulesModified_otherCompiler)
950 otherEnvironments.insert(i.first);
951 for (
auto i : sourcesDepOnModulesModified_otherCompiler)
952 otherEnvironments.insert(i.first);
953 for (
auto i : modulesDepOnModulesRemoved_otherCompiler)
954 otherEnvironments.insert(i.first);
955 for (
auto i : sourcesDepOnModulesRemoved_otherCompiler)
956 otherEnvironments.insert(i.first);
967 goto foundOtherCompiler;
971 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
972 dispatch_sync(environmentQueue, ^{
973 otherCompiler->loadModulesAndSources(set<string>(), modulesDepOnModulesModified_otherCompiler[env], modulesDepOnModulesRemoved_otherCompiler[env],
974 set<string>(), sourcesDirectDepOnModulesModified_otherCompiler[env], sourcesDirectDepOnModulesRemoved_otherCompiler[env],
975 false,
true, env,
nullptr,
nullptr,
"");
985 map<VuoCompilerEnvironment *, set<VuoCompilerModule *> > actualModulesRemoved;
986 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
990 set<string> modulesToUnload;
991 modulesToUnload.insert(modulesRemoved[env].begin(), modulesRemoved[env].end());
992 modulesToUnload.insert(modulesModified[env].begin(), modulesModified[env].end());
993 modulesToUnload.insert(modulesDepOnModulesRemoved[env].begin(), modulesDepOnModulesRemoved[env].end());
994 modulesToUnload.insert(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end());
1007 map<VuoCompilerEnvironment *, set<string> > modulesToLoad;
1008 map<VuoCompilerEnvironment *, map<string, string> > modulesToLoadSourceCode;
1009 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1013 auto moduleNotInvalidated = [env] (
const string &moduleKey)
1015 return invalidatedModulesAwaitingRecompilation[env].find(moduleKey) == invalidatedModulesAwaitingRecompilation[env].end();
1018 if (env == currentEnvironment && moduleLoadedCallback)
1020 modulesToLoad[env].insert(modulesModified[env].begin(), modulesModified[env].end());
1021 modulesToLoad[env].insert(modulesAdded[env].begin(), modulesAdded[env].end());
1025 std::copy_if(modulesAdded[env].begin(), modulesAdded[env].end(),
1026 std::inserter(modulesToLoad[env], modulesToLoad[env].end()),
1027 moduleNotInvalidated);
1028 std::copy_if(modulesModified[env].begin(), modulesModified[env].end(),
1029 std::inserter(modulesToLoad[env], modulesToLoad[env].end()),
1030 moduleNotInvalidated);
1033 std::copy_if(modulesDepOnModulesModified[env].begin(), modulesDepOnModulesModified[env].end(),
1034 std::inserter(modulesToLoad[env], modulesToLoad[env].end()),
1035 moduleNotInvalidated);
1037 if (env == currentEnvironment && moduleLoadedCallback)
1039 if (modulesAdded[env].size() == 1)
1040 modulesToLoadSourceCode[env][*modulesAdded[env].begin()] = moduleAddedOrModifiedSourceCode;
1041 else if (modulesModified[env].size() == 1)
1042 modulesToLoadSourceCode[env][*modulesModified[env].begin()] = moduleAddedOrModifiedSourceCode;
1047 set<string> modulesAttempted;
1048 modulesAttempted.insert(modulesAddedKeys.begin(), modulesAddedKeys.end());
1049 modulesAttempted.insert(modulesModifiedKeys.begin(), modulesModifiedKeys.end());
1051 map<VuoCompilerEnvironment *, set<VuoCompilerModule *> > actualModulesAdded;
1052 map<string, VuoCompilerEnvironment *> broadestEnvironmentThatDependsOnModule;
1053 while (! modulesToLoad.empty())
1055 map<VuoCompilerEnvironment *, set<string>> dependenciesToLoad;
1057 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1061 set<VuoCompilerModule *> actualModulesLoaded = env->loadCompiledModules(modulesToLoad[env], modulesToLoadSourceCode[env],
llvmQueue);
1063 actualModulesAdded[env].insert(actualModulesLoaded.begin(), actualModulesLoaded.end());
1064 modulesToLoad.erase(env);
1067 for (set<VuoCompilerModule *>::iterator j = actualModulesLoaded.begin(); j != actualModulesLoaded.end(); ++j)
1069 set<string> dependencies = (*j)->getDependencies();
1070 dependenciesToLoad[env].insert(dependencies.begin(), dependencies.end());
1072 for (
const string &dependency : dependencies)
1075 broadestEnvironmentThatDependsOnModule[dependency] = currEnv ? environmentAtBroaderScope(currEnv, env) : env;
1078 modulesAttempted.insert(dependencies.begin(), dependencies.end());
1084 for (
auto i : dependenciesToLoad)
1088 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1094 while ((moduleInfo = dependenciesInEnv.
next()))
1097 modulesToLoad[env].insert(moduleKey);
1101 if (find(environmentsAtScope.begin(), environmentsAtScope.end(), dependentEnv) != environmentsAtScope.end())
1109 if (moduleLoadedCallback)
1110 moduleLoadedCallback();
1120 vector<string> actualModulesAddedKeys;
1121 for (
auto i : actualModulesAdded)
1123 actualModulesAddedKeys.push_back(module->getPseudoBase()->getModuleKey());
1125 vector<string> modulesNotAdded;
1126 std::set_difference(modulesAttempted.begin(), modulesAttempted.end(),
1127 actualModulesAddedKeys.begin(), actualModulesAddedKeys.end(),
1128 std::back_inserter(modulesNotAdded));
1130 auto moduleNotAlreadyLoaded = [
this] (
const string &moduleKey)
1132 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1134 if (env->findModule(moduleKey))
1140 set<string> potentialSpecializedModules;
1141 std::copy_if(modulesNotAdded.begin(), modulesNotAdded.end(),
1142 std::inserter(potentialSpecializedModules, potentialSpecializedModules.begin()),
1143 moduleNotAlreadyLoaded);
1148 map<VuoCompilerEnvironment *, set<string>> potentialSpecializedModulesByEnvironment;
1149 for (
const string &moduleKey : potentialSpecializedModules)
1153 auto envIter = broadestEnvironmentThatDependsOnModule.find(moduleKey);
1154 if (envIter != broadestEnvironmentThatDependsOnModule.end())
1155 envForLoadingModule = generatedEnvironmentAtSameScopeAs(envIter->second);
1157 potentialSpecializedModulesByEnvironment[envForLoadingModule].insert(moduleKey);
1160 set<dispatch_group_t> specializedModulesLoading;
1161 for (
auto i : potentialSpecializedModulesByEnvironment)
1165 specializedModulesLoading.insert(s.begin(), s.end());
1172 for (vector< vector<VuoCompilerEnvironment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
1176 set<string> sourcesToUnload;
1177 sourcesToUnload.insert(sourcesRemoved[env].begin(), sourcesRemoved[env].end());
1178 sourcesToUnload.insert(sourcesDepOnModulesRemoved[env].begin(), sourcesDepOnModulesRemoved[env].end());
1179 if (! sourcesToUnload.empty())
1183 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1186 dispatch_sync(environmentQueue, ^{
1187 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), sourcesToUnload,
1188 set<string>(), set<string>(), set<string>(),
1189 false,
false, env,
nullptr,
nullptr,
"");
1192 delete otherCompiler;
1199 env->deleteFromCompiledModuleCache(sourcesToUnload);
1207 map<VuoCompilerEnvironment *, set<string> > sourcesDirectDepOnModulesAdded;
1209 map<VuoCompilerEnvironment *, set<string> > modulesDirectDepOnModulesAdded;
1210 map<VuoCompilerEnvironment *, set<string> > modulesDirectDepOnModulesAdded_otherCompiler;
1211 __block map<VuoCompilerEnvironment *, set<string> > sourcesDirectDepOnModulesAdded_otherCompiler;
1213 map<VuoCompilerEnvironment *, set<string> > actualModuleKeysAdded;
1214 for (
const vector<VuoCompilerEnvironment *> &envs : environments)
1218 actualModuleKeysAdded[env].insert( module->getPseudoBase()->getModuleKey() );
1221 vector<VuoDirectedAcyclicNetwork *> searchDependencyGraphs;
1222 searchDependencyGraphs.push_back(compositionDependencyGraph);
1223 for (map<
string, vector<VuoCompilerEnvironment *> >::iterator ii = environmentsForCompositionFamily[target].begin(); ii != environmentsForCompositionFamily[target].end(); ++ii)
1225 vector< vector<VuoCompilerEnvironment *> > otherEnvs = sharedEnvironments[target];
1226 otherEnvs.push_back(ii->second);
1228 searchDependencyGraphs.push_back(other);
1233 findDependentModulesAndSources(actualModuleKeysAdded, searchDependencyGraphs, currentEnvironmentDependencyGraph,
false,
1234 modulesDirectDepOnModulesAdded, modulesDirectDepOnModulesAdded_otherCompiler,
1235 sourcesDirectDepOnModulesAdded, sourcesDirectDepOnModulesAdded_otherCompiler);
1237 set<VuoCompilerEnvironment *> otherEnvironments;
1238 for (map<
VuoCompilerEnvironment *, set<string> >::iterator i = sourcesDirectDepOnModulesAdded_otherCompiler.begin(); i != sourcesDirectDepOnModulesAdded_otherCompiler.end(); ++i)
1239 otherEnvironments.insert(i->first);
1243 dispatch_group_enter(moduleSourceCompilersExist);
1244 dispatch_group_enter(moduleSourceCompilersExistGlobally);
1246 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
1250 dispatch_sync(environmentQueue, ^{
1251 otherCompiler->loadModulesAndSources(set<string>(), set<string>(), set<string>(),
1252 sourcesDirectDepOnModulesAdded_otherCompiler[env], set<string>(), set<string>(),
1253 false,
true, env,
nullptr,
nullptr,
"");
1256 delete otherCompiler;
1258 dispatch_group_leave(moduleSourceCompilersExist);
1259 dispatch_group_leave(moduleSourceCompilersExistGlobally);
1264 set<dispatch_group_t> sourcesLoading;
1265 for (
const vector<VuoCompilerEnvironment *> &envs : environments)
1269 auto moduleNotInvalidated = [env] (
const string &moduleKey)
1271 return invalidatedModulesAwaitingRecompilation[env].find(moduleKey) == invalidatedModulesAwaitingRecompilation[env].end();
1274 set<string> sourcesToCompile;
1275 set<string> otherSourcesForCallerToWaitOn;
1276 if (env == currentEnvironment)
1278 sourcesToCompile.insert(sourcesAdded[env].begin(), sourcesAdded[env].end());
1279 sourcesToCompile.insert(sourcesModified[env].begin(), sourcesModified[env].end());
1283 set<string> addedSourcesToCompile;
1284 set<string> modifiedSourcesToCompile;
1286 std::copy_if(sourcesAdded[env].begin(), sourcesAdded[env].end(),
1287 std::inserter(addedSourcesToCompile, addedSourcesToCompile.end()),
1288 moduleNotInvalidated);
1289 std::copy_if(sourcesModified[env].begin(), sourcesModified[env].end(),
1290 std::inserter(modifiedSourcesToCompile, modifiedSourcesToCompile.end()),
1291 moduleNotInvalidated);
1293 sourcesToCompile.insert(addedSourcesToCompile.begin(), addedSourcesToCompile.end());
1294 sourcesToCompile.insert(modifiedSourcesToCompile.begin(), modifiedSourcesToCompile.end());
1296 std::set_difference(sourcesAdded[env].begin(), sourcesAdded[env].end(),
1297 addedSourcesToCompile.begin(), addedSourcesToCompile.end(),
1298 std::inserter(otherSourcesForCallerToWaitOn, otherSourcesForCallerToWaitOn.end()));
1299 std::set_difference(sourcesModified[env].begin(), sourcesModified[env].end(),
1300 modifiedSourcesToCompile.begin(), modifiedSourcesToCompile.end(),
1301 std::inserter(otherSourcesForCallerToWaitOn, otherSourcesForCallerToWaitOn.end()));
1304 if (! sourcesToCompile.empty())
1307 sourcesLoading.insert(s.begin(), s.end());
1310 for (
const string &moduleKey : otherSourcesForCallerToWaitOn)
1312 dispatch_group_t preloadingGroup = invalidatedModulesAwaitingRecompilation[env][moduleKey].second;
1313 if (! preloadingGroup)
1315 preloadingGroup = dispatch_group_create();
1316 dispatch_group_enter(preloadingGroup);
1317 invalidatedModulesAwaitingRecompilation[env][moduleKey].second = preloadingGroup;
1319 sourcesLoading.insert(preloadingGroup);
1323 for (vector< vector<VuoCompilerEnvironment *> >::iterator i = environments.begin(); i != environments.end(); ++i)
1327 set<string> sourcesToCompile;
1328 sourcesToCompile.insert(sourcesDirectDepOnModulesAdded[env].begin(), sourcesDirectDepOnModulesAdded[env].end());
1329 sourcesToCompile.insert(sourcesDirectDepOnModulesModified[env].begin(), sourcesDirectDepOnModulesModified[env].end());
1331 if (! sourcesToCompile.empty())
1338 map<VuoCompilerEnvironment *, set< pair<VuoCompilerModule *, VuoCompilerModule *> > > actualModulesModified;
1339 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1343 for (set<VuoCompilerModule *>::iterator
add = actualModulesAdded[env].begin();
add != actualModulesAdded[env].end(); )
1349 auto rem = std::find_if(actualModulesRemoved[env].begin(), actualModulesRemoved[env].end(),
1351 if (rem != actualModulesRemoved[env].end())
1353 removedModule = *rem;
1354 actualModulesRemoved[env].erase(rem);
1358 auto invalidatedIter = invalidatedModulesAwaitingRecompilation[env].find(moduleKey);
1359 if (invalidatedIter != invalidatedModulesAwaitingRecompilation[env].end())
1361 removedModule = invalidatedIter->second.first;
1362 dispatch_group_t preloadingGroup = invalidatedIter->second.second;
1364 invalidatedModulesAwaitingRecompilation[env].erase(invalidatedIter);
1366 if (preloadingGroup)
1367 dispatch_group_leave(preloadingGroup);
1373 actualModulesModified[env].insert({removedModule, addedModule});
1374 actualModulesAdded[env].erase(
add++);
1385 if (currentEnvironment && moduleLoadedCallback)
1387 for (
const string &moduleKey : modulesRemoved[currentEnvironment])
1389 auto foundIter = invalidatedModulesAwaitingRecompilation[currentEnvironment].find(moduleKey);
1390 if (foundIter != invalidatedModulesAwaitingRecompilation[currentEnvironment].end())
1393 dispatch_group_t preloadingGroup = foundIter->second.second;
1395 actualModulesRemoved[currentEnvironment].insert(module);
1396 invalidatedModulesAwaitingRecompilation[currentEnvironment].erase(foundIter);
1398 if (preloadingGroup)
1399 dispatch_group_leave(preloadingGroup);
1407 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1411 for (
auto i : invalidatedModulesAwaitingRecompilation[env])
1415 auto foundIter = actualModulesRemoved[env].find(module);
1416 if (foundIter != actualModulesRemoved[env].end())
1417 actualModulesRemoved[env].erase(foundIter);
1425 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1429 addedModulesAwaitingReification[env].insert(actualModulesAdded[env].begin(), actualModulesAdded[env].end());
1430 modifiedModulesAwaitingReification[env].insert(actualModulesModified[env].begin(), actualModulesModified[env].end());
1431 actualModulesAdded[env].clear();
1432 actualModulesModified[env].clear();
1436 map<VuoCompilerEnvironment *, set<VuoCompilerModule *>> postponedModulesAdded;
1437 map<VuoCompilerEnvironment *, set<pair<VuoCompilerModule *, VuoCompilerModule *>>> postponedModulesModified;
1441 auto lookUpType = [
this] (
const string &moduleKey) ->
VuoCompilerType *
1443 for (
auto i = environments.rbegin(); i != environments.rend(); ++i)
1458 bool allReified =
true;
1462 allReified = reifyPortTypes(nodeClass, lookUpType);
1467 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1472 if (! reifyPortTypesForModule(module))
1473 postponedModulesAdded[env].insert(module);
1475 for (pair<VuoCompilerModule *, VuoCompilerModule *> i : modifiedModulesAwaitingReification[env])
1476 if (! reifyPortTypesForModule(i.second))
1477 postponedModulesModified[env].insert(i);
1486 for (
auto i = environments.rbegin(); i != environments.rend(); ++i)
1497 auto fillInModuleReferences = [lookUpGenericNodeClass, lookUpType] (
VuoCompilerModule *module)
1499 bool allFilledIn =
true;
1502 if (specializedNodeClass)
1507 if (makeListNodeClass)
1508 allFilledIn = allFilledIn && makeListNodeClass->
updateListType(lookUpType);
1514 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1519 if (! fillInModuleReferences(module))
1520 postponedModulesAdded[env].insert(module);
1522 for (pair<VuoCompilerModule *, VuoCompilerModule *> i : modifiedModulesAwaitingReification[env])
1523 if (! fillInModuleReferences(i.second))
1524 postponedModulesModified[env].insert(i);
1529 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1533 std::set_difference(addedModulesAwaitingReification[env].begin(), addedModulesAwaitingReification[env].end(),
1534 postponedModulesAdded[env].begin(), postponedModulesAdded[env].end(),
1535 std::inserter(actualModulesAdded[env], actualModulesAdded[env].end()));
1536 std::set_difference(modifiedModulesAwaitingReification[env].begin(), modifiedModulesAwaitingReification[env].end(),
1537 postponedModulesModified[env].begin(), postponedModulesModified[env].end(),
1538 std::inserter(actualModulesModified[env], actualModulesModified[env].end()));
1539 addedModulesAwaitingReification[env] = postponedModulesAdded[env];
1540 modifiedModulesAwaitingReification[env] = postponedModulesModified[env];
1546 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1548 env->notifyCompilers(actualModulesAdded[env], actualModulesModified[env], actualModulesRemoved[env], issues[env]);
1555 VUserLog(
"Removed from %s environment: %s", env->
getName().c_str(),
module->getPseudoBase()->getModuleKey().c_str());
1558 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1562 for (pair<VuoCompilerModule *, VuoCompilerModule *> i : actualModulesModified[env])
1563 logModuleUnloaded(env, i.second);
1566 logModuleUnloaded(env, module);
1575 if (module->getPseudoBase()->getNodeSet())
1576 path = module->getPseudoBase()->getNodeSet()->getArchivePath();
1580 if (cnc && !cnc->getSourcePath().empty())
1583 if (!cnc->getSourceCode().empty())
1588 path =
module->getModulePath();
1591 if (hash.empty() && ! path.empty())
1600 if (hash.empty() && module->getModule())
1603 raw_string_ostream out(bitcode);
1604 llvm::WriteBitcodeToFile(module->getModule(), out);
1609 path =
module->getPseudoBase()->getModuleKey();
1612 VDebugLog(
"Loaded into %s environment: %s (%s)", env->
getName().c_str(), module->getPseudoBase()->getModuleKey().c_str(), path.c_str());
1614 VUserLog(
"Loaded into %s environment: [%8.8s] %s (%s)", env->
getName().c_str(), hash.c_str(), module->getPseudoBase()->getModuleKey().c_str(), path.c_str());
1618 for (
const vector<VuoCompilerEnvironment *> environmentsAtScope : environments)
1623 logModuleLoaded(env, module);
1625 for (pair<VuoCompilerModule *, VuoCompilerModule *> i : actualModulesModified[env])
1626 logModuleLoaded(env, i.second);
1633 if (currentEnvironment == generatedEnvironment)
1638 for (
const string &dependency : module->getDependencies())
1644 if (installedVertex)
1645 generatedDependencyGraph->removeEdge(generatedVertex, toVertex);
1651 for (
const vector<VuoCompilerEnvironment *> &environmentsAtScope : environments)
1653 if (environmentsAtScope.at(1) == currentEnvironment)
1655 installedDependencyGraph = environmentsAtScope.at(0)->getDependencyGraph();
1663 removeCyclesForDependencies(installedDependencyGraph, generatedDependencyGraph, m);
1664 for (pair<VuoCompilerModule *, VuoCompilerModule *> i : actualModulesModified[currentEnvironment])
1665 removeCyclesForDependencies(installedDependencyGraph, generatedDependencyGraph, i.first);
1672 for (
const dispatch_group_t &group : sourcesLoading)
1673 dispatch_retain(group);
1675 set<dispatch_group_t> loadingGroups;
1676 loadingGroups.insert(specializedModulesLoading.begin(), specializedModulesLoading.end());
1677 loadingGroups.insert(sourcesLoading.begin(), sourcesLoading.end());
1678 return loadingGroups;
1693void VuoCompiler::findDependentModulesAndSources(map<
VuoCompilerEnvironment *, set<string> > &changedModules,
1694 const vector<VuoDirectedAcyclicNetwork *> &searchDependencyGraphs,
1701 for (
const vector<VuoCompilerEnvironment *> &environmentsAtScope : environments)
1705 for (
const string &module : changedModules[env])
1709 set<VuoDirectedAcyclicGraph::Vertex *> dependents;
1712 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices;
1713 if (currentEnvironmentDependencyGraph)
1719 moduleVertices.push_back(mv);
1722 moduleVertices = searchDependencyGraph->findVertex(module);
1729 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = includeIndirectDependents ?
1730 searchDependencyGraph->getUpstreamVertices(moduleVertex) :
1731 searchDependencyGraph->getImmediatelyUpstreamVertices(moduleVertex);
1732 dependents.insert(upstream.begin(), upstream.end());
1737 set< pair<VuoCompilerEnvironment *, string> > dependentsMap;
1747 dependentsMap.insert({dependentEnv, dependent});
1759 set<string> dependencies = potentialDependentModule->getDependencies();
1760 if (dependencies.find(module) != dependencies.end())
1761 dependentsMap.insert({env, potentialDependentModule->getPseudoBase()->getModuleKey()});
1765 addDependentIfNeeded(generatedEnvironmentAtScope, i.second);
1766 for (
auto i : generatedEnvironmentAtScope->
getTypes())
1767 addDependentIfNeeded(generatedEnvironmentAtScope, i.second);
1769 addDependentIfNeeded(generatedEnvironmentAtScope, i.second);
1774 for (
auto i : dependentsMap)
1777 string dependent = i.second;
1781 if (changedModules[dependentEnv].find(dependent) != changedModules[dependentEnv].end())
1787 bool belongsToCurrentCompiler =
false;
1788 for (
const vector<VuoCompilerEnvironment *> &envs2 : environments)
1790 if (find(envs2.begin(), envs2.end(), dependentEnv) != envs2.end())
1792 belongsToCurrentCompiler =
true;
1797 auto distributeToList = [dependentEnv, dependent] (map<VuoCompilerEnvironment *, set<string>> *dependentsList,
VuoModuleInfo *moduleInfo)
1799 (*dependentsList)[dependentEnv].insert(dependent);
1804 if (foundSourceInfo)
1805 distributeToList(belongsToCurrentCompiler ? &sourcesDepOnChangedModules_this : &sourcesDepOnChangedModules_other, foundSourceInfo);
1807 if (foundModuleInfo)
1808 distributeToList(belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other, foundModuleInfo);
1810 if (! foundSourceInfo && ! foundModuleInfo)
1811 distributeToList(belongsToCurrentCompiler ? &modulesDepOnChangedModules_this : &modulesDepOnChangedModules_other, nullptr);
1821void VuoCompiler::loadedModules(map<string, VuoCompilerModule *> modulesAdded,
1822 map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified,
1823 map<string, VuoCompilerModule *> modulesRemoved,
1836 auto findVersionsOfModule = [
this, currentEnvironment] (
const string &moduleKey)
1838 vector< pair<VuoCompilerEnvironment *, VuoCompilerModule *> > moduleVersions;
1839 for (
const vector<VuoCompilerEnvironment *> &envs : environments)
1843 if (module || env == currentEnvironment)
1844 moduleVersions.push_back( make_pair(env, module) );
1846 return moduleVersions;
1849 for (map<string, VuoCompilerModule *>::iterator i = modulesAdded.begin(); i != modulesAdded.end(); )
1851 string moduleKey = i->first;
1854 vector< pair<VuoCompilerEnvironment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
1856 if (moduleVersions.size() > 1)
1858 modulesAdded.erase(i++);
1860 if (moduleVersions.back().second == moduleAdded)
1862 VuoCompilerModule *moduleSuperseded = moduleVersions.at(moduleVersions.size()-2).second;
1863 modulesModified[moduleKey] = make_pair(moduleSuperseded, moduleAdded);
1870 for (map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> >::iterator i = modulesModified.begin(); i != modulesModified.end(); )
1872 string moduleKey = i->first;
1875 vector< pair<VuoCompilerEnvironment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
1877 if (moduleVersions.size() > 1 && moduleVersions.back().second != moduleModified)
1878 modulesModified.erase(i++);
1883 for (map<string, VuoCompilerModule *>::iterator i = modulesRemoved.begin(); i != modulesRemoved.end(); )
1885 string moduleKey = i->first;
1888 vector< pair<VuoCompilerEnvironment *, VuoCompilerModule *> > moduleVersions = findVersionsOfModule(moduleKey);
1890 if (moduleVersions.size() > 1)
1892 modulesRemoved.erase(i++);
1894 if (moduleVersions.back().first == currentEnvironment)
1896 VuoCompilerModule *moduleUnsuperseded = moduleVersions.at(moduleVersions.size()-2).second;
1897 modulesModified[moduleKey] = make_pair(moduleRemoved, moduleUnsuperseded);
1911 dispatch_async(delegateQueue, ^{
1912 VuoCompilerDelegate::LoadedModulesData *delegateData =
static_cast<VuoCompilerDelegate::LoadedModulesData *
>(delegateDataV);
1914 if (delegate && ! (modulesAdded.empty() && modulesModified.empty() && modulesRemoved.empty() && issues->
isEmpty()))
1916 delegate->enqueueData(delegateData);
1917 delegate->
loadedModules(modulesAdded, modulesModified, modulesRemoved, issues);
1921 delegateData->release();
1935 bool missingTypes =
false;
1937 auto setPortTypesForNodeClass = [lookUpType, &missingTypes] (
const vector<VuoPortClass *> portClasses)
1961 missingTypes =
true;
1969 VuoType *type = trigger->getDataType();
1976 trigger->setDataType(reifiedType->
getBase());
1979 if (trigger->getDataType() && ! trigger->getDataType()->hasCompiler())
1980 missingTypes =
true;
1983 return ! missingTypes;
1991 for (
VuoCompilerNode *node : composition->getCachedGraph(this)->getNodes())
1992 reifyGenericPortTypes(node->getBase());
2000void VuoCompiler::reifyGenericPortTypes(
VuoNode *node)
2010 vector<VuoPort *> ports;
2011 ports.insert(ports.end(), inputPorts.begin(), inputPorts.end());
2012 ports.insert(ports.end(), outputPorts.begin(), outputPorts.end());
2014 for (vector<VuoPort *>::iterator j = ports.begin(); j != ports.end(); ++j)
2043 const map<string, string> &typeNameReplacements)
2047 settings.
target = target;
2056 dispatch_sync(environmentQueue, ^{
2057 environments[0][0]->addModuleSearchPath(VUO_BUILD_DIR
"/lib/Vuo.framework/Modules",
false);
2064 vector<string> headerSearchPaths;
2068 headerSearchPaths.insert(headerSearchPaths.end(), envHeaderSearchPaths.begin(), envHeaderSearchPaths.end());
2074 auto getVuoType = [
this] (
const string &moduleKey) {
return this->
getType(moduleKey); };
2077 for (
string type : {
"c",
"isf"})
2084 return moduleCompiler;
2096 const map<string, string> &typeNameReplacements)
2104 if (! moduleCompiler)
2110 if (! overriddenSourceCode.empty())
2116 if (! results.module)
2123 delete moduleCompiler;
2138 Module *
module = results.module;
2151 verifyModule(module, issues);
2152 writeModuleToBitcode(module, target, outputPath, issues);
2154 if (! dependencyOutputPath.empty())
2156 shared_ptr<VuoMakeDependencies> makeDependencies = results.
makeDependencies;
2157 if (makeDependencies)
2158 makeDependencies->setCompiledFilePath(outputPath);
2162 makeDependencies->writeToFile(dependencyOutputPath);
2169 issues->append(issue);
2176 if (issues->hasErrors())
2183 string dir, file, ext;
2202 if (! moduleCompiler)
2217 delete moduleCompiler;
2225Module * VuoCompiler::compileCompositionToModule(
VuoCompilerComposition *composition,
const string &moduleKey,
bool isTopLevelComposition,
2228 composition->
check(issues);
2230 reifyGenericPortTypes(composition);
2233 isTopLevelComposition,
2236 __block Module *
module = nullptr;
2240 module = generator->generateBitcode();
2241 setTargetForModule(module, target);
2270 bool ownsIssues =
false;
2278 Module *
module = compileCompositionToModule(composition, moduleKey, isTopLevelComposition, issues);
2285 verifyModule(module, issues);
2286 writeModuleToBitcode(module, target, outputPath, issues);
2313 VUserLog(
"Compiling '%s' (%s)…", inputPath.c_str(), target.c_str());
2323 "",
"The composition file couldn't be read or was empty.");
2362 delete baseComposition;
2382 vector<string> rPaths = ! rPath.empty() ? vector<string>(1, rPath) : getRunPathSearchPaths(environments.back().front());
2383 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
false, rPaths, shouldAdHocCodeSign);
2405 vector<string> rPaths = getRunPathSearchPaths(environments.back().front());
2406 linkCompositionToCreateExecutableOrDynamicLibrary(inputPath, outputPath, optimization,
true, rPaths, shouldAdHocCodeSign);
2423void VuoCompiler::linkCompositionToCreateExecutableOrDynamicLibrary(
string compiledCompositionPath,
string linkedCompositionPath,
2424 Optimization optimization,
bool isDylib,
const vector<string> &rPaths,
2425 bool shouldAdHocCodeSign)
2431 shouldLoadAllModules =
false;
2433 vector<shared_ptr<VuoModuleCacheRevision>> currentModuleCaches = useCurrentModuleCaches(optimization);
2435 set<string> dependencies = getDependenciesForComposition(compiledCompositionPath);
2438 linkerInputs.
addDependencies(dependencies, currentModuleCaches,
this);
2444 link(linkedCompositionPath, linkerInputs, isDylib, rPaths, shouldAdHocCodeSign);
2446 for (shared_ptr<VuoModuleCacheRevision> revision : currentModuleCaches)
2472 bool shouldAdHocCodeSign =
false;
2474 shouldAdHocCodeSign =
true;
2480 set<string> allDependencies = getDependenciesForComposition(compiledCompositionPath);
2481 set<string> addedDependencies;
2482 std::set_difference(allDependencies.begin(), allDependencies.end(),
2483 carriedOverDependencies.begin(), carriedOverDependencies.end(),
2484 std::inserter(addedDependencies, addedDependencies.end()));
2490 set<string> carriedOverExternalLibraries = runningCompositionLibraries->
getExternalLibraries();
2500 vector<string> defunctModuleCaches;
2501 set<string> dependenciesInDefunctModuleCaches;
2502 set<string> dependenciesInDefunctResources;
2506 for (
auto i : defunctModuleCachesAndDependencies)
2508 defunctModuleCaches.push_back(i.first);
2509 dependenciesInDefunctModuleCaches.insert(i.second.begin(), i.second.end());
2513 for (
string carriedOverCachePath : carriedOverModuleCaches)
2515 auto sameAsCarriedOverCachePath = [&carriedOverCachePath] (shared_ptr<VuoModuleCacheRevision> revision)
2517 return revision->getDylibPath() == carriedOverCachePath;
2520 auto foundIter = std::find_if(currentModuleCaches.begin(), currentModuleCaches.end(), sameAsCarriedOverCachePath);
2521 if (foundIter == currentModuleCaches.end())
2523 defunctModuleCaches.push_back(carriedOverCachePath);
2526 dependenciesInDefunctModuleCaches.insert(dependenciesInCache.begin(), dependenciesInCache.end());
2530 if (! defunctModuleCaches.empty())
2534 std::sort(carriedOverModuleCaches.begin(), carriedOverModuleCaches.end());
2535 std::sort(defunctModuleCaches.begin(), defunctModuleCaches.end());
2537 carriedOverUnloadableLibraries.clear();
2538 std::set_difference(carriedOverModuleCaches.begin(), carriedOverModuleCaches.end(),
2539 defunctModuleCaches.begin(), defunctModuleCaches.end(),
2540 std::back_inserter(carriedOverUnloadableLibraries));
2549 string nonUnloadableResourcePath;
2550 string unloadableResourcePath;
2552 if (! addedDependencies.empty() || ! dependenciesInDefunctModuleCaches.empty() || ! dependenciesInDefunctResources.empty())
2556 linkerInputsForAddedDependencies.
addDependencies(addedDependencies, currentModuleCaches,
this);
2557 linkerInputsForAddedDependencies.
addDependencies(dependenciesInDefunctModuleCaches, currentModuleCaches,
this);
2558 linkerInputsForAddedDependencies.
addDependencies(dependenciesInDefunctResources, currentModuleCaches,
this);
2560 string dir, linkedCompositionFile, ext;
2567 if (wereBuiltInModulesAdded || wereBuiltInLibrariesAdded)
2576 linkerInputsForNonUnloadableResource.
addExternalLibraries( carriedOverNonUnloadableLibraries );
2578 linkerInputsForNonUnloadableResource.
addFrameworks( carriedOverFrameworks );
2580 vector<string> rPaths = getRunPathSearchPaths(environments.front().front());
2582 link(nonUnloadableResourcePath, linkerInputsForNonUnloadableResource,
true, rPaths, shouldAdHocCodeSign);
2589 if (wereNonBuiltInModulesAdded || wereNonBuiltInLibrariesAdded)
2601 linkerInputsForUnloadableResource.
addFrameworks( carriedOverFrameworks );
2603 if (! nonUnloadableResourcePath.empty())
2613 vector<string> rPaths = getRunPathSearchPaths(environments.back().front());
2615 link(unloadableResourcePath, linkerInputsForUnloadableResource,
true, rPaths, shouldAdHocCodeSign);
2635 linkerInputsForComposition.
addFrameworks( carriedOverFrameworks );
2637 if (! nonUnloadableResourcePath.empty())
2644 if (! unloadableResourcePath.empty())
2652 vector<string> rPaths = getRunPathSearchPaths(environments.front().front());
2653 link(linkedCompositionPath, linkerInputsForComposition,
true, rPaths, shouldAdHocCodeSign);
2658 if (! nonUnloadableResourcePath.empty())
2664 if (! unloadableResourcePath.empty())
2672 shared_ptr<VuoModuleCacheRevision> revision = i.first;
2674 runningCompositionLibraries->
enqueueCacheLibraryToLoad(revision->getDylibPath(), i.second,
false, [revision](void){ revision->disuse(); });
2679 shared_ptr<VuoModuleCacheRevision> revision = i.first;
2681 runningCompositionLibraries->
enqueueCacheLibraryToLoad(revision->getDylibPath(), i.second,
true, [revision](void){ revision->disuse(); });
2687 for (shared_ptr<VuoModuleCacheRevision> revision : currentModuleCaches)
2697set<string> VuoCompiler::getDependenciesForComposition(
const string &compiledCompositionPath)
2702 __block set<string> directDependencies;
2704 Module *
module = readModuleFromBitcode(compiledCompositionPath, getTargetArch(target));
2708 delete compilerModule;
2714 auto deps = getDependenciesForComposition(directDependencies,
true);
2715 VUserLog(
"Gathering dependencies for '%s' took %5.2fs", compiledCompositionPath.c_str(),
VuoLogGetTime() - t0);
2733 set<string> directDependencies;
2742 vector<VuoPublishedPort *> publishedPorts;
2743 publishedPorts.insert(publishedPorts.end(), publishedInputPorts.begin(), publishedInputPorts.end());
2744 publishedPorts.insert(publishedPorts.end(), publishedOutputPorts.begin(), publishedOutputPorts.end());
2747 if (publishedPort->getClass()->hasCompiler())
2763 directDependencies.insert(dependency);
2768 return directDependencies;
2780 return getDependenciesForComposition(directDependencies,
false);
2790 vector<string> librarySearchPaths;
2794 librarySearchPaths.insert(librarySearchPaths.end(), envLibrarySearchPaths.begin(), envLibrarySearchPaths.end());
2797 set<string> dylibDeps;
2798 for (
string dep : getDependenciesForComposition(composition))
2800 string path = getLibraryPath(dep, librarySearchPaths);
2802 dylibDeps.insert(path);
2821set<string> VuoCompiler::getDependenciesForComposition(
const set<string> &directDependencies,
bool checkCompatibility)
2825 for (set<string>::const_iterator i = directDependencies.begin(); i != directDependencies.end(); ++i)
2828 set<string> dependencies;
2829 vector<string> dependenciesToVisit(directDependencies.begin(), directDependencies.end());
2831 while (! dependenciesToVisit.empty())
2833 string moduleKey = dependenciesToVisit.back();
2834 dependenciesToVisit.pop_back();
2836 set<pair<string, VuoCompilerEnvironment *>> currentDependencies;
2840 vector<VuoDirectedAcyclicGraph::Vertex *> firstPassVertices = dependencyGraph->
findVertex(moduleKey);
2841 set<VuoDirectedAcyclicGraph::Vertex *> firstPassDependencies(firstPassVertices.begin(), firstPassVertices.end());
2842 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassVertices.begin(); j != firstPassVertices.end(); ++j)
2845 firstPassDependencies.insert(downstream.begin(), downstream.end());
2850 for (set<VuoDirectedAcyclicGraph::Vertex *>::iterator j = firstPassDependencies.begin(); j != firstPassDependencies.end(); ++j)
2859 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
2863 currentDependencies.insert({moduleKey, moduleVertex->
getEnvironment()});
2876 set<string> extraDependencies;
2877 for (
auto i : currentDependencies)
2884 extraDependencies.insert(dependenciesOfDependency.begin(), dependenciesOfDependency.end());
2888 vector<string> notYetAdded;
2889 std::set_difference(extraDependencies.begin(), extraDependencies.end(),
2890 dependencies.begin(), dependencies.end(),
2891 std::back_inserter(notYetAdded));
2893 vector<string> notYetAddedOrEnqueued;
2894 std::set_difference(notYetAdded.begin(), notYetAdded.end(),
2895 dependenciesToVisit.begin(), dependenciesToVisit.end(),
2896 std::back_inserter(notYetAddedOrEnqueued));
2898 dependenciesToVisit.insert(dependenciesToVisit.end(), notYetAddedOrEnqueued.begin(), notYetAddedOrEnqueued.end());
2900 for (
auto i : currentDependencies)
2901 dependencies.insert(i.first);
2906 if (checkCompatibility)
2908 string targetForCompatibility = ! requestedTarget.empty() ? requestedTarget : getProcessTarget();
2915 set<VuoCompilerNodeClass *> nodeClassesReported;
2917 for (
string moduleKey : dependencies)
2920 if (module && ! module->getCompatibleTargets().isCompatibleWith(neededCompatibility))
2922 vector<VuoCompilerNodeClass *> incompatibleNodeClasses;
2925 if (moduleAsNodeClass)
2926 incompatibleNodeClasses.push_back(moduleAsNodeClass);
2929 vector<VuoDirectedAcyclicGraph::Vertex *> moduleVertices = dependencyGraph->
findVertex(moduleKey);
2932 vector<VuoDirectedAcyclicGraph::Vertex *> upstream = dependencyGraph->
getUpstreamVertices(v);
2934 vector<string> upstreamModuleKeys;
2935 std::transform(upstream.begin(), upstream.end(),
2936 std::back_inserter(upstreamModuleKeys),
2939 vector<string> potentialNodeClassNames;
2940 std::set_intersection(directDependencies.begin(), directDependencies.end(),
2941 upstreamModuleKeys.begin(), upstreamModuleKeys.end(),
2942 std::back_inserter(potentialNodeClassNames));
2944 for (
string nodeClassName : potentialNodeClassNames)
2947 if (upstreamNodeClass)
2948 incompatibleNodeClasses.push_back(upstreamNodeClass);
2953 if (incompatibleNodeClasses.empty())
2956 "Dependencies incompatible with system",
2957 "%module is only compatible with " + module->getCompatibleTargets().toString() +
2958 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
2959 issue.setModule(module->getPseudoBase());
2966 if (nodeClassesReported.find(nodeClass) != nodeClassesReported.end())
2969 nodeClassesReported.insert(nodeClass);
2972 "Nodes incompatible with system",
2973 "%module is only compatible with " + module->getCompatibleTargets().toString() +
2974 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
2985 "Dependencies incompatible with system",
2986 "Some dependencies of this composition are only compatible with " + actualCompatibility.
toString() +
2987 ", so this composition can't run on " + neededCompatibility.
toString() +
".");
2997 vector<string> coreDependencies = getCoreVuoDependencies();
2998 dependencies.insert(coreDependencies.begin(), coreDependencies.end());
3000 return dependencies;
3010 for (
string dependency : dependencies)
3014 compatibility = compatibility.
intersection(module->getCompatibleTargets());
3017 return compatibility;
3025string VuoCompiler::getLibraryPath(
const string &dependency, vector<string> librarySearchPaths)
3032 if (dependency !=
"crypto"
3033 && dependency !=
"ssl")
3034 librarySearchPaths.push_back(
"/usr/lib");
3036 for (
auto &path : librarySearchPaths)
3038 vector<string> variations;
3039 variations.push_back(path +
"/" + dependency);
3040 variations.push_back(path +
"/lib" + dependency);
3041 variations.push_back(path +
"/lib" + dependency +
".dylib");
3042 variations.push_back(path +
"/lib" + dependency +
".a");
3043 for (
auto &variation : variations)
3062void VuoCompiler::makeModuleCachesAvailable(
bool shouldUseExistingBuiltInCaches,
bool shouldUseExistingOtherCaches,
const string &target)
3064 loadModulesIfNeeded();
3065 dispatch_group_wait(modulesLoading, DISPATCH_TIME_FOREVER);
3067 dispatch_sync(environmentQueue, ^{
3069 set<string> accumulatedDylibs;
3070 set<string> accumulatedFrameworks;
3071 vector<shared_ptr<VuoModuleCache>> accumulatedModuleCaches;
3072 double lastPrerequisiteModuleCacheRebuild = 0;
3074 for (
const vector<VuoCompilerEnvironment *> &environmentsAtScope : environments)
3076 shared_ptr<VuoModuleCache> moduleCache = environmentsAtScope.at(0)->getModuleCache();
3081 vector<VuoModuleInfoIterator> expectedModules;
3085 set<string> dylibsNeededToLinkToCache;
3086 set<string> frameworksNeededToLinkToCache;
3090 accumulatedDylibs.insert(dylibsNeededToLinkToCache.begin(), dylibsNeededToLinkToCache.end());
3091 accumulatedFrameworks.insert(frameworksNeededToLinkToCache.begin(), frameworksNeededToLinkToCache.end());
3096 vector<string> runPathSearchPaths = getRunPathSearchPaths(environmentsAtScope.at(0));
3098 bool shouldUseExistingCache = (environmentsAtScope.at(0)->isBuiltIn() ? shouldUseExistingBuiltInCaches : shouldUseExistingOtherCaches);
3100 moduleCache->makeAvailable(shouldUseExistingCache, accumulatedModuleCaches, lastPrerequisiteModuleCacheRebuild,
3101 expectedManifest, expectedModules, accumulatedDylibs, accumulatedFrameworks, runPathSearchPaths,
3104 accumulatedModuleCaches.push_back(moduleCache);
3115vector<shared_ptr<VuoModuleCacheRevision>> VuoCompiler::useCurrentModuleCaches(Optimization optimization)
3117 vector<shared_ptr<VuoModuleCacheRevision>> revisions;
3128 shared_ptr<VuoModuleCacheRevision> revision = moduleCache->useCurrentRevision();
3130 revisions.push_back(revision);
3145 dispatch_group_async(moduleCacheBuilding, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3146 makeModuleCachesAvailable(
true,
false);
3167 vuoFrameworkInProgressPath = vuoFrameworkPath;
3172 if (! cachePath.empty())
3176 compiler.generatedEnvironment = compiler.environments.at(0).at(1);
3178 if (onlyGenerateModules)
3180 compiler.loadModulesIfNeeded();
3181 dispatch_group_wait(compiler.moduleSourceCompilersExist, DISPATCH_TIME_FOREVER);
3185 compiler.makeModuleCachesAvailable(
false,
true, target);
3213 dispatch_sync(modulesToLoadQueue, ^{
3214 this->shouldLoadAllModules = shouldLoadAllModules;
3228void VuoCompiler::link(
string outputPath,
const VuoLinkerInputs &linkerInputs,
3229 bool isDylib,
const vector<string> &rPaths,
bool shouldAdHocCodeSign,
VuoCompilerIssues *issues)
3234 bool ownsIssues =
false;
3246 unique_ptr<Module> compositeModule(
new Module(
"composite", *
globalLLVMContext));
3247 Linker linker(*compositeModule);
3248 setTargetForModule(compositeModule.get(), target);
3250 for (
auto i : linkerInputs.getModules())
3252 unique_ptr<Module> upi = llvm::CloneModule(i);
3253 if (linker.linkInModule(std::move(upi)))
3256 "",
"Failed to link in the module with ID '" + i->getModuleIdentifier() +
"'");
3263 verifyModule(compositeModule.get(), issues);
3264 writeModuleToBitcode(compositeModule.get(), target, compositeModulePath, issues);
3269 if (linkModulesTime > 0.1)
3270 VUserLog(
"\tLinkModules took %5.2fs", linkModulesTime);
3277 string clangPath(getClangPath() +
"++");
3279 vector<const char *> args;
3280 vector<char *> argsToFree;
3281 args.push_back(clangPath.c_str());
3284 char *outputPathZ = strdup((
"-o" + outputPath).c_str());
3285 args.push_back(outputPathZ);
3286 argsToFree.push_back(outputPathZ);
3289 args.push_back(compositeModulePath.c_str());
3291 vector<string> coreDependencies = getCoreVuoDependencies();
3292 for (
string library : linkerInputs.getLibraries())
3294 for (vector<string>::iterator j = coreDependencies.begin(); j != coreDependencies.end(); ++j)
3296 string coreDependency = *j;
3298 args.push_back(
"-force_load");
3306 library = libraryObject;
3309 char *libraryZ = strdup(library.c_str());
3310 args.push_back(libraryZ);
3311 argsToFree.push_back(libraryZ);
3315 vector<string> frameworkArguments;
3317 vector<string> frameworkSearchPaths;
3321 frameworkSearchPaths.insert(frameworkSearchPaths.end(), envFrameworkSearchPaths.begin(), envFrameworkSearchPaths.end());
3324 for (vector<string>::const_iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
3328 frameworkArguments.push_back(a);
3329 char *frameworkArgument = strdup(a.c_str());
3330 args.push_back(frameworkArgument);
3331 argsToFree.push_back(frameworkArgument);
3334 for (
const string &framework : linkerInputs.getFrameworks())
3336 args.push_back(
"-framework");
3338 string frameworkName = framework.substr(0, framework.length() -
string(
".framework").length());
3339 char *frameworkNameZ = strdup(frameworkName.c_str());
3340 args.push_back(frameworkNameZ);
3341 argsToFree.push_back(frameworkNameZ);
3347 string frameworkMacOSSDKFolder = vuoFrameworkPath +
"/SDKs/MacOSX.sdk";
3351 args.push_back(
"-Xlinker");
3352 args.push_back(
"-syslibroot");
3353 args.push_back(
"-Xlinker");
3354 char *frameworkMacOSSDKFolderZ = strdup(frameworkMacOSSDKFolder.c_str());
3355 args.push_back(frameworkMacOSSDKFolderZ);
3356 argsToFree.push_back(frameworkMacOSSDKFolderZ);
3358 args.push_back(
"-Xlinker");
3359 args.push_back(
"-platform_version");
3360 args.push_back(
"-Xlinker");
3361 args.push_back(
"macos");
3362 args.push_back(
"-Xlinker");
3363 char *deploymentTargetZ = strdup(MACOS_DEPLOYMENT_TARGET);
3364 args.push_back(deploymentTargetZ);
3365 argsToFree.push_back(deploymentTargetZ);
3366 args.push_back(
"-Xlinker");
3367 char *sdkVersionZ = strdup(MACOS_SDK_VERSION);
3368 args.push_back(sdkVersionZ);
3369 argsToFree.push_back(sdkVersionZ);
3372 args.push_back(
"-Xlinker");
3373 args.push_back(
"--no-demangle");
3376 args.push_back(
"-v");
3379 args.push_back(
"-dynamiclib");
3381 args.push_back(
"-Xlinker");
3382 args.push_back(
"-headerpad_max_install_names");
3385 for (
const string &rPath : rPaths)
3387 args.push_back(
"-rpath");
3388 args.push_back(rPath.c_str());
3392 args.push_back(
"-rpath");
3393 args.push_back(LLVM_ROOT
"/lib");
3396 args.push_back(
"-target");
3397 args.push_back(target.c_str());
3399 args.push_back(
"-std=c++14");
3400 args.push_back(
"-stdlib=libc++");
3401 args.push_back(
"-mmacosx-version-min=10.10");
3404 shared_ptr<VuoClangIssues> clangIssues = std::make_shared<VuoClangIssues>();
3406 clang::DiagnosticOptions *diagOptions =
new clang::DiagnosticOptions();
3407 IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
3408 clang::DiagnosticsEngine Diags(DiagID, diagOptions, diagnosticConsumer);
3413 for (vector<const char *>::iterator i = args.begin(); i != args.end(); ++i)
3420 const StringRef stdoutPath(stdoutFile);
3421 const StringRef *redirects[] = {
3428 const char **argsz = (
const char **)malloc(
sizeof(
char *) * args.size() + 1);
3429 for (
int i = 0; i < args.size(); ++i)
3431 argsz[args.size()] =
nullptr;
3434 bool executionFailed;
3436 int ret = llvm::sys::ExecuteAndWait(args[0], argsz,
nullptr, redirects, 0, 0, &errMsg, &executionFailed);
3438 for (
auto i : argsToFree)
3442 remove(compositeModulePath.c_str());
3448 chmod(outputPath.c_str(), 0755);
3450 if (! clangIssues->isEmpty())
3453 issue.setClangIssues(clangIssues);
3460 if (!errMsg.empty())
3463 details +=
"\n" + errMsg +
"\n";
3466 if (!stdoutFileContents.empty())
3468 VUserLog(
"%s", stdoutFileContents.c_str());
3469 details +=
"\n" + stdoutFileContents +
"\n";
3484 if (shouldAdHocCodeSign)
3485 adHocCodeSign(outputPath);
3491void VuoCompiler::adHocCodeSign(
string path)
3495 "CODESIGN_ALLOCATE=" + getCodesignAllocatePath(),
3505Module *VuoCompiler::readModuleFromBitcode(
string inputPath,
string arch)
3507 string dir, file, ext;
3510 return readModuleFromBitcode(&inputFile, arch);
3522 size_t inputDataBytes;
3526 set<string> availableArchs;
3528 Module *
module = readModuleFromBitcodeData(inputData, inputDataBytes, arch, availableArchs, error);
3531 VUserLog(
"Error: Couldn't parse module '%s' (%s): %s.", inputFile->
getRelativePath().c_str(), arch.c_str(), error.c_str());
3543Module *VuoCompiler::readModuleFromBitcodeData(
char *inputData,
size_t inputDataBytes,
string arch,
3544 set<string> &availableArchs,
string &error)
3546 if (inputDataBytes <
sizeof(
unsigned int))
3549 __block Module *
module = nullptr;
3551 StringRef inputDataAsStringRef(inputData, inputDataBytes);
3552 auto mb = MemoryBuffer::getMemBuffer(inputDataAsStringRef,
"",
false);
3555 error =
"Couldn't create MemoryBuffer";
3559 MemoryBufferRef bitcodeBuffer;
3561 unsigned int fileID = *(
unsigned int *)inputData;
3562 if (fileID == 0x0b17c0de)
3564 bitcodeBuffer = mb.get()->getMemBufferRef();
3566 else if (fileID == 0xdec04342)
3569 bitcodeBuffer = mb.get()->getMemBufferRef();
3570 moduleArch =
"x86_64";
3571 availableArchs.insert(moduleArch);
3574 else if (fileID == 0xbebafeca)
3578 error =
"It's a Mach-O universal binary, but this compiler instance's LLVM target isn't set";
3584 auto binary = llvm::object::MachOUniversalBinary::create(mb.get()->getMemBufferRef());
3587 error =
"Couldn't read Mach-O universal binary:";
3588 handleAllErrors(binary.takeError(), [&error](
const ErrorInfoBase &ei) {
3589 error +=
" " + ei.message();
3594 for (
auto &o : binary.get()->objects())
3596 if (o.getArchFlagName() == arch)
3597 bitcodeBuffer = MemoryBufferRef(mb.get()->getMemBufferRef().getBuffer().slice(o.getOffset(), o.getOffset() + o.getSize()),
"");
3599 availableArchs.insert(o.getArchFlagName());
3602 if (!bitcodeBuffer.getBufferSize())
3604 error =
"The Mach-O universal binary doesn't have an \"" + arch +
"\" slice";
3612 error =
"Couldn't parse bitcode file:";
3613 handleAllErrors(wrappedModule.takeError(), [&error](
const ErrorInfoBase &ei) {
3614 error +=
" " + ei.message();
3619 module = wrappedModule.get().release();
3621 if (moduleArch.empty())
3624 if (availableArchs.empty())
3625 availableArchs.insert(moduleArch);
3627 if (moduleArch != arch)
3629 error =
"The module's CPU architecture \"" + moduleArch +
"\" doesn't match the compiler's CPU architecture \"" + arch +
"\"";
3648 raw_string_ostream verifyOut(str);
3649 if (llvm::verifyModule(*module, &verifyOut))
3653 issue.setModuleKey(module->getModuleIdentifier());
3666void VuoCompiler::writeModuleToBitcode(Module *module,
string target,
string outputPath,
VuoCompilerIssues *issues)
3669 setTargetForModule(module, target);
3671 std::error_code err;
3672 raw_fd_ostream out(outputPath.c_str(), err, sys::fs::F_None);
3676 "Couldn't write to '" + outputPath +
"': " + err.message());
3677 issue.setModuleKey(module->getModuleIdentifier());
3681 llvm::WriteBitcodeToFile(module, out);
3690void VuoCompiler::setTargetForModule(Module *module,
string targetTriple)
3693 llvm::Triple triple(targetTriple);
3694 if (triple.isMacOSX())
3695 triple.setOSName(
"macosx10.10.0");
3697 module->setTargetTriple(triple.str());
3700 auto target = TargetRegistry::lookupTarget(module->getTargetTriple(), error);
3703 VUserLog(
"Error: Couldn't look up target: %s", error.c_str());
3707 auto targetMachine = target->createTargetMachine(module->getTargetTriple(),
"",
"", TargetOptions(), Optional<Reloc::Model>());
3710 VUserLog(
"Error: Couldn't create targetMachine.");
3714 module->setDataLayout(targetMachine->createDataLayout());
3716 delete targetMachine;
3725 auto hyphen = target.find(
'-');
3726 if (hyphen == string::npos)
3729 return target.substr(0, hyphen);
3735string VuoCompiler::getProcessTarget(
void)
3741 llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
3744 if (triple.isMacOSX())
3746 unsigned int major, minor, micro;
3747 if (triple.getMacOSXVersion(major, minor, micro))
3749 ostringstream osVersion;
3750 osVersion <<
"macosx" << major <<
"." << minor <<
"." << micro;
3751 triple.setOSName(osVersion.str());
3755 return triple.str();
3766 Module *llvmModule =
module->getModule();
3791 baseModule =
module->getPseudoBase();
3795 delete baseNodeClass;
3828 if (nodeClassForNode)
3829 return nodeClassForNode->
newNode(title, x, y);
3843 if (nodeClassForNode)
3844 return nodeClassForNode->
newNode(nodeToCopyMetadataFrom);
3855 return createPublishedNode(nodeClassName, publishedInputPorts);
3864 return createPublishedNode(nodeClassName, publishedOutputPorts);
3870VuoNode * VuoCompiler::createPublishedNode(
const string &nodeClassName,
const vector<VuoPublishedPort *> &publishedPorts)
3878 for (
size_t i = 0; i < publishedPorts.size(); ++i)
3880 VuoType *publishedPortType =
static_cast<VuoCompilerPort *
>(publishedPorts[i]->getCompiler())->getDataVuoType();
3884 set<VuoPort *> nodePorts;
3888 nodePorts.insert(inputPort);
3891 nodePorts.insert(outputPort);
3896 nodePorts.insert(inputPort);
3899 for (
VuoPort *port : nodePorts)
3906 reifyGenericPortTypes(node);
3917 dispatch_sync(environmentQueue, ^{
3918 if (environments.size() >= 5)
3919 environments.at(3).at(0)->addExpatriateSourceFile(sourcePath);
3929 dispatch_sync(environmentQueue, ^{
3930 if (environments.size() >= 5)
3932 environments.at(3).at(0)->removeExpatriateSourceFile(sourcePath);
3934 set<string> sourcesRemoved;
3935 sourcesRemoved.insert(getModuleKeyForPath(sourcePath));
3936 loadModulesAndSources(set<string>(), set<string>(), set<string>(), set<string>(), set<string>(), sourcesRemoved,
3937 false, false, environments.at(3).at(0), nullptr, nullptr,
"");
3960 string sourcePathCopy = sourcePath;
3961 string sourceCodeCopy = sourceCode;
3963 dispatch_async(environmentQueue, ^{
3967 for (
const vector<VuoCompilerEnvironment *> &envs : environments)
3974 sourceInfo = potentialSourceInfo;
3983 if (! sourceCodeCopy.empty())
3990 loadModulesAndSources({}, {}, {}, {}, { nodeClassName }, {},
false,
false, sourceInfo->
getEnvironment(),
nullptr,
nullptr,
"");
4003 loadModulesAndSources({}, { nodeClassName }, {}, {}, {}, {},
false,
false, sourceInfo->
getEnvironment(),
nullptr,
nullptr,
"");
4058 loadModulesIfNeeded();
4060 map<string, VuoCompilerNodeClass *> nodeClasses;
4063 map<string, VuoCompilerNodeClass *> envNodeClasses = env->
getNodeClasses();
4064 nodeClasses.insert(envNodeClasses.begin(), envNodeClasses.end());
4100 loadModulesIfNeeded();
4102 map<string, VuoCompilerType *> types;
4105 map<string, VuoCompilerType *> envTypes = env->
getTypes();
4106 types.insert(envTypes.begin(), envTypes.end());
4119 return loadModuleIfNeeded(libraryModuleName);
4129 loadModulesIfNeeded();
4131 map<string, VuoCompilerModule *> libraryModules;
4135 libraryModules.insert(envLibraryModules.begin(), envLibraryModules.end());
4138 return libraryModules;
4148 loadModulesIfNeeded();
4150 map<string, VuoNodeSet *> nodeSets;
4153 map<string, VuoNodeSet *> envNodeSets = env->
getNodeSets();
4154 nodeSets.insert(envNodeSets.begin(), envNodeSets.end());
4167 loadModulesIfNeeded();
4174 nodeSet = foundNodeSet;
4190 module = foundModule;
4209 map<string, VuoCompilerNodeClass *> nodeClasses =
getNodeClasses();
4210 for (map<string, VuoCompilerNodeClass *>::const_iterator i = nodeClasses.begin(); i != nodeClasses.end(); ++i)
4217 else if (format ==
"path")
4221 else if (format ==
"dot")
4245 vector<string> rPaths;
4246 for (
size_t i = 0; i < environments.size(); ++i)
4251 if (! vuoFrameworkPath.empty())
4252 rPaths.push_back(vuoFrameworkPath +
"/..");
4261 if (! localModulesPath.empty())
4262 rPaths.push_back(localModulesPath);
4265 if (std::find(environments[i].begin(), environments[i].end(), narrowestScope) != environments[i].end())
4269 std::reverse(rPaths.begin(), rPaths.end());
4279vector<string> VuoCompiler::getCoreVuoDependencies(
void)
4281 vector<string> dependencies;
4283 dependencies.push_back(
"VuoHeap");
4284 dependencies.push_back(
"VuoApp");
4286 dependencies.push_back(
"zmq");
4287 dependencies.push_back(
"json-c");
4288 dependencies.push_back(
"objc");
4289 dependencies.push_back(
"c");
4290 dependencies.push_back(
"AppKit.framework");
4293 dependencies.push_back(LLVM_ROOT
"/lib/libprofile_rt.dylib");
4295 return dependencies;
4301string VuoCompiler::getRuntimeMainDependency(
void)
4303 return "VuoRuntimeMain.o";
4313string VuoCompiler::getRuntimeDependency(
void)
4315 return "VuoRuntime.o";
4326 if (! vuoFrameworkInProgressPath.empty())
4327 return vuoFrameworkInProgressPath;
4335string VuoCompiler::getClangPath(
void)
4346 string dir, moduleKey, ext;
4354 while (nodeClassNameParts.size() > 1 && nodeClassNameParts.back() == ext)
4355 nodeClassNameParts.pop_back();
4358 for (
string &part : nodeClassNameParts)
4362 if (nodeClassNameParts.size() == 1)
4363 nodeClassNameParts.insert(nodeClassNameParts.begin(),
"isf");
4377 __block
bool isLocal =
false;
4379 dispatch_sync(environmentQueue, ^{
4380 if (environments.size() >= 5)
4381 isLocal = environments.at(3).at(0)->findModule(moduleKey);
4395 return lastCompositionBaseDir.empty() ?
"" : lastCompositionBaseDir +
"/Modules";
4410 return lastCompositionBaseDir;
4416void VuoCompiler::addModuleSearchPath(
string path)
4418 dispatch_sync(environmentQueue, ^{
4419 environments.back().at(0)->addModuleSearchPath(path);
4429 dispatch_sync(environmentQueue, ^{
4439 dispatch_sync(environmentQueue, ^{
4449 dispatch_sync(environmentQueue, ^{
4459 this->isVerbose = isVerbose;
4469 if (VuoPro::getProAccess())
4471 _shouldShowSplashWindow =
false;
4476 _shouldShowSplashWindow = potentiallyShow;
4485 dependencyOutputPath = path;
4493 return _shouldShowSplashWindow;
4499void VuoCompiler::setClangPath(
const string &clangPath)
4501 this->clangPath = clangPath;
4510 return (vuoFrameworkPath.empty() ?
4511 VUO_BUILD_DIR
"/bin/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader" :
4512 vuoFrameworkPath +
"/Helpers/VuoCompositionLoader.app/Contents/MacOS/VuoCompositionLoader");
4518string VuoCompiler::getCompositionStubPath(
void)
4521 return (vuoFrameworkPath.empty() ?
4522 VUO_BUILD_DIR
"/lib/libVuoCompositionStub.dylib" :
4523 vuoFrameworkPath +
"/Modules/libVuoCompositionStub.dylib");
4531 vector<string> moduleSearchPaths;
4535 moduleSearchPaths.insert(moduleSearchPaths.end(), envModuleSearchPaths.begin(), envModuleSearchPaths.end());
4538 vector<string> headerSearchPaths;
4542 headerSearchPaths.insert(headerSearchPaths.end(), envHeaderSearchPaths.begin(), envHeaderSearchPaths.end());
4545 vector<string> librarySearchPaths;
4549 librarySearchPaths.insert(librarySearchPaths.end(), envLibrarySearchPaths.begin(), envLibrarySearchPaths.end());
4552 vector<string> frameworkSearchPaths;
4556 frameworkSearchPaths.insert(frameworkSearchPaths.end(), envFrameworkSearchPaths.begin(), envFrameworkSearchPaths.end());
4559 fprintf(stderr,
"Module (node class, type, library) search paths:\n");
4560 for (vector<string>::iterator i = moduleSearchPaths.begin(); i != moduleSearchPaths.end(); ++i)
4561 fprintf(stderr,
" %s\n", (*i).c_str());
4562 fprintf(stderr,
"Header search paths:\n");
4563 for (vector<string>::iterator i = headerSearchPaths.begin(); i != headerSearchPaths.end(); ++i)
4564 fprintf(stderr,
" %s\n", (*i).c_str());
4565 fprintf(stderr,
"Other library search paths:\n");
4566 for (vector<string>::iterator i = librarySearchPaths.begin(); i != librarySearchPaths.end(); ++i)
4567 fprintf(stderr,
" %s\n", (*i).c_str());
4568 fprintf(stderr,
"Other framework search paths:\n");
4569 for (vector<string>::iterator i = frameworkSearchPaths.begin(); i != frameworkSearchPaths.end(); ++i)
4570 fprintf(stderr,
" %s\n", (*i).c_str());
4571 fprintf(stderr,
"Framework path:\n");
4574 fprintf(stderr,
"Clang path:\n");
4575 if (! getClangPath().empty())
4576 fprintf(stderr,
" %s\n", getClangPath().c_str());
4592 string directory, file, extension;
4596 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
4598 remove(compiledCompositionPath.c_str());
4600 typedef VuoRunner * (*runnerFunctionType)(
const char *,
const char *, bool, bool);
4601 runnerFunctionType runnerFunction = (runnerFunctionType)dlsym(RTLD_DEFAULT,
"VuoRunner_newSeparateProcessRunnerFromExecutable");
4602 return runnerFunction(linkedCompositionPath.c_str(), directory.c_str(),
false,
true);
4630 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/" + processName +
".vuo";
4636 remove(compiledCompositionPath.c_str());
4638 typedef VuoRunner * (*runnerFunctionType)(
const char *,
const char *, bool, bool);
4639 runnerFunctionType runnerFunction = (runnerFunctionType)dlsym(RTLD_DEFAULT,
"VuoRunner_newSeparateProcessRunnerFromExecutable");
4640 return runnerFunction(linkedCompositionPath.c_str(), workingDirectory.c_str(),
false,
true);
4663 string directory, file, extension;
4666 compiler.
compileComposition(compositionFilePath, compiledCompositionPath,
true, issues);
4669 remove(compiledCompositionPath.c_str());
4671 typedef VuoRunner * (*runnerFunctionType)(
const char *,
const char *, bool);
4672 runnerFunctionType runnerFunction = (runnerFunctionType)dlsym(RTLD_DEFAULT,
"VuoRunner_newCurrentProcessRunnerFromDynamicLibrary");
4673 return runnerFunction(linkedCompositionPath.c_str(), directory.c_str(),
true);
4701 string compositionPath = (workingDirectory.empty() ?
"." : workingDirectory) +
"/UntitledComposition.vuo";
4707 remove(compiledCompositionPath.c_str());
4709 typedef VuoRunner * (*runnerFunctionType)(
const char *,
const char *, bool);
4710 runnerFunctionType runnerFunction = (runnerFunctionType)dlsym(RTLD_DEFAULT,
"VuoRunner_newCurrentProcessRunnerFromDynamicLibrary");
4711 return runnerFunction(linkedCompositionPath.c_str(), workingDirectory.c_str(),
true);