Vuo  2.0.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  bool getAttempted(void) const;
107  void setAttempted(bool attempted);
108  dispatch_group_t getLoadingGroup(void) const;
109  void dump() const;
110 
111  private:
112  void initialize(Environment *environment, const string &searchPath, VuoFileUtilities::File *file, bool isSourceFile, bool isSubcomposition);
113 
114  Environment *environment;
115  string searchPath;
116  string moduleKey;
117  VuoFileUtilities::File *file;
118  string sourceCode;
119  bool sourceCodeOverridden;
120  unsigned long lastModified;
121  set<string> containedNodeClasses;
122  bool attempted;
123  dispatch_group_t loading;
124 
125  void *p;
126 #ifdef VUO_PRO
127 #include "pro/VuoCompilerModuleInfo_Pro.hh"
128 #endif
129  };
130 
131  class DependencyGraphVertex : public VuoDirectedAcyclicGraph::Vertex
132  {
133  public:
134  static DependencyGraphVertex * vertexForDependency(const string &dependency, VuoDirectedAcyclicGraph *graph);
135  string getDependency(void);
136  Environment * getEnvironment(void);
137  void setEnvironment(Environment *environment);
138  bool isCompatible(void);
139  void setCompatible(bool compatible);
140  string key(void);
141 
142  private:
143  string dependency;
144  Environment *environment;
145  bool compatible;
146  };
147 
151  class ModuleInfoIterator
152  {
153  public:
154  ModuleInfoIterator(map<string, map<string, ModuleInfo *> > *allModuleInfos);
155  ModuleInfoIterator(map<string, map<string, ModuleInfo *> > *allModuleInfos, const set<string> &searchModuleKeys);
156  ModuleInfo * next(void);
157 
158  private:
159  void initialize(void);
160 
161  map<string, map<string, ModuleInfo *> > *allModuleInfos;
162  set<string> searchModuleKeys;
163  bool hasSearchModuleKeys;
164  map<string, map<string, ModuleInfo *> >::iterator currSearchPath;
165  map<string, ModuleInfo *>::iterator currModuleKey;
166  bool hasCurrModuleKey;
167  };
168 
197  class Environment : public VuoFileWatcherDelegate
198  {
199  private:
200  set<VuoCompiler *> compilersToNotify;
201  dispatch_queue_t compilersToNotifyQueue;
202  set<VuoFileWatcher *> moduleSearchPathWatchers;
203  map<string, VuoCompilerNodeClass *> nodeClasses;
204  map<string, VuoCompilerType *> types;
205  set<VuoCompilerGenericType *> genericTypes;
206  map<string, VuoNodeSet *> nodeSetForName;
207  map<string, VuoCompilerModule *> libraryModules;
208  map<string, dispatch_group_t> specializedModulesLoading;
209  map<string, map<string, ModuleInfo *> > moduleFilesAtSearchPath;
210  map<string, map<string, ModuleInfo *> > sourceFilesAtSearchPath;
211  vector<string> moduleSearchPaths;
212  vector<string> headerSearchPaths;
213  vector<string> librarySearchPaths;
214  vector<string> frameworkSearchPaths;
215  vector<string> expatriateSourceFiles;
216  string moduleCachePath;
217  string moduleCacheSuffix;
218  bool isModuleCacheableDataDirty;
219  bool isModuleCacheInitialized;
220  bool isModuleCacheAvailable;
221  set<string> moduleCacheContents;
222  set<string> moduleCacheDylibs;
223  set<string> moduleCacheFrameworks;
224  static map<string, VuoFileUtilities::File *> moduleCacheFileForLocking;
225  static dispatch_queue_t moduleCacheBuildingQueue;
226  VuoDirectedAcyclicGraph *dependencyGraph;
227  VuoDirectedAcyclicGraph *compositionDependencyGraph;
228  VuoModuleCompilationQueue *moduleCompilationQueue;
229 
230  void updateModulesAtSearchPath(const string &path, bool shouldCleanModuleCache=true);
231  void updateSourceFilesAtSearchPath(const string &path);
232  void startWatchingModuleSearchPath(const string &moduleSearchPath);
233  VuoCompilerModule * loadModule(ModuleInfo *moduleInfo);
234 
235  friend class TestCompilingAndLinking;
236 
237  public:
238  dispatch_queue_t moduleSearchPathContentsChangedQueue;
239  static const string pidCacheDirPrefix;
240 
241  Environment(void);
242  virtual ~Environment(void);
243  void addCompilerToNotify(VuoCompiler *compiler);
244  void removeCompilerToNotify(VuoCompiler *compiler);
245  map<string, VuoCompilerNodeClass *> getNodeClasses(void);
246  VuoCompilerNodeClass * getNodeClass(const string &moduleKey);
247  VuoCompilerNodeClass * takeNodeClass(const string &moduleKey);
248  map<string, VuoCompilerType *> getTypes(void);
249  VuoCompilerType * getType(const string &moduleKey);
250  map<string, VuoNodeSet *> getNodeSets();
251  map<string, VuoCompilerModule *> getLibraryModules(void);
252  VuoCompilerModule * findModule(const string &moduleKey);
253  VuoNodeSet * findNodeSet(const string &name);
254  void addModuleSearchPath(const string &path, bool shouldWatch = true);
255  vector<string> getModuleSearchPaths(void);
256  void addHeaderSearchPath(const string &path);
257  vector<string> getHeaderSearchPaths(void);
258  void addLibrarySearchPath(const string &path);
259  vector<string> getLibrarySearchPaths(void);
260  void addFrameworkSearchPath(const string &path);
261  void setModuleCachePath(const string &path);
262  string getCompiledModuleCachePath(void);
263  string getOverriddenCompiledModuleCachePath(void);
264  vector<string> getFrameworkSearchPaths(void);
265  VuoDirectedAcyclicGraph * getDependencyGraph(void);
266  VuoDirectedAcyclicGraph * getCompositionDependencyGraph(void);
267  void addExpatriateSourceFile(const string &sourcePath);
268  void removeExpatriateSourceFile(const string &sourcePath);
269  ModuleInfo * listModule(const string &moduleKey);
270  ModuleInfoIterator listModules(const set<string> &moduleKeys);
271  ModuleInfoIterator listAllModules(void);
272  ModuleInfo * listSourceFile(const string &moduleKey);
273  ModuleInfoIterator listSourceFiles(const set<string> &moduleKeys);
274  ModuleInfoIterator listAllSourceFiles(void);
275  static vector<string> getBuiltInModuleSearchPaths(void);
276  static vector<string> getBuiltInHeaderSearchPaths(void);
277  static vector<string> getBuiltInLibrarySearchPaths(void);
278  static vector<string> getBuiltInFrameworkSearchPaths(void);
279  void addSearchPathsToSharedEnvironment(void);
280  void stopWatchingModuleSearchPaths(void);
281  void fileChanged(const string &moduleSearchPath);
282  void moduleSearchPathContentsChanged(const string &moduleSearchPath, const string &moduleAddedOrModifiedPath = "", const string &moduleAddedOrModifiedSourceCode = "", std::function<void(void)> moduleLoadedCallback = nullptr, VuoCompiler *compiler = nullptr, VuoCompilerIssues *issues = nullptr);
283  void notifyCompilers(const set<VuoCompilerModule *> &modulesAdded, const set<pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified, const set<VuoCompilerModule *> &modulesRemoved, VuoCompilerIssues *issues, bool oldModulesInvalidated = true);
284  set<VuoCompilerModule *> loadCompiledModules(const set<string> &moduleKeys, const map<string, string> &sourceCodeForModule);
285  set<dispatch_group_t> loadSpecializedModules(const set<string> &moduleKeys, VuoCompiler *compiler, dispatch_queue_t llvmQueue);
286  set<dispatch_group_t> compileModulesFromSourceCode(const set<string> &moduleKeys, bool shouldRecompileIfUnchanged);
287  set<VuoCompilerModule *> unloadCompiledModules(const set<string> &moduleKeys);
288  void deleteModulesCompiledFromSourceCode(const set<string> &moduleKeys);
289  void replaceNodeClass(VuoCompilerNodeClass *newNodeClass);
290  void addToDependencyGraph(VuoCompilerModule *module);
291  void removeFromDependencyGraph(VuoCompilerModule *module);
292  void reifyPortTypes(const map<string, VuoCompilerType *> &inheritedTypes);
293  void getCacheableModulesAndDependencies(bool isBuiltIn, bool installed, set<string> &cacheableModulesAndDependencies, set<string> &dylibsNeededToLinkToThisCache, set<string> &frameworksNeededToLinkToThisCache);
294  void useModuleCache(bool shouldUseExistingCache, VuoCompiler *compiler, set<string> cacheableModulesAndDependencies, set<string> dylibsNeededToLinkToCaches, set<string> frameworksNeededToLinkToCaches);
295  static void waitForModuleCachesToBuild(void);
296  bool findInModuleCache(const string &moduleOrDependency, string &cachePath);
297  void modulesChanged(void);
298 
299  bool isBuiltIn();
300  string getName();
301 
302 #ifdef VUO_PRO
303 #include "pro/VuoCompilerEnvironment_Pro.hh"
304 #endif
305  };
306 
307  static dispatch_queue_t environmentQueue;
308  static vector< vector<Environment *> > sharedEnvironments;
309  static map<string, vector<Environment *> > environmentsForCompositionFamily;
310  vector< vector<Environment *> > environments;
311  string lastCompositionBaseDir;
312  bool lastCompositionIsSubcomposition;
313  bool shouldLoadAllModules;
314  bool hasLoadedAllModules;
315  dispatch_queue_t modulesToLoadQueue;
316  static dispatch_group_t moduleSourceCompilersExist;
317  dispatch_group_t moduleCacheBuilding;
318  VuoDirectedAcyclicNetwork *dependencyGraph;
319  VuoDirectedAcyclicNetwork *compositionDependencyGraph;
320  static string vuoFrameworkInProgressPath;
321  llvm::sys::Path clangPath;
322  string telemetry;
323  string target;
324  bool isVerbose;
325  bool _shouldShowSplashWindow;
326  VuoCompilerDelegate *delegate;
327  dispatch_queue_t delegateQueue;
328 
329  void applyToInstalledEnvironments(void (^doForEnvironment)(Environment *));
330  void applyToInstalledEnvironments(void (^doForEnvironment)(Environment *, bool *, string), bool *, string);
331  void applyToAllEnvironments(void (^doForEnvironment)(Environment *));
332 
333  static void reset(void);
334  VuoDirectedAcyclicNetwork * makeDependencyNetwork(const vector< vector<Environment *> > &environments, VuoDirectedAcyclicGraph * (^graphForEnvironment)(Environment *));
335  void loadModulesIfNeeded(const set<string> &moduleKeys = set<string>());
336  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);
337  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);
338  void loadedModules(map<string, VuoCompilerModule *> modulesAdded, map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified, map<string, VuoCompilerModule *> modulesRemoved, VuoCompilerIssues *issues, void *delegateData, Environment *currentEnvironment);
339  void loadNodeClassGeneratedAtRuntime(VuoCompilerNodeClass *nodeClass, Environment *env);
340  void reifyGenericPortTypes(VuoCompilerComposition *composition);
341  void reifyGenericPortTypes(VuoNode *node);
342  Module * compileCompositionToModule(VuoCompilerComposition *composition, const string &moduleKey, bool isTopLevelComposition, VuoCompilerIssues *issues);
343  void compileSubcompositionString(const string &compositionString, const string &outputPath, std::function<void(void)> moduleLoadedCallback, Environment *environment, VuoCompilerIssues *issues = NULL, const string inputPathForIssues = "");
344  void linkCompositionToCreateExecutableOrDynamicLibrary(string compiledCompositionPath, string linkedCompositionPath, Optimization optimization, bool isDylib, string rPath="");
345  set<string> getDependenciesForComposition(const string &compiledCompositionPath);
346  set<string> getDependenciesForComposition(const set<string> &directDependencies, bool checkCompatibility);
347  void getLinkerInputs(const set<string> &dependencies, Optimization optimization, set<Module *> &modules, set<string> &libraries, set<string> &frameworks);
348  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);
349  static string getLibraryPath(const string &dependency, vector<string> librarySearchPaths);
350  void useModuleCache(bool shouldUseExistingBuiltInCaches, bool shouldUseExistingOtherCaches);
351  bool findInModuleCache(const string &moduleOrDependency, string &cachePath, bool &isBuiltinCache) VuoWarnUnusedResult;
352  void link(string outputPath, const set<Module *> &modules, const set<string> &libraries, const set<string> &frameworks, bool isDylib, string rPath="");
353  Module * readModuleFromC(string inputPath, const vector<string> &headerSearchPaths, const vector<string> &extraArgs);
354  static Module * readModuleFromBitcode(VuoFileUtilities::File *inputFile);
355  static Module * readModuleFromBitcodeData(char *inputData, size_t inputDataBytes, string &error);
356  static bool writeModuleToBitcode(Module *module, string outputPath);
357  VuoNode * createPublishedNode(const string &nodeClassName, const vector<VuoPublishedPort *> &publishedPorts);
358  static void setTargetForModule(Module *module, string target = "");
359  VuoCompilerModule * getModule(const string &moduleKey);
360  static vector<string> getCoreVuoDependencies(void);
361  static string getRuntimeMainDependency(void);
362  static string getRuntimeDependency(void);
363  void addModuleSearchPath(string path);
364  static string getVuoFrameworkPath(void);
365  llvm::sys::Path getClangPath(void);
366  void setClangPath(const string &clangPath);
367  string getCompositionStubPath(void);
368  static string getCachePathForComposition(const string compositionDir);
369 
370  friend class TestVuoCompiler;
372  friend class TestCompilerDelegate;
373  friend class TestVuoCompilerModule;
374  friend class TestVuoCompilerBitcodeGenerator;
375  friend class TestCompilingAndLinking;
376  friend class TestSubcompositions;
377  friend class TestModuleLoading;
378  friend class TestEventDropping;
380 
381 public:
382  VuoCompiler(const string &compositionPath = "");
383  ~VuoCompiler(void);
384  void setDelegate(VuoCompilerDelegate *delegate);
385  void setCompositionPath(const string &compositionPath);
386  static Module * readModuleFromBitcode(string inputPath);
387  static void destroyModule(VuoCompilerModule *module);
388  static void destroyLlvmModule(Module *module);
389  void compileComposition(VuoCompilerComposition *composition, string outputPath, bool isTopLevelComposition, VuoCompilerIssues *issues);
390  void compileComposition(string inputPath, string outputPath, bool isTopLevelComposition, VuoCompilerIssues *issues);
391  void compileCompositionString(const string &compositionString, string outputPath, bool isTopLevelComposition, VuoCompilerIssues *issues);
392  void compileModule(string inputPath, string outputPath);
393  void compileModule(string inputPath, string outputPath, const vector<string> &includeDirs);
394  void linkCompositionToCreateExecutable(string inputPath, string outputPath, Optimization optimization, string rPath="");
395  void linkCompositionToCreateDynamicLibrary(string inputPath, string outputPath, Optimization optimization);
396  void linkCompositionToCreateDynamicLibraries(string compiledCompositionPath, string linkedCompositionPath, VuoRunningCompositionLibraries *runningCompositionLibraries);
398  set<string> getDependenciesForComposition(VuoCompilerComposition *composition);
400  void prepareForFastBuild(void);
401  static void generateBuiltInModuleCaches(const string &vuoFrameworkPath);
402  static void deleteOldModuleCaches(void);
403  void setLoadAllModules(bool shouldLoadAllModules);
404  VuoNode * createNode(VuoCompilerNodeClass *nodeClass, string title="", double x=0, double y=0);
405  VuoNode * createPublishedInputNode(vector<VuoPublishedPort *> publishedInputPorts);
406  VuoNode * createPublishedOutputNode(vector<VuoPublishedPort *> publishedOutputPorts);
407  void installNodeClassAtCompositionLocalScope(const string &sourcePath);
408  void uninstallNodeClassAtCompositionLocalScope(const string &sourcePath);
409  void overrideInstalledNodeClass(const string &sourcePath, const string &sourceCode);
410  void revertOverriddenNodeClass(const string &sourcePath);
411  VuoCompilerNodeClass * getNodeClass(const string &nodeClassName);
412  map<string, VuoCompilerNodeClass *> getNodeClasses(void);
413  VuoCompilerType * getType(const string &typeName);
414  map<string, VuoCompilerType *> getTypes(void);
415  map<string, VuoCompilerModule *> getLibraryModules();
416  map<string, VuoNodeSet *> getNodeSets();
417  VuoNodeSet * getNodeSetForName(const string &name);
418  void listNodeClasses(const string &format = "");
419  static string getModuleKeyForPath(string path);
420  bool isCompositionLocalModule(string moduleKey);
421  string getCompositionLocalModulesPath(void);
422  string getCompositionLocalPath(void);
423  void addHeaderSearchPath(const string &path);
424  void addLibrarySearchPath(const string &path);
425  void addFrameworkSearchPath(const string &path);
426  void setTelemetry(const string &telemetry);
427  void setTarget(const string &target);
428  void setVerbose(bool isVerbose);
429  void setShouldPotentiallyShowSplashWindow(bool potentiallyShow);
430  bool shouldShowSplashWindow();
431  string getCompositionLoaderPath(void);
432  void print(void);
433 
434  static VuoRunner * newSeparateProcessRunnerFromCompositionFile(string compositionFilePath, VuoCompilerIssues *issues);
435  static VuoRunner * newSeparateProcessRunnerFromCompositionString(string composition, string processName, string workingDirectory, VuoCompilerIssues *issues);
436  static VuoRunner * newCurrentProcessRunnerFromCompositionFile(string compositionFilePath, VuoCompilerIssues *issues);
437  static VuoRunner * newCurrentProcessRunnerFromCompositionString(string composition, string workingDirectory, VuoCompilerIssues *issues);
438 
439 private:
440  void *p;
441 #ifdef VUO_PRO
442 #include "pro/VuoCompiler_Pro.hh"
443 #endif
444 };
445 
453 {
454 public:
458  VuoCompilerDelegate(void);
459 
485  virtual void loadedModules(const map<string, VuoCompilerModule *> &modulesAdded,
486  const map<string, pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
487  const map<string, VuoCompilerModule *> &modulesRemoved, VuoCompilerIssues *issues) = 0;
488 
498  void loadedModulesCompleted(void);
499 
500 private:
501  class LoadedModulesData
502  {
503  public:
504  LoadedModulesData(const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
505  const set<VuoCompilerModule *> &modulesRemoved, VuoCompilerIssues *issues);
506  ~LoadedModulesData(void);
507  void retain(void);
508  void release(void);
509 
510  private:
511  int referenceCount;
512  dispatch_queue_t referenceCountQueue;
513  set< pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModified;
514  set<VuoCompilerModule *> modulesRemoved;
515  VuoCompilerIssues *issues;
516  };
517 
518  void enqueueData(LoadedModulesData *data);
519  LoadedModulesData * dequeueData(void);
520 
521  list<LoadedModulesData *> pendingData;
522  dispatch_queue_t pendingDataQueue;
523 
524  friend class VuoCompiler;
525 };