The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
5.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #include "projucer_LiveCodeBuilderDLL.h"
  18. struct CompileEngineDLL
  19. {
  20. CompileEngineDLL()
  21. {
  22. File f = findDLLFile();
  23. if (f != File() && dll.open (f.getLinkedTarget().getFullPathName()))
  24. {
  25. #define INIT_LIVE_DLL_FN(name, returnType, params) name = (name##_type) dll.getFunction (#name);
  26. LIVE_DLL_FUNCTIONS (INIT_LIVE_DLL_FN);
  27. #undef INIT_LIVE_DLL_FN
  28. }
  29. }
  30. ~CompileEngineDLL()
  31. {
  32. shutdown();
  33. }
  34. void initialise (CrashCallbackFunction crashFn, QuitCallbackFunction quitFn, bool setupSignals)
  35. {
  36. if (isLoaded())
  37. projucer_initialise (crashFn, quitFn, setPropertyCallback, getPropertyCallback, setupSignals);
  38. }
  39. void shutdown()
  40. {
  41. if (isLoaded())
  42. projucer_shutdown();
  43. }
  44. bool isLoaded() const
  45. {
  46. #define CHECK_LIVE_DLL_FN(name, returnType, params) if (name == nullptr) return false;
  47. LIVE_DLL_FUNCTIONS (CHECK_LIVE_DLL_FN);
  48. #undef CHECK_LIVE_DLL_FN
  49. return projucer_getVersion() == requiredVersion;
  50. }
  51. #define DECLARE_LIVE_DLL_FN(name, returnType, params) \
  52. typedef returnType (*name##_type) params; \
  53. name##_type name = nullptr;
  54. LIVE_DLL_FUNCTIONS (DECLARE_LIVE_DLL_FN);
  55. #undef DECLARE_LIVE_DLL_FN
  56. static String getDLLName()
  57. {
  58. #if JUCE_MAC
  59. return "JUCECompileEngine.dylib";
  60. #elif JUCE_LINUX
  61. return "JUCECompileEngine.so";
  62. #elif JUCE_WINDOWS
  63. return "JUCECompileEngine.dll";
  64. #else
  65. #error
  66. return "JUCECompileEngine.so";
  67. #endif
  68. }
  69. static bool isDLLFile (const File& f)
  70. {
  71. return f.getFileName().equalsIgnoreCase (getDLLName()) && f.exists();
  72. }
  73. static File findDLLFile()
  74. {
  75. File appFile = File::getSpecialLocation (File::currentApplicationFile);
  76. #if JUCE_MAC
  77. // Look in the app bundle..
  78. for (DirectoryIterator i (appFile, true, "*", File::findFilesAndDirectories); i.next();)
  79. if (isDLLFile (i.getFile()))
  80. return i.getFile();
  81. {
  82. // Try in Application Support..
  83. File f = File ("~/Library/Application Support/Projucer").getChildFile (getDLLName());
  84. if (isDLLFile (f))
  85. return f;
  86. f = File ("/Library/Application Support/Projucer").getChildFile (getDLLName());
  87. if (isDLLFile (f))
  88. return f;
  89. }
  90. #elif JUCE_WINDOWS
  91. {
  92. // Look in the application folder
  93. File f = appFile.getParentDirectory().getChildFile (getDLLName());
  94. if (isDLLFile (f))
  95. return f;
  96. }
  97. #elif JUCE_LINUX
  98. // TODO?
  99. #else
  100. #error
  101. #endif
  102. {
  103. // Look for a DLL in extras/Projucer/Builds
  104. File f = appFile.getParentDirectory();
  105. for (int i = 5; --i >= 0;)
  106. {
  107. if (f.getFileName().equalsIgnoreCase ("Builds")
  108. && f.getParentDirectory().getFileName().equalsIgnoreCase ("Projucer"))
  109. {
  110. f = f.getSiblingFile (getDLLName());
  111. if (isDLLFile (f))
  112. return f;
  113. break;
  114. }
  115. f = f.getParentDirectory();
  116. }
  117. }
  118. // See if there's one in the same folder as the app...
  119. File f = appFile.getSiblingFile (getDLLName());
  120. if (isDLLFile (f))
  121. return f;
  122. // Look in some common folders as a last resort..
  123. f = File::getSpecialLocation (File::userHomeDirectory).getChildFile (getDLLName());
  124. if (isDLLFile (f))
  125. return f;
  126. f = File::getSpecialLocation (File::userDocumentsDirectory).getChildFile (getDLLName());
  127. if (isDLLFile (f))
  128. return f;
  129. return File();
  130. }
  131. private:
  132. DynamicLibrary dll;
  133. enum { requiredVersion = 1 };
  134. static void setPropertyCallback (const char* key, const char* value)
  135. {
  136. if (String (key).isNotEmpty())
  137. getGlobalProperties().setValue (key, value);
  138. else
  139. jassertfalse;
  140. }
  141. static void getPropertyCallback (const char* key, char* value, size_t size)
  142. {
  143. jassert (getGlobalProperties().getValue (key).getNumBytesAsUTF8() < size);
  144. value[0] = 0;
  145. getGlobalProperties().getValue (key).copyToUTF8 (value, size);
  146. }
  147. };