1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Projucer: Build VST3 bundles from the MSVC exporters

This commit is contained in:
reuk 2023-01-10 14:10:52 +00:00
parent 69795dc8e5
commit 65305b1afe
No known key found for this signature in database
GPG key ID: 9ADCD339CFC98A11
3 changed files with 115 additions and 41 deletions

View file

@ -1,6 +1,32 @@
JUCE breaking changes JUCE breaking changes
===================== =====================
develop
=======
Change
------
Projucer-generated MSVC projects now build VST3s as bundles, rather than as
single DLL files.
Possible Issues
---------------
Build workflows that expect the VST3 to be a single DLL may break.
Workaround
----------
Any post-build scripts that expect to copy or move the built VST3 should be
updated so that the entire bundle directory is copied/moved. The DLL itself
can still be located and extracted from within the generated bundle if
necessary.
Rationale
---------
Distributing VST3s as single files was deprecated in VST3 v3.6.10. JUCE's CMake
scripts already produce VST3s as bundles, so this change increases consistency
between the two build systems.
Version 7.0.3 Version 7.0.3
============= =============

View file

@ -225,9 +225,9 @@ private:
if (archFlag.startsWith (prefix)) if (archFlag.startsWith (prefix))
return archFlag.substring (prefix.length()); return archFlag.substring (prefix.length());
else if (archFlag == "-m64") if (archFlag == "-m64")
return "x86_64"; return "x86_64";
else if (archFlag == "-m32") if (archFlag == "-m32")
return "i386"; return "i386";
jassertfalse; jassertfalse;

View file

@ -1105,7 +1105,7 @@ public:
.toWindowsStyle()); .toWindowsStyle());
} }
String getConfigTargetPath (const BuildConfiguration& config) const String getConfigTargetPath (const MSVCBuildConfiguration& config) const
{ {
const auto result = getSolutionTargetPath (config) + "\\" + getName(); const auto result = getSolutionTargetPath (config) + "\\" + getName();
@ -1147,7 +1147,6 @@ public:
if (fileType == pluginBundle) if (fileType == pluginBundle)
{ {
if (type == VST3PlugIn) return ".vst3";
if (type == AAXPlugIn) return ".aaxdll"; if (type == AAXPlugIn) return ".aaxdll";
return ".dll"; return ".dll";
@ -1209,27 +1208,47 @@ public:
String getExtraPostBuildSteps (const MSVCBuildConfiguration& config) const String getExtraPostBuildSteps (const MSVCBuildConfiguration& config) const
{ {
const auto copyBuildOutputIntoBundle = [&] (const StringArray& segments)
{
return "copy /Y "
+ getOutputFilePath (config).quoted()
+ " "
+ getOwner().getOutDirFile (config, segments.joinIntoString ("\\")).quoted();
};
const auto copyBundleToInstallDirectory = [&] (const StringArray& segments, const String& directory)
{
const auto copyStep = "\r\nxcopy /E /H /K /R /Y /I "
+ getOwner().getOutDirFile (config, segments[0]).quoted()
+ " "
+ (directory + "\\" + segments[0] + "\\").quoted();
return config.isPluginBinaryCopyStepEnabled() ? copyStep : "";
};
if (type == AAXPlugIn) if (type == AAXPlugIn)
{ {
build_tools::RelativePath aaxSDK (owner.getAAXPathString(), build_tools::RelativePath::projectFolder); const build_tools::RelativePath aaxSDK (owner.getAAXPathString(), build_tools::RelativePath::projectFolder);
build_tools::RelativePath aaxLibsFolder = aaxSDK.getChildFile ("Libs"); const build_tools::RelativePath aaxLibsFolder = aaxSDK.getChildFile ("Libs");
build_tools::RelativePath bundleScript = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat"); const build_tools::RelativePath bundleScript = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat");
build_tools::RelativePath iconFilePath = getAAXIconFile(); const build_tools::RelativePath iconFilePath = getAAXIconFile();
auto outputFilename = config.getOutputFilename (".aaxplugin", true, type); const auto segments = getAaxBundleStructure (config);
auto bundleDir = getOwner().getOutDirFile (config, outputFilename);
auto bundleContents = bundleDir + "\\Contents";
auto archDir = bundleContents + String ("\\") + config.getArchitectureString();
auto executablePath = archDir + String ("\\") + outputFilename;
auto pkgScript = String ("copy /Y ") + getOutputFilePath (config).quoted() + String (" ") + executablePath.quoted() + String ("\r\ncall ") const auto pkgScript = copyBuildOutputIntoBundle (segments);
+ createRebasedPath (bundleScript) + String (" ") + archDir.quoted() + String (" ") + createRebasedPath (iconFilePath);
if (config.isPluginBinaryCopyStepEnabled()) const auto archDir = StringArray (segments.strings.data(), segments.size() - 1).joinIntoString ("\\");
return pkgScript + "\r\n" + "xcopy " + bundleDir.quoted() + " " const auto rebasedArchDir = getOwner().getOutDirFile (config, archDir);
+ String (config.getAAXBinaryLocationString() + "\\" + outputFilename + "\\").quoted() + " /E /H /K /R /Y"; const auto fixScript = "\r\ncall "
+ createRebasedPath (bundleScript)
+ " "
+ rebasedArchDir.quoted()
+ String (" ")
+ createRebasedPath (iconFilePath);
return pkgScript; const auto copyScript = copyBundleToInstallDirectory (segments, config.getAAXBinaryLocationString());
return pkgScript + fixScript + copyScript;
} }
if (type == UnityPlugIn) if (type == UnityPlugIn)
@ -1266,44 +1285,53 @@ public:
+ "\\" + "\\"
+ writerTarget->getBinaryNameWithSuffix (config); + writerTarget->getBinaryNameWithSuffix (config);
const auto copyScript = [&]() -> String const auto copyStep = "xcopy /E /H /I /K /R /Y \"$(OutDir)\" \""
{ + config.getLV2BinaryLocationString()
if (! config.isPluginBinaryCopyStepEnabled()) + '\\'
return ""; + config.getTargetBinaryNameString()
+ ".lv2\"\r\n";
return "xcopy /E /H /I /K /R /Y \"$(OutDir)\" \"" + config.getLV2BinaryLocationString() return writer.quoted()
+ '\\' + config.getTargetBinaryNameString() + ".lv2\"\r\n"; + " \"$(OutDir)$(TargetFileName)\"\r\n"
}(); + (config.isPluginBinaryCopyStepEnabled() ? copyStep : "");
return writer.quoted() + " \"$(OutDir)$(TargetFileName)\"\r\n" + copyScript;
} }
if (config.isPluginBinaryCopyStepEnabled()) if (type == VST3PlugIn)
{ {
auto copyScript = String ("copy /Y \"$(OutDir)$(TargetFileName)\"") + String (" \"$COPYDIR$\\$(TargetFileName)\""); const auto segments = getVst3BundleStructure (config);
const auto pkgScript = copyBuildOutputIntoBundle (segments);
const auto copyScript = copyBundleToInstallDirectory (segments, config.getVST3BinaryLocationString());
if (type == VSTPlugIn) return copyScript.replace ("$COPYDIR$", config.getVSTBinaryLocationString()); return pkgScript + copyScript;
if (type == VST3PlugIn) return copyScript.replace ("$COPYDIR$", config.getVST3BinaryLocationString());
} }
if (type == VSTPlugIn && config.isPluginBinaryCopyStepEnabled())
return "copy /Y \"$(OutDir)$(TargetFileName)\" \"" + config.getVSTBinaryLocationString() + "\\$(TargetFileName)\"";
return {}; return {};
} }
String getExtraPreBuildSteps (const MSVCBuildConfiguration& config) const String getExtraPreBuildSteps (const MSVCBuildConfiguration& config) const
{ {
if (type == AAXPlugIn) const auto createBundleStructure = [&] (const StringArray& segments)
{ {
auto directory = getOwner().getOutDirFile (config, "");
String script; String script;
auto bundleDir = getOwner().getOutDirFile (config, config.getOutputFilename (".aaxplugin", false, type)); std::for_each (segments.begin(), std::prev (segments.end()), [&] (const auto& s)
auto bundleContents = bundleDir + "\\Contents"; {
auto archDir = bundleContents + String ("\\") + config.getArchitectureString(); directory += (directory.isEmpty() ? "" : "\\") + s;
script += "if not exist \"" + directory + "\" mkdir \"" + directory + "\"\r\n";
for (auto& folder : StringArray { bundleDir, bundleContents, archDir }) });
script += String ("if not exist \"") + folder + String ("\" mkdir \"") + folder + String ("\"\r\n");
return script; return script;
} };
if (type == AAXPlugIn)
return createBundleStructure (getAaxBundleStructure (config));
if (type == VST3PlugIn)
return createBundleStructure (getVst3BundleStructure (config));
return {}; return {};
} }
@ -1343,7 +1371,7 @@ public:
return getOwner().getOutDirFile (config, getBinaryNameWithSuffix (config)); return getOwner().getOutDirFile (config, getBinaryNameWithSuffix (config));
} }
StringArray getLibrarySearchPaths (const BuildConfiguration& config) const StringArray getLibrarySearchPaths (const MSVCBuildConfiguration& config) const
{ {
auto librarySearchPaths = config.getLibrarySearchPaths(); auto librarySearchPaths = config.getLibrarySearchPaths();
@ -1410,6 +1438,26 @@ public:
} }
protected: protected:
StringArray getAaxBundleStructure (const MSVCBuildConfiguration& config) const
{
const auto dllName = config.getOutputFilename (".aaxplugin", false, type);
return { dllName, "Contents", config.getArchitectureString(), dllName };
}
StringArray getVst3BundleStructure (const MSVCBuildConfiguration& config) const
{
static const std::map<String, String> suffixes
{
{ "Win32", "x86" },
{ "x64", "x86_64" },
};
const auto iter = suffixes.find (config.getArchitectureString());
const auto dllName = config.getOutputFilename (".vst3", false, type);
return { dllName, "Contents", iter != suffixes.cend() ? iter->second + "-win" : "win", dllName };
}
const MSVCProjectExporterBase& owner; const MSVCProjectExporterBase& owner;
String projectGuid; String projectGuid;
}; };