Vuo  2.3.0
VuoCompiler.hh
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #include "VuoFileUtilities.hh"
13 #include "VuoFileWatcher.hh"
15 
19 class VuoCompilerIssues;
20 class VuoCompilerModule;
22 class VuoCompilerType;
24 class VuoNode;
25 class VuoNodeSet;
26 class VuoPublishedPort;
27 class VuoRunner;
29 
30 
68 {
69 public:
74  {
78  };
79 
80 private:
81  class Environment;
82 
86  class ModuleInfo
87  {
88  public:
89  ModuleInfo(Environment *environment, const string &searchPath, const string &relativePath, bool isSourceFile, bool isSubcomposition);
90  ModuleInfo(Environment *environment, const string &searchPath, VuoFileUtilities::File *file, bool isSourceFile, bool isSubcomposition);
91  ~ModuleInfo(void);
92  Environment * getEnvironment(void) const;
93  string getSearchPath(void) const;
94  string getModuleKey(void) const;
95  VuoFileUtilities::File * getFile(void) const;
96  string getSourceCode(void) const;
97  void setSourceCode(const string &sourceCode);
98  void revertSourceCode(void);
99  bool isSourceCodeOverridden(void) const;
100  void setSourceCodeOverridden(bool overridden);
101  bool isNewerThan(ModuleInfo *other) const;
102  bool isNewerThan(unsigned long seconds) const;
103  bool isOlderThan(unsigned long seconds) const;
104  void setLastModifiedToNow(void);
105  set<string> getContainedNodeClasses(void) const;
106  int getLongestDownstreamPath(void) const;
107  void setLongestDownstreamPath(int pathLength);
108  bool getAttempted(void) const;
109  void setAttempted(bool attempted);
110  dispatch_group_t getLoadingGroup(void) const;
111  void dump() const;
112 
113  private:
114  void initialize(Environment *environment, const string &searchPath, VuoFileUtilities::File *file, bool isSourceFile, bool isSubcomposition);
115 
116  Environment *environment;
117  string searchPath;
118  string moduleKey;
119  VuoFileUtilities::File *file;
120  string sourceCode;
121  bool sourceCodeOverridden;
122  unsigned long lastModified;
123  set<string> containedNodeClasses;
124  int longestDownstreamPath;
125  bool attempted;
126  dispatch_group_t loading;
127 
128 #pragma clang diagnostic push
129 #pragma clang diagnostic ignored "-Wunused-private-field"
130  void *p;
131 #pragma clang diagnostic pop
132 #ifdef VUO_PRO
133 #include "pro/VuoCompilerModuleInfo_Pro.hh"
134 #endif
135  };
136 
137  class DependencyGraphVertex : public VuoDirectedAcyclicGraph::Vertex
138  {
139  public:
140  static DependencyGraphVertex * vertexForDependency(const string &dependency, VuoDirectedAcyclicGraph *graph);
141  string getDependency(void);
142  Environment * getEnvironment(void);
143  void setEnvironment(Environment *environment);
144  bool isCompatible(void);
145  void setCompatible(bool compatible);
146  string key(void);
147 
148  private:
149  string dependency;
150  Environment *environment;
151  bool compatible;
152  };
153 
157  class ModuleInfoIterator
158  {
159  public:
160  ModuleInfoIterator(map<string, map<string, ModuleInfo *> > *allModuleInfos);
161  ModuleInfoIterator(map<string, map<string, ModuleInfo *> > *allModuleInfos, const set<string> &searchModuleKeys);
162  ModuleInfo * next(void);
163 
164  private:
165  void initialize(void);
166 
167  map<string, map<string, ModuleInfo *> > *allModuleInfos;
168  set<string> searchModuleKeys;
169  bool hasSearchModuleKeys;
170  map<string, map<string, ModuleInfo *> >::iterator currSearchPath;
171  map<string, ModuleInfo *>::iterator currModuleKey;
172  bool hasCurrModuleKey;
173  };
174 
203  class Environment : public VuoFileWatcherDelegate
204  {
205  private:
206  string target;
207  bool builtIn;
208  bool generated;
209  set<VuoCompiler *> compilersToNotify;
210  dispatch_queue_t compilersToNotifyQueue;
211  set<VuoFileWatcher *> moduleSearchPathWatchers;
212  map<string, VuoCompilerNodeClass *> nodeClasses;
213  map<string, VuoCompilerType *> types;
214  set<VuoCompilerGenericType *> genericTypes;
215  map<string, VuoNodeSet *> nodeSetForName;
216  map<string, VuoCompilerModule *> libraryModules;
217  map<string, dispatch_group_t> specializedModulesLoading;
218  map<string, map<string, ModuleInfo *> > moduleFilesAtSearchPath;
219  map<string, map<string, ModuleInfo *> > sourceFilesAtSearchPath;
220  vector<string> moduleSearchPaths;
221  vector<string> headerSearchPaths;
222  vector<string> librarySearchPaths;
223  vector<string> frameworkSearchPaths;
224  vector<string> expatriateSourceFiles;
225  string moduleCachePath;
226  string currentModuleCacheDylib;
227  unsigned long lastModuleCacheRebuild;
228  bool isModuleCacheableDataDirty;
229  bool isModuleCacheInitialized;
230  bool isModuleCacheAvailable;
231  set<string> moduleCacheContents;
232  set<string> moduleCacheDylibs;
233  set<string> moduleCacheFrameworks;
234  static map<string, VuoFileUtilities::File *> moduleCacheFileForLocking;
235  static dispatch_queue_t moduleCacheBuildingQueue;
236  VuoDirectedAcyclicGraph *dependencyGraph;
237  VuoDirectedAcyclicGraph *compositionDependencyGraph;
238  VuoModuleCompilationQueue *moduleCompilationQueue;
239 
240  void updateModulesAtSearchPath(const string &path);
241  void updateModuleAtSearchPath(const string &moduleSearchPath, const string &moduleRelativePath);
242  void updateSourceFilesAtSearchPath(const string &path);
243  void startWatchingModuleSearchPath(const string &moduleSearchPath);
244  VuoCompilerModule * loadModule(ModuleInfo *moduleInfo);
245 
246  friend class TestCompilingAndLinking;
247 
248  public:
249  dispatch_queue_t moduleSearchPathContentsChangedQueue;
250  static const string pidCacheDirPrefix;
251 
252  explicit Environment(string target, bool builtIn, bool generated);
253  virtual ~Environment(void);
254  string getTarget();
255  void addCompilerToNotify(VuoCompiler *compiler);
256  void removeCompilerToNotify(VuoCompiler *compiler);
257  map<string, VuoCompilerNodeClass *> getNodeClasses(void);
258  VuoCompilerNodeClass * getNodeClass(const string &moduleKey);
259  VuoCompilerNodeClass * takeNodeClass(const string &moduleKey);
260  map<string, VuoCompilerType *> getTypes(void);
261  VuoCompilerType * getType(const string &moduleKey);
262  map<string, VuoNodeSet *> getNodeSets();
263  VuoCompilerModule *getLibraryModule(const string &libraryModuleName);
264  map<string, VuoCompilerModule *> getLibraryModules(void);
265  VuoCompilerModule * findModule(const string &moduleKey);
266  VuoNodeSet * findNodeSet(const string &name);
267  void addModuleSearchPath(const string &path, bool shouldWatch = true);
268  vector<string> getModuleSearchPaths(void);
269  void addHeaderSearchPath(const string &path);
270  vector<string> getHeaderSearchPaths(void);
271  void addLibrarySearchPath(const string &path);
272  vector<string> getLibrarySearchPaths(void);
273  void addFrameworkSearchPath(const string &path);
274  void setModuleCachePath(const string &path);
275  string getCompiledModuleCachePath(void);
276  string getOverriddenCompiledModuleCachePath(void);
277  vector<string> getFrameworkSearchPaths(void);
278  VuoDirectedAcyclicGraph * getDependencyGraph(void);
279  VuoDirectedAcyclicGraph * getCompositionDependencyGraph(void);
280  void addExpatriateSourceFile(const string &sourcePath);
281  void removeExpatriateSourceFile(const string &sourcePath);
282  ModuleInfo * listModule(const string &moduleKey);
283  ModuleInfoIterator listModules(const set<string> &moduleKeys);
284  ModuleInfoIterator listAllModules(void);
285  ModuleInfo * listSourceFile(const string &moduleKey);
286  ModuleInfoIterator listSourceFiles(const set<string> &moduleKeys);
287  ModuleInfoIterator listAllSourceFiles(void);
288  static vector<string> getBuiltInModuleSearchPaths(void);
289  static vector<string> getBuiltInHeaderSearchPaths(void);
290  static vector<string> getBuiltInLibrarySearchPaths(void);
291  static vector<string> getBuiltInFrameworkSearchPaths(void);
292  void addSearchPathsToSharedEnvironment(void);
293  void stopWatchingModuleSearchPaths(void);
294  void fileChanged(const string &moduleSearchPath);
295  void moduleSearchPathContentsChanged(const string &moduleSearchPath);
296  void moduleFileChanged(const string &modulePath, const string &moduleSourceCode, std::function<void(void)> moduleLoadedCallback, VuoCompiler *compiler, VuoCompilerIssues *issues = nullptr);
297  void notifyCompilers(const set<VuoCompilerModule *> &modulesAdded, const set<pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified, const set<VuoCompilerModule *> &modulesRemoved, VuoCompilerIssues *issues, bool oldModulesInvalidated = true);
298  set<VuoCompilerModule *> loadCompiledModules(const set<string> &moduleKeys, const map<string, string> &sourceCodeForModule);
299  set<dispatch_group_t> loadSpecializedModules(const set<string> &moduleKeys, VuoCompiler *compiler, dispatch_queue_t llvmQueue);
300  set<dispatch_group_t> compileModulesFromSourceCode(const set<string> &moduleKeys, bool shouldRecompileIfUnchanged);
301  set<VuoCompilerModule *> unloadCompiledModules(const set<string> &moduleKeys);
302  void deleteModulesCompiledFromSourceCode(const set<string> &moduleKeys);
303  void replaceNodeClass(VuoCompilerNodeClass *newNodeClass);
304  void addToDependencyGraph(VuoCompilerModule *module);
305  void removeFromDependencyGraph(VuoCompilerModule *module);
306  void reifyPortTypes(const map<string, VuoCompilerType *> &inheritedTypes);
307  void getCacheableModulesAndDependencies(set<string> &cacheableModulesAndDependencies, set<string> &dylibsNeededToLinkToThisCache, set<string> &frameworksNeededToLinkToThisCache);
308  void useModuleCache(bool shouldUseExistingCache, VuoCompiler *compiler, set<string> cacheableModulesAndDependencies, set<string> dylibsNeededToLinkToCaches, set<string> frameworksNeededToLinkToCaches, unsigned long lastPrerequisiteModuleCacheRebuild);
309  static void waitForModuleCachesToBuild(void);
310  bool findInModuleCache(const string &moduleOrDependency, string &cachePath);
311  string getCurrentModuleCacheDylib(void);
312  unsigned long getLastModuleCacheRebuild(void);
313  void modulesChanged(void);
314 
315  bool isBuiltInOriginal(void);
316  bool isBuiltIn(void);
317  bool isGenerated(void);
318  string getName();
319 
320 #ifdef VUO_PRO
321 #include "pro/VuoCompilerEnvironment_Pro.hh"
322 #endif
323  };
324 
325  static set<VuoCompiler *> allCompilers;
326  static dispatch_queue_t environmentQueue;
327  static map<string, vector< vector<Environment *> > > sharedEnvironments;
328  static map<string, vector<Environment *> > environmentsForCompositionFamily;
329  vector< vector<Environment *> > environments;
330  string lastCompositionBaseDir;
331  bool lastCompositionIsSubcomposition;
332  bool shouldLoadAllModules;
333  bool hasLoadedAllModules;
334  dispatch_queue_t modulesToLoadQueue;
335  dispatch_group_t moduleSourceCompilersExist;
336  static dispatch_group_t moduleSourceCompilersExistGlobally;
337  dispatch_group_t moduleCacheBuilding;
338  VuoDirectedAcyclicNetwork *dependencyGraph;
339  VuoDirectedAcyclicNetwork *compositionDependencyGraph;
340  static string vuoFrameworkInProgressPath;
341  string clangPath;
342  string telemetry;
343  string target;
344  bool isVerbose;
345  bool _shouldShowSplashWindow;
346  VuoCompilerDelegate *delegate;
347  dispatch_queue_t delegateQueue;
348 
349  void applyToInstalledEnvironments(void (^doForEnvironment)(Environment *));
350  void applyToInstalledEnvironments(void (^doForEnvironment)(Environment *, bool *, string), bool *, string);
351  void applyToAllEnvironments(void (^doForEnvironment)(Environment *));
352 
353  static void reset(void);
354  VuoDirectedAcyclicNetwork * makeDependencyNetwork(const vector< vector<Environment *> > &environments, VuoDirectedAcyclicGraph * (^graphForEnvironment)(Environment *));
355  void loadModulesIfNeeded(const set<string> &moduleKeys = set<string>());
356  set<dispatch_group_t> loadModulesAndSources(const set<string> &modulesAddedKeys, const set<string> &modulesModifiedKeys, const set<string> &modulesRemovedKeys, const set<string> &sourcesAddedKeys, const set<string> &sourcesModifiedKeys, const set<string> &sourcesRemovedKeys, bool willLoadAllModules, bool shouldRecompileSourcesIfUnchanged, Environment *currentEnvironment, VuoCompilerIssues *issuesForCurrentEnvironment, std::function<void(void)> moduleLoadedCallback, const string &moduleAddedOrModifiedSourceCode);
357  void findDependentModulesAndSources(map<Environment *, set<string> > &changedModules, const vector<VuoDirectedAcyclicNetwork *> &searchDependencyGraphs, VuoDirectedAcyclicGraph *currentEnvironmentDependencyGraph, map<Environment *, set<string> > &modulesDepOnChangedModules_this, map<Environment *, set<string> > &modulesDepOnChangedModules_other, map<Environment *, set<string> > &sourcesDepOnChangedModules_this, map<Environment *, set<string> > &sourcesDepOnChangedModules_other);
358  void loadedModules(map<string, VuoCompilerModule *> modulesAdded, map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified, map<string, VuoCompilerModule *> modulesRemoved, VuoCompilerIssues *issues, void *delegateData, Environment *currentEnvironment);
359  void loadNodeClassGeneratedAtRuntime(VuoCompilerNodeClass *nodeClass, Environment *env);
360  void reifyGenericPortTypes(VuoCompilerComposition *composition);
361  void reifyGenericPortTypes(VuoNode *node);
362  Module * compileCompositionToModule(VuoCompilerComposition *composition, const string &moduleKey, bool isTopLevelComposition, VuoCompilerIssues *issues);
363  void compileSubcompositionString(const string &compositionString, const string &outputPath, std::function<void(void)> moduleLoadedCallback, Environment *environment, VuoCompilerIssues *issues = NULL, const string inputPathForIssues = "");
364  void linkCompositionToCreateExecutableOrDynamicLibrary(string compiledCompositionPath, string linkedCompositionPath, Optimization optimization, bool isDylib, string rPath="", bool shouldAdHocCodeSign = true);
365  set<string> getDependenciesForComposition(const string &compiledCompositionPath);
366  set<string> getDependenciesForComposition(const set<string> &directDependencies, bool checkCompatibility);
367  void getLinkerInputs(const set<string> &dependencies, Optimization optimization, set<Module *> &modules, set<string> &libraries, set<string> &frameworks);
368  void getLinkerInputs(const set<string> &dependencies, Optimization optimization, set<string> &builtInModuleAndLibraryDependencies, set<string> &userModuleAndLibraryDependencies, map<string, set<string> > &builtInCacheDependencies, map<string, set<string> > &userCacheDependencies, set<Module *> &builtInModules, set<Module *> &userModules, set<string> &builtInLibraries, set<string> &userLibraries, set<string> &externalLibraries, set<string> &externalFrameworks);
369  static string getLibraryPath(const string &dependency, vector<string> librarySearchPaths);
370  void useModuleCache(bool shouldUseExistingBuiltInCaches, bool shouldUseExistingOtherCaches);
371  bool findInModuleCache(const string &moduleOrDependency, string &cachePath, bool &isBuiltinCache) VuoWarnUnusedResult;
372  void link(string outputPath, const set<Module *> &modules, const set<string> &libraries, const set<string> &frameworks, bool isDylib, string rPath="", bool shouldAdHocCodeSign = true, VuoCompilerIssues *issues = nullptr);
373  static void adHocCodeSign(string path);
374  Module *readModuleFromC(string inputPath, const vector<string> &headerSearchPaths, const vector<string> &extraArgs, VuoCompilerIssues *issues);
375  static Module *readModuleFromBitcode(VuoFileUtilities::File *inputFile, string arch);
376  static Module *readModuleFromBitcodeData(char *inputData, size_t inputDataBytes, string arch, string &error);
377  static bool writeModuleToBitcode(Module *module, string outputPath);
378  VuoNode * createPublishedNode(const string &nodeClassName, const vector<VuoPublishedPort *> &publishedPorts);
379  static void setTargetForModule(Module *module, string target);
380  static string getTargetArch(string target);
381  static string getProcessTarget(void);
382  VuoCompilerModule * getModule(const string &moduleKey);
383  static vector<string> getCoreVuoDependencies(void);
384  static string getRuntimeMainDependency(void);
385  static string getRuntimeDependency(void);
386  void addModuleSearchPath(string path);
387  static string getVuoFrameworkPath(void);
388  string getClangPath(void);
389  void setClangPath(const string &clangPath);
390  string getCompositionStubPath(void);
391  static string getCachePathForComposition(const string compositionDir);
392 
393  friend class TestVuoCompiler;
395  friend class TestCompilerDelegate;
396  friend class TestVuoCompilerModule;
397  friend class TestVuoCompilerBitcodeGenerator;
398  friend class TestCompilingAndLinking;
399  friend class TestSubcompositions;
400  friend class TestModuleLoading;
401  friend class TestEventDropping;
403 
404 public:
405  VuoCompiler(const string &compositionPath = "", string target = "");
406  ~VuoCompiler(void);
407  void setDelegate(VuoCompilerDelegate *delegate);
408  void setCompositionPath(const string &compositionPath);
409  static Module *readModuleFromBitcode(string inputPath, string arch);
410  static void destroyModule(VuoCompilerModule *module);
411  static void destroyLlvmModule(Module *module);
412  void compileComposition(VuoCompilerComposition *composition, string outputPath, bool isTopLevelComposition, VuoCompilerIssues *issues);
413  void compileComposition(string inputPath, string outputPath, bool isTopLevelComposition, VuoCompilerIssues *issues);
414  void compileCompositionString(const string &compositionString, string outputPath, bool isTopLevelComposition, VuoCompilerIssues *issues);
415  void compileModule(string inputPath, string outputPath);
416  void compileModule(string inputPath, string outputPath, const vector<string> &includeDirs);
417  void linkCompositionToCreateExecutable(string inputPath, string outputPath, Optimization optimization, string rPath="", bool shouldAdHocCodeSign = true);
418  void linkCompositionToCreateDynamicLibrary(string inputPath, string outputPath, Optimization optimization, bool shouldAdHocCodeSign = true);
419  void linkCompositionToCreateDynamicLibraries(string compiledCompositionPath, string linkedCompositionPath, VuoRunningCompositionLibraries *runningCompositionLibraries);
421  set<string> getDependenciesForComposition(VuoCompilerComposition *composition);
423  void prepareForFastBuild(void);
424  string getArch(void);
425  static void generateBuiltInModuleCaches(string vuoFrameworkPath, string target);
426  static void deleteOldModuleCaches(void);
427  void setLoadAllModules(bool shouldLoadAllModules);
428  VuoNode * createNode(VuoCompilerNodeClass *nodeClass, string title="", double x=0, double y=0);
429  VuoNode * createNode(VuoCompilerNodeClass *nodeClass, VuoNode *nodeToCopyMetadataFrom);
430  VuoNode * createPublishedInputNode(vector<VuoPublishedPort *> publishedInputPorts);
431  VuoNode * createPublishedOutputNode(vector<VuoPublishedPort *> publishedOutputPorts);
432  void installNodeClassAtCompositionLocalScope(const string &sourcePath);
433  void uninstallNodeClassAtCompositionLocalScope(const string &sourcePath);
434  void overrideInstalledNodeClass(const string &sourcePath, const string &sourceCode);
435  void revertOverriddenNodeClass(const string &sourcePath);
436  VuoCompilerNodeClass * getNodeClass(const string &nodeClassName);
437  map<string, VuoCompilerNodeClass *> getNodeClasses(void);
438  VuoCompilerType * getType(const string &typeName);
439  map<string, VuoCompilerType *> getTypes(void);
440  VuoCompilerModule *getLibraryModule(const string &libraryModuleName);
441  map<string, VuoCompilerModule *> getLibraryModules();
442  map<string, VuoNodeSet *> getNodeSets();
443  VuoNodeSet * getNodeSetForName(const string &name);
444  void listNodeClasses(const string &format = "");
445  static string getModuleKeyForPath(string path);
446  bool isCompositionLocalModule(string moduleKey);
447  string getCompositionLocalModulesPath(void);
448  string getCompositionLocalPath(void);
449  void addHeaderSearchPath(const string &path);
450  void addLibrarySearchPath(const string &path);
451  void addFrameworkSearchPath(const string &path);
452  void setTelemetry(const string &telemetry);
453  void setVerbose(bool isVerbose);
454  void setShouldPotentiallyShowSplashWindow(bool potentiallyShow);
455  bool shouldShowSplashWindow();
456  string getCompositionLoaderPath(void);
457  void print(void);
458 
459  static VuoRunner * newSeparateProcessRunnerFromCompositionFile(string compositionFilePath, VuoCompilerIssues *issues);
460  static VuoRunner * newSeparateProcessRunnerFromCompositionString(string composition, string processName, string workingDirectory, VuoCompilerIssues *issues);
461  static VuoRunner * newCurrentProcessRunnerFromCompositionFile(string compositionFilePath, VuoCompilerIssues *issues);
462  static VuoRunner * newCurrentProcessRunnerFromCompositionString(string composition, string workingDirectory, VuoCompilerIssues *issues);
463 
464  static llvm::LLVMContext *globalLLVMContext;
465 
466 private:
467  void *p;
468 #ifdef VUO_PRO
469 #include "pro/VuoCompiler_Pro.hh"
470 #endif
471 };
472 
480 {
481 public:
485  VuoCompilerDelegate(void);
486 
512  virtual void loadedModules(const map<string, VuoCompilerModule *> &modulesAdded,
513  const map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
514  const map<string, VuoCompilerModule *> &modulesRemoved, VuoCompilerIssues *issues) = 0;
515 
525  void loadedModulesCompleted(void);
526 
527 private:
528  class LoadedModulesData
529  {
530  public:
531  LoadedModulesData(const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
532  const set<VuoCompilerModule *> &modulesRemoved, VuoCompilerIssues *issues);
533  ~LoadedModulesData(void);
534  void retain(void);
535  void release(void);
536 
537  private:
538  int referenceCount;
539  dispatch_queue_t referenceCountQueue;
540  set< pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified;
541  set<VuoCompilerModule *> modulesRemoved;
542  VuoCompilerIssues *issues;
543  };
544 
545  void enqueueData(LoadedModulesData *data);
546  LoadedModulesData * dequeueData(void);
547 
548  list<LoadedModulesData *> pendingData;
549  dispatch_queue_t pendingDataQueue;
550 
551  friend class VuoCompiler;
552 };