diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index 6991950ba..f934e7188 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -964,7 +964,8 @@ public: static CarlaPluginPtr newNative(const Initializer& init); static CarlaPluginPtr newBridge(const Initializer& init, - BinaryType btype, PluginType ptype, const char* bridgeBinary); + BinaryType btype, PluginType ptype, + const char* binaryArchName, const char* bridgeBinary); static CarlaPluginPtr newLADSPA(const Initializer& init, const LADSPA_RDF_Descriptor* rdfDescriptor); static CarlaPluginPtr newDSSI(const Initializer& init); diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 5413dcd50..1d9467c10 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -44,6 +44,10 @@ #include "water/xml/XmlDocument.h" #include "water/xml/XmlElement.h" +#if defined(CARLA_OS_MAC) && defined(CARLA_OS_64BIT) && defined(HAVE_LIBMAGIC) // && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) +# define ADAPT_FOR_APPLE_SILLICON +#endif + #include // FIXME Remove on 2.1 release @@ -560,12 +564,19 @@ bool CarlaEngine::addPlugin(const BinaryType btype, bridgeBinary.clear(); } + const bool canBeBridged = ptype != PLUGIN_INTERNAL + && ptype != PLUGIN_SF2 + && ptype != PLUGIN_SFZ + && ptype != PLUGIN_JACK; + // Prefer bridges for some specific plugins - const bool preferBridges = pData->options.preferPluginBridges; + bool preferBridges = pData->options.preferPluginBridges; + const char* needsArchBridge = nullptr; -#if 0 // ndef BUILD_BRIDGE - if (! preferBridges) +#ifndef BUILD_BRIDGE + if (canBeBridged && ! preferBridges) { +# if 0 if (ptype == PLUGIN_LV2 && label != nullptr) { if (std::strncmp(label, "http://calf.sourceforge.net/plugins/", 36) == 0 || @@ -575,19 +586,39 @@ bool CarlaEngine::addPlugin(const BinaryType btype, preferBridges = true; } } +# endif +# ifdef ADAPT_FOR_APPLE_SILLICON + // see if this binary needs bridging + if (ptype == PLUGIN_VST2) + { + if (const char* const vst2Binary = findBinaryInBundle(filename)) + { + const CarlaMagic magic; + if (const char* const output = magic.getFileDescription(vst2Binary)) + { +# ifdef __aarch64__ + if (std::strstr(output, "arm64") == nullptr && std::strstr(output, "x86_64") != nullptr) + needsArchBridge = "x86_64"; +# else + if (std::strstr(output, "x86_64") == nullptr && std::strstr(output, "arm64") != nullptr) + needsArchBridge = "arm64"; +# endif + } + } + } + else if (ptype == PLUGIN_VST3) + { + // TODO + } +# endif } #endif // ! BUILD_BRIDGE - const bool canBeBridged = ptype != PLUGIN_INTERNAL - && ptype != PLUGIN_SF2 - && ptype != PLUGIN_SFZ - && ptype != PLUGIN_JACK; - - if (canBeBridged && (btype != BINARY_NATIVE || (preferBridges && bridgeBinary.isNotEmpty()))) + if (canBeBridged && (needsArchBridge || btype != BINARY_NATIVE || (preferBridges && bridgeBinary.isNotEmpty()))) { if (bridgeBinary.isNotEmpty()) { - plugin = CarlaPlugin::newBridge(initializer, btype, ptype, bridgeBinary); + plugin = CarlaPlugin::newBridge(initializer, btype, ptype, needsArchBridge, bridgeBinary); } else { diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp index 1a9ca49f2..2501d65d2 100644 --- a/source/backend/plugin/CarlaPluginBridge.cpp +++ b/source/backend/plugin/CarlaPluginBridge.cpp @@ -91,7 +91,8 @@ public: : CarlaThread("CarlaPluginBridgeThread"), kEngine(engine), kPlugin(plugin), - fBinary(), + fBinaryArchName(), + fBridgeBinary(), fLabel(), fShmIds(), #ifndef CARLA_OS_WIN @@ -103,18 +104,20 @@ public: #ifndef CARLA_OS_WIN const char* const winePrefix, #endif - const char* const binary, + const char* const binaryArchName, + const char* const bridgeBinary, const char* const label, const char* const shmIds) noexcept { - CARLA_SAFE_ASSERT_RETURN(binary != nullptr && binary[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(bridgeBinary != nullptr && bridgeBinary[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',); CARLA_SAFE_ASSERT(! isThreadRunning()); #ifndef CARLA_OS_WIN fWinePrefix = winePrefix; #endif - fBinary = binary; + fBinaryArchName = binaryArchName; + fBridgeBinary = bridgeBinary; fShmIds = shmIds; if (label != nullptr) @@ -160,7 +163,7 @@ protected: #ifndef CARLA_OS_WIN // start with "wine" if needed - if (fBinary.endsWithIgnoreCase(".exe")) + if (fBridgeBinary.endsWithIgnoreCase(".exe")) { String wineCMD; @@ -168,7 +171,7 @@ protected: { wineCMD = options.wine.executable; - if (fBinary.endsWithIgnoreCase("64.exe") + if (fBridgeBinary.endsWithIgnoreCase("64.exe") && options.wine.executable[0] == CARLA_OS_SEP && File(wineCMD + "64").existsAsFile()) wineCMD += "64"; @@ -182,8 +185,18 @@ protected: } #endif - // binary - arguments.add(fBinary); +#ifdef CARLA_OS_MAC + // setup binary arch + if (fBinaryArchName.isNotEmpty()) + { + arguments.add("arch"); + arguments.add("-arch"); + arguments.add(fBinaryArchName); + } +#endif + + // bridge binary + arguments.add(fBridgeBinary); // plugin type arguments.add(getPluginTypeAsString(kPlugin->getType())); @@ -309,7 +322,7 @@ protected: #endif carla_stdout("Starting plugin bridge, command is:\n%s \"%s\" \"%s\" \"%s\" " P_INT64, - fBinary.toRawUTF8(), getPluginTypeAsString(kPlugin->getType()), filename.toRawUTF8(), fLabel.toRawUTF8(), kPlugin->getUniqueId()); + fBridgeBinary.toRawUTF8(), getPluginTypeAsString(kPlugin->getType()), filename.toRawUTF8(), fLabel.toRawUTF8(), kPlugin->getUniqueId()); started = fProcess->start(arguments); } @@ -361,7 +374,8 @@ private: CarlaEngine* const kEngine; CarlaPlugin* const kPlugin; - String fBinary; + String fBinaryArchName; + String fBridgeBinary; String fLabel; String fShmIds; #ifndef CARLA_OS_WIN @@ -2543,6 +2557,7 @@ public: const char* const label, const int64_t uniqueId, const uint options, + const char* const binaryArchName, const char* const bridgeBinary) { CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); @@ -2652,7 +2667,7 @@ public: #ifndef CARLA_OS_WIN fWinePrefix.toRawUTF8(), #endif - bridgeBinary, label, shmIdsStr); + binaryArchName, bridgeBinary, label, shmIdsStr); } if (! restartBridgeThread()) @@ -3136,11 +3151,14 @@ CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_START_NAMESPACE CarlaPluginPtr CarlaPlugin::newBridge(const Initializer& init, - BinaryType btype, PluginType ptype, const char* bridgeBinary) + const BinaryType btype, + const PluginType ptype, + const char* const binaryArchName, + const char* bridgeBinary) { - carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", + carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label, - BinaryType2Str(btype), PluginType2Str(ptype), bridgeBinary); + BinaryType2Str(btype), PluginType2Str(ptype), binaryArchName, bridgeBinary); if (bridgeBinary == nullptr || bridgeBinary[0] == '\0') { @@ -3156,7 +3174,7 @@ CarlaPluginPtr CarlaPlugin::newBridge(const Initializer& init, std::shared_ptr plugin(new CarlaPluginBridge(init.engine, init.id, btype, ptype)); - if (! plugin->init(plugin, init.filename, init.name, init.label, init.uniqueId, init.options, bridgeBinary)) + if (! plugin->init(plugin, init.filename, init.name, init.label, init.uniqueId, init.options, binaryArchName, bridgeBinary)) return nullptr; return plugin; diff --git a/source/utils/CarlaBinaryUtils.hpp b/source/utils/CarlaBinaryUtils.hpp index a29a53e59..1ce1131eb 100644 --- a/source/utils/CarlaBinaryUtils.hpp +++ b/source/utils/CarlaBinaryUtils.hpp @@ -112,9 +112,11 @@ BinaryType getBinaryTypeFromFile(const char* const filename) // We just assume what architectures are more important, and check for them first if (std::strstr(output, "x86_64") != nullptr) return BINARY_POSIX64; - if (std::strstr(output, "i386")) + if (std::strstr(output, "arm64") != nullptr) + return BINARY_POSIX64; + if (std::strstr(output, "i386") != nullptr) return BINARY_POSIX32; - if (std::strstr(output, "ppc")) + if (std::strstr(output, "ppc") != nullptr) return BINARY_OTHER; }