1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 By using JUCE, you agree to the terms of both the JUCE 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-licence 14 Privacy Policy: www.juce.com/juce-privacy-policy 15 16 Or: You may also use this code under the terms of the GPL v3 (see 17 www.gnu.org/licenses). 18 19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 21 DISCLAIMED. 22 23 ============================================================================== 24 */ 25 26 #pragma once 27 28 #include "jucer_LiveCodeBuilderDLL.h" 29 30 //============================================================================== 31 struct CompileEngineDLL : private DeletedAtShutdown 32 { CompileEngineDLLCompileEngineDLL33 CompileEngineDLL() 34 { 35 tryLoadDll(); 36 } 37 ~CompileEngineDLLCompileEngineDLL38 ~CompileEngineDLL() 39 { 40 shutdown(); 41 clearSingletonInstance(); 42 } 43 tryLoadDllCompileEngineDLL44 bool tryLoadDll() 45 { 46 // never load the dynamic lib multiple times 47 if (! isLoaded()) 48 { 49 auto f = findDLLFile(); 50 51 if (f != File() && dll.open (f.getLinkedTarget().getFullPathName())) 52 { 53 #define INIT_LIVE_DLL_FN(name, returnType, params) name = (name##_type) dll.getFunction (#name); 54 LIVE_DLL_FUNCTIONS (INIT_LIVE_DLL_FN); 55 #undef INIT_LIVE_DLL_FN 56 57 return true; 58 } 59 60 return false; 61 } 62 63 return true; 64 } 65 initialiseCompileEngineDLL66 void initialise (CrashCallbackFunction crashFn, QuitCallbackFunction quitFn, bool setupSignals) 67 { 68 if (isLoaded()) 69 projucer_initialise (crashFn, quitFn, setPropertyCallback, getPropertyCallback, setupSignals); 70 } 71 shutdownCompileEngineDLL72 void shutdown() 73 { 74 if (isLoaded()) 75 projucer_shutdown(); 76 } 77 isLoadedCompileEngineDLL78 bool isLoaded() const 79 { 80 #define CHECK_LIVE_DLL_FN(name, returnType, params) if (name == nullptr) return false; 81 LIVE_DLL_FUNCTIONS (CHECK_LIVE_DLL_FN); 82 #undef CHECK_LIVE_DLL_FN 83 84 return projucer_getVersion() == requiredVersion; 85 } 86 87 #define DECLARE_LIVE_DLL_FN(name, returnType, params) \ 88 typedef returnType (*name##_type) params; \ 89 name##_type name = nullptr; 90 LIVE_DLL_FUNCTIONSCompileEngineDLL91 LIVE_DLL_FUNCTIONS (DECLARE_LIVE_DLL_FN) 92 93 #undef DECLARE_LIVE_DLL_FN 94 95 static String getDLLName() 96 { 97 #if JUCE_MAC 98 return "JUCECompileEngine.dylib"; 99 #elif JUCE_LINUX || JUCE_BSD 100 return "JUCECompileEngine.so"; 101 #elif JUCE_WINDOWS 102 return "JUCECompileEngine.dll"; 103 #else 104 #error 105 return "JUCECompileEngine.so"; 106 #endif 107 } 108 getVersionedUserAppSupportFolderCompileEngineDLL109 static File getVersionedUserAppSupportFolder() 110 { 111 auto userAppData = File::getSpecialLocation (File::userApplicationDataDirectory); 112 113 #if JUCE_MAC 114 userAppData = userAppData.getChildFile ("Application Support"); 115 #endif 116 117 return userAppData.getChildFile ("Projucer").getChildFile (String ("CompileEngine-") + ProjectInfo::versionString); 118 } 119 120 JUCE_DECLARE_SINGLETON (CompileEngineDLL, false) 121 122 private: 123 DynamicLibrary dll; 124 125 enum { requiredVersion = 2 }; 126 findDLLFileCompileEngineDLL127 static File findDLLFile() 128 { 129 auto dllFile = File(); 130 131 if (tryFindDLLFileInAppFolder (dllFile)) 132 return dllFile; 133 134 #if JUCE_MAC 135 if (tryFindDLLFileInAppBundle(dllFile)) 136 return dllFile; 137 #endif 138 139 if (tryFindDLLFileInAppConfigFolder (dllFile)) 140 return dllFile; 141 142 return {}; 143 } 144 145 #if JUCE_MAC tryFindDLLFileInAppBundleCompileEngineDLL146 static bool tryFindDLLFileInAppBundle (File& outFile) 147 { 148 File currentAppFile (File::getSpecialLocation (File::currentApplicationFile)); 149 return tryFindDLLFileInFolder (currentAppFile.getChildFile ("Contents"), outFile); 150 } 151 #endif 152 tryFindDLLFileInAppFolderCompileEngineDLL153 static bool tryFindDLLFileInAppFolder (File& outFile) 154 { 155 auto currentAppFile = File::getSpecialLocation (File::currentApplicationFile); 156 return tryFindDLLFileInFolder (currentAppFile.getParentDirectory(), outFile); 157 } 158 tryFindDLLFileInAppConfigFolderCompileEngineDLL159 static bool tryFindDLLFileInAppConfigFolder (File& outFile) 160 { 161 auto userAppDataFolder = getVersionedUserAppSupportFolder(); 162 return tryFindDLLFileInFolder (userAppDataFolder, outFile); 163 } 164 tryFindDLLFileInFolderCompileEngineDLL165 static bool tryFindDLLFileInFolder(File folder, File& outFile) 166 { 167 auto file = folder.getChildFile (getDLLName()); 168 if (isDLLFile (file)) 169 { 170 outFile = file; 171 return true; 172 } 173 174 return false; 175 } 176 isDLLFileCompileEngineDLL177 static bool isDLLFile (const File& f) 178 { 179 return f.getFileName().equalsIgnoreCase (getDLLName()) && f.exists(); 180 } 181 setPropertyCallbackCompileEngineDLL182 static void setPropertyCallback (const char* key, const char* value) 183 { 184 auto keyStr = String (key); 185 if (keyStr.isNotEmpty()) 186 getGlobalProperties().setValue (key, value); 187 else 188 jassertfalse; 189 } 190 getPropertyCallbackCompileEngineDLL191 static void getPropertyCallback (const char* key, char* value, size_t size) 192 { 193 jassert (getGlobalProperties().getValue (key).getNumBytesAsUTF8() < size); 194 195 value[0] = 0; 196 getGlobalProperties().getValue (key).copyToUTF8 (value, size); 197 } 198 crashCallbackCompileEngineDLL199 static void crashCallback (const char*) {} quitCallbackCompileEngineDLL200 static void quitCallback() {} 201 }; 202