DistrhoPluginExport.cpp (10874B)
1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any purpose with 6 * or without fee is hereby granted, provided that the above copyright notice and this 7 * permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD 10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN 11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "DistrhoPluginInternal.hpp" 18 #include "../DistrhoPluginUtils.hpp" 19 20 #ifndef DISTRHO_PLUGIN_BRAND_ID 21 # error DISTRHO_PLUGIN_BRAND_ID undefined! 22 #endif 23 24 #ifndef DISTRHO_PLUGIN_UNIQUE_ID 25 # error DISTRHO_PLUGIN_UNIQUE_ID undefined! 26 #endif 27 28 #include <fstream> 29 #include <iostream> 30 31 USE_NAMESPACE_DISTRHO 32 33 // -------------------------------------------------------------------------------------------------------------------- 34 35 void generate_au_plist(const PluginExporter& plugin, 36 const char* const basename, 37 const char* const license) 38 { 39 std::cout << "Writing Info.plist..."; std::cout.flush(); 40 std::fstream outputFile("Info.plist", std::ios::out); 41 42 const uint32_t version = plugin.getVersion(); 43 44 const uint32_t majorVersion = (version & 0xFF0000) >> 16; 45 const uint32_t minorVersion = (version & 0x00FF00) >> 8; 46 const uint32_t microVersion = (version & 0x0000FF) >> 0; 47 48 outputFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 49 outputFile << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"; 50 outputFile << "<plist>\n"; 51 outputFile << " <dict>\n"; 52 outputFile << " <key>CFBundleExecutable</key>\n"; 53 outputFile << " <string>" << basename << "</string>\n"; 54 outputFile << " <key>CFBundleIconFile</key>\n"; 55 outputFile << " <string></string>\n"; 56 outputFile << " <key>CFBundleIdentifier</key>\n"; 57 outputFile << " <string>" DISTRHO_PLUGIN_CLAP_ID "</string>\n"; 58 outputFile << " <key>CFBundleName</key>\n"; 59 outputFile << " <string>" << basename << "</string>\n"; 60 outputFile << " <key>CFBundleDisplayName</key>\n"; 61 outputFile << " <string>" << plugin.getName() << "</string>\n"; 62 outputFile << " <key>CFBundlePackageType</key>\n"; 63 outputFile << " <string>BNDL</string>\n"; 64 outputFile << " <key>CFBundleSignature</key>\n"; 65 outputFile << " <string>" << "????" << "</string>\n"; 66 outputFile << " <key>CFBundleShortVersionString</key>\n"; 67 outputFile << " <string>" << majorVersion << "." << minorVersion << "." << microVersion << "</string>\n"; 68 outputFile << " <key>CFBundleVersion</key>\n"; 69 outputFile << " <string>" << majorVersion << "." << minorVersion << "." << microVersion << "</string>\n"; 70 if (license != nullptr && license[0] != '\0') 71 { 72 outputFile << " <key>NSHumanReadableCopyright</key>\n"; 73 outputFile << " <string>" << license << "</string>\n"; 74 } 75 outputFile << " <key>NSHighResolutionCapable</key>\n"; 76 outputFile << " <true/>\n"; 77 outputFile << " <key>AudioComponents</key>\n"; 78 outputFile << " <array>\n"; 79 outputFile << " <dict>\n"; 80 outputFile << " <key>name</key>\n"; 81 outputFile << " <string>" << plugin.getMaker() << ": " << plugin.getName() << "</string>\n"; 82 outputFile << " <key>description</key>\n"; 83 outputFile << " <string>" << plugin.getDescription() << "</string>\n"; 84 outputFile << " <key>factoryFunction</key>\n"; 85 outputFile << " <string>PluginAUFactory</string>\n"; 86 outputFile << " <key>type</key>\n"; 87 outputFile << " <string>" STRINGIFY(DISTRHO_PLUGIN_AU_TYPE) "</string>\n"; 88 outputFile << " <key>subtype</key>\n"; 89 outputFile << " <string>" STRINGIFY(DISTRHO_PLUGIN_UNIQUE_ID) "</string>\n"; 90 outputFile << " <key>manufacturer</key>\n"; 91 outputFile << " <string>" STRINGIFY(DISTRHO_PLUGIN_BRAND_ID) "</string>\n"; 92 outputFile << " <key>version</key>\n"; 93 outputFile << " <integer>" << version << "</integer>\n"; 94 outputFile << " <key>resourceUsage</key>\n"; 95 outputFile << " <dict>\n"; 96 outputFile << " <key>network.client</key>\n"; 97 outputFile << " <true/>\n"; 98 outputFile << " <key>temporary-exception.files.all.read-write</key>\n"; 99 outputFile << " <true/>\n"; 100 outputFile << " </dict>\n"; 101 outputFile << " </dict>\n"; 102 outputFile << " </array>\n"; 103 outputFile << " </dict>\n"; 104 outputFile << "</plist>\n"; 105 106 outputFile.close(); 107 std::cout << " done!" << std::endl; 108 } 109 110 // -------------------------------------------------------------------------------------------------------------------- 111 112 int main(int argc, char* argv[]) 113 { 114 if (argc <= 1) 115 return 1; 116 117 // Dummy plugin to get data from 118 d_nextBufferSize = 512; 119 d_nextSampleRate = 44100.0; 120 d_nextPluginIsDummy = true; 121 PluginExporter plugin(nullptr, nullptr, nullptr, nullptr); 122 d_nextBufferSize = 0; 123 d_nextSampleRate = 0.0; 124 d_nextPluginIsDummy = false; 125 126 String license(plugin.getLicense()); 127 128 if (license.isEmpty()) 129 {} 130 // License as URL, use as-is 131 else if (license.contains("://")) 132 {} 133 // License contains quotes, use as-is 134 else if (license.contains('"')) 135 {} 136 // Regular license string, convert to URL as much as we can 137 else 138 { 139 const String uplicense(license.asUpper()); 140 141 // for reference, see https://spdx.org/licenses/ 142 143 // common licenses 144 /**/ if (uplicense == "AGPL-1.0-ONLY" || 145 uplicense == "AGPL1" || 146 uplicense == "AGPLV1") 147 { 148 license = "http://spdx.org/licenses/AGPL-1.0-only.html"; 149 } 150 else if (uplicense == "AGPL-1.0-OR-LATER" || 151 uplicense == "AGPL1+" || 152 uplicense == "AGPLV1+") 153 { 154 license = "http://spdx.org/licenses/AGPL-1.0-or-later.html"; 155 } 156 else if (uplicense == "AGPL-3.0-ONLY" || 157 uplicense == "AGPL3" || 158 uplicense == "AGPLV3") 159 { 160 license = "http://spdx.org/licenses/AGPL-3.0-only.html"; 161 } 162 else if (uplicense == "AGPL-3.0-OR-LATER" || 163 uplicense == "AGPL3+" || 164 uplicense == "AGPLV3+") 165 { 166 license = "http://spdx.org/licenses/AGPL-3.0-or-later.html"; 167 } 168 else if (uplicense == "APACHE-2.0" || 169 uplicense == "APACHE2" || 170 uplicense == "APACHE-2") 171 { 172 license = "http://spdx.org/licenses/Apache-2.0.html"; 173 } 174 else if (uplicense == "BSD-2-CLAUSE" || 175 uplicense == "BSD2" || 176 uplicense == "BSD-2") 177 { 178 license = "http://spdx.org/licenses/BSD-2-Clause.html"; 179 } 180 else if (uplicense == "BSD-3-CLAUSE" || 181 uplicense == "BSD3" || 182 uplicense == "BSD-3") 183 { 184 license = "http://spdx.org/licenses/BSD-3-Clause.html"; 185 } 186 else if (uplicense == "GPL-2.0-ONLY" || 187 uplicense == "GPL2" || 188 uplicense == "GPLV2") 189 { 190 license = "http://spdx.org/licenses/GPL-2.0-only.html"; 191 } 192 else if (uplicense == "GPL-2.0-OR-LATER" || 193 uplicense == "GPL2+" || 194 uplicense == "GPLV2+" || 195 uplicense == "GPLV2.0+" || 196 uplicense == "GPL V2+") 197 { 198 license = "http://spdx.org/licenses/GPL-2.0-or-later.html"; 199 } 200 else if (uplicense == "GPL-3.0-ONLY" || 201 uplicense == "GPL3" || 202 uplicense == "GPLV3") 203 { 204 license = "http://spdx.org/licenses/GPL-3.0-only.html"; 205 } 206 else if (uplicense == "GPL-3.0-OR-LATER" || 207 uplicense == "GPL3+" || 208 uplicense == "GPLV3+" || 209 uplicense == "GPLV3.0+" || 210 uplicense == "GPL V3+") 211 { 212 license = "http://spdx.org/licenses/GPL-3.0-or-later.html"; 213 } 214 else if (uplicense == "ISC") 215 { 216 license = "http://spdx.org/licenses/ISC.html"; 217 } 218 else if (uplicense == "LGPL-2.0-ONLY" || 219 uplicense == "LGPL2" || 220 uplicense == "LGPLV2") 221 { 222 license = "http://spdx.org/licenses/LGPL-2.0-only.html"; 223 } 224 else if (uplicense == "LGPL-2.0-OR-LATER" || 225 uplicense == "LGPL2+" || 226 uplicense == "LGPLV2+") 227 { 228 license = "http://spdx.org/licenses/LGPL-2.0-or-later.html"; 229 } 230 else if (uplicense == "LGPL-2.1-ONLY" || 231 uplicense == "LGPL2.1" || 232 uplicense == "LGPLV2.1") 233 { 234 license = "http://spdx.org/licenses/LGPL-2.1-only.html"; 235 } 236 else if (uplicense == "LGPL-2.1-OR-LATER" || 237 uplicense == "LGPL2.1+" || 238 uplicense == "LGPLV2.1+") 239 { 240 license = "http://spdx.org/licenses/LGPL-2.1-or-later.html"; 241 } 242 else if (uplicense == "LGPL-3.0-ONLY" || 243 uplicense == "LGPL3" || 244 uplicense == "LGPLV3") 245 { 246 license = "http://spdx.org/licenses/LGPL-2.0-only.html"; 247 } 248 else if (uplicense == "LGPL-3.0-OR-LATER" || 249 uplicense == "LGPL3+" || 250 uplicense == "LGPLV3+") 251 { 252 license = "http://spdx.org/licenses/LGPL-3.0-or-later.html"; 253 } 254 else if (uplicense == "MIT") 255 { 256 license = "http://spdx.org/licenses/MIT.html"; 257 } 258 259 // generic fallbacks 260 else if (uplicense.startsWith("GPL")) 261 { 262 license = "http://opensource.org/licenses/gpl-license"; 263 } 264 else if (uplicense.startsWith("LGPL")) 265 { 266 license = "http://opensource.org/licenses/lgpl-license"; 267 } 268 269 // unknown or not handled yet, log a warning 270 else 271 { 272 d_stderr("Unknown license string '%s'", license.buffer()); 273 } 274 } 275 276 generate_au_plist(plugin, argv[1], license); 277 278 return 0; 279 } 280 281 // --------------------------------------------------------------------------------------------------------------------