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
=====================
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
=============

View file

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

View file

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