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:
parent
69795dc8e5
commit
65305b1afe
3 changed files with 115 additions and 41 deletions
|
|
@ -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
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue