1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

Projucer: (MSVC) Emit message on plugin install location and config error

This commit is contained in:
Oli 2025-03-26 16:09:39 +00:00
parent cb698566e8
commit 270063ac31

View file

@ -77,6 +77,8 @@ public:
MSVCScriptBuilder& deleteFile (const StringOrBuilder& path) MSVCScriptBuilder& deleteFile (const StringOrBuilder& path)
{ {
jassert (path.value.isQuotedString());
script << "del /s /q " << path.value; script << "del /s /q " << path.value;
script << newLine; script << newLine;
return *this; return *this;
@ -84,6 +86,8 @@ public:
MSVCScriptBuilder& mkdir (const StringOrBuilder& path) MSVCScriptBuilder& mkdir (const StringOrBuilder& path)
{ {
jassert (path.value.isQuotedString());
script << "mkdir " << path.value; script << "mkdir " << path.value;
script << newLine; script << newLine;
return *this; return *this;
@ -175,7 +179,8 @@ public:
MSVCScriptBuilder& append (const StringOrBuilder& string) MSVCScriptBuilder& append (const StringOrBuilder& string)
{ {
script << string.value << newLine; if (string.isNotEmpty())
script << string.value << newLine;
return *this; return *this;
} }
@ -1723,6 +1728,17 @@ public:
return aaxSdk.getChildFile ("Utilities").getChildFile ("PlugIn.ico"); return aaxSdk.getChildFile ("Utilities").getChildFile ("PlugIn.ico");
} }
static bool shouldPerformCopyStepForPlugin (Target::Type pluginType,
const MSVCBuildConfiguration& config,
Architecture arch)
{
if (! config.isPluginBinaryCopyStepEnabled())
return false;
const auto binaryLocationId = getPluginTypeInfo (pluginType).second;
return binaryLocationId.isValid() && config.getBinaryPath (binaryLocationId, arch).isNotEmpty();
}
String getExtraPostBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const String getExtraPostBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const
{ {
using Builder = MSVCScriptBuilder; using Builder = MSVCScriptBuilder;
@ -1742,7 +1758,7 @@ public:
+ " " + " "
+ (directory + "\\" + segments[0] + "\\").quoted(); + (directory + "\\" + segments[0] + "\\").quoted();
return config.isPluginBinaryCopyStepEnabled() ? copyStep : ""; return shouldPerformCopyStepForPlugin (type, config, arch) ? copyStep : "";
}; };
if (type == AAXPlugIn) if (type == AAXPlugIn)
@ -1778,7 +1794,7 @@ public:
auto pkgScript = String ("copy /Y ") + scriptPath.toWindowsStyle().quoted() + " \"$(OutDir)\""; auto pkgScript = String ("copy /Y ") + scriptPath.toWindowsStyle().quoted() + " \"$(OutDir)\"";
if (config.isPluginBinaryCopyStepEnabled()) if (shouldPerformCopyStepForPlugin (type, config, arch))
{ {
auto copyLocation = config.getBinaryPath (Ids::unityPluginBinaryLocation, arch); auto copyLocation = config.getBinaryPath (Ids::unityPluginBinaryLocation, arch);
@ -1813,7 +1829,9 @@ public:
+ ".lv2\"\r\n"; + ".lv2\"\r\n";
builder.runAndCheck (writer, builder.runAndCheck (writer,
config.isPluginBinaryCopyStepEnabled() ? copyStep : Builder{}.info ("Sucessfully generated LV2 manifest").build(), shouldPerformCopyStepForPlugin (type, config, arch)
? copyStep
: Builder{}.info ("Successfully generated LV2 manifest").build(),
Builder{}.error ("Failed to generate LV2 manifest.") Builder{}.error ("Failed to generate LV2 manifest.")
.exit (-1)); .exit (-1));
@ -1923,7 +1941,7 @@ public:
.build(); .build();
} }
if (type == VSTPlugIn && config.isPluginBinaryCopyStepEnabled()) if (type == VSTPlugIn && shouldPerformCopyStepForPlugin (type, config, arch))
{ {
const String copyCommand = "copy /Y \"$(OutDir)$(TargetFileName)\" \"" const String copyCommand = "copy /Y \"$(OutDir)$(TargetFileName)\" \""
+ config.getBinaryPath (Ids::vstBinaryLocation, arch) + config.getBinaryPath (Ids::vstBinaryLocation, arch)
@ -1938,6 +1956,114 @@ public:
return {}; return {};
} }
static std::pair<String, Identifier> getPluginTypeInfo (Target::Type targetType)
{
if (targetType == AAXPlugIn) return { "AAX", Ids::aaxBinaryLocation };
if (targetType == VSTPlugIn) return { "VST (Legacy)", Ids::vstBinaryLocation };
if (targetType == VST3PlugIn) return { "VST3", Ids::vst3BinaryLocation };
if (targetType == UnityPlugIn) return { "Unity", Ids::unityPluginBinaryLocation };
if (targetType == LV2PlugIn) return { "LV2", Ids::lv2BinaryLocation };
return {};
}
static String generatePluginCopyStepPathValidatorScript (Target::Type targetType,
const MSVCBuildConfiguration& config,
Architecture arch)
{
MSVCScriptBuilder builder;
if (config.isPluginBinaryCopyStepEnabled())
{
const auto [projectTypeString, binaryLocationId] = getPluginTypeInfo (targetType);
if (projectTypeString.isNotEmpty())
{
const auto binaryPath = config.getBinaryPath (binaryLocationId, arch);
if (binaryPath.isEmpty())
{
String warningMessage =
"Plugin Configuration Warning: Plugin copy step is enabled but no target "
"path is specified in the Projucer.";
warningMessage << " This can be configured via the \""
<< getArchitectureValueString (arch) << " "
<< projectTypeString << " "
<< "Binary Location\" option in the relevant Exporter configuration panel.";
builder.warning (warningMessage.quoted());
}
else
{
constexpr auto errorMessage =
"Plugin Copy Step Failure: Either the install path does not exist or you "
"do not have permission to write to the target directory. Ensure you "
"have the necessary permissions to write to the directory, or choose "
"a different install location (e.g., a folder in your user directory).";
MemoryOutputStream script;
const auto validProjectName = build_tools::makeValidIdentifier (config.project.getProjectNameString(),
false,
true,
false,
false);
const auto validPluginName = build_tools::makeValidIdentifier (projectTypeString,
false,
true,
false,
false);
script << "set TOUCH_NAME=\".touch_\""
<< validProjectName << "_"
<< validPluginName << "_"
<< "\"%RANDOM%\"" << newLine;
String tempPath = binaryPath;
tempPath << "\\%TOUCH_NAME%";
script << "(" << newLine;
script << "echo \".\" > " << tempPath.quoted() << newLine;
script << ") > nul 2>&1" << newLine;
builder.append (script.toString());
builder.ifelse ("exist " + tempPath.quoted(),
MSVCScriptBuilder{}.deleteFile (tempPath.quoted()),
MSVCScriptBuilder{}.error (String { errorMessage }.quoted())
.exit (1));
}
}
}
return builder.build();
}
static String generateToolchainValidatorScript (Architecture arch)
{
MSVCScriptBuilder builder;
if (arch == Architecture::win64)
{
const auto x86ToolchainErrorMessage =
"echo : Warning: Toolchain configuration issue!"
" You are using a 32-bit toolchain to compile a 64-bit target on a 64-bit system."
" This may cause problems with the build system."
" To resolve this, use the x64 version of MSBuild. You can invoke it directly at:"
" \"<VisualStudioPathHere>/MSBuild/Current/Bin/amd64/MSBuild.exe\""
" Or, use the \"x64 Native Tools Command Prompt\" script.";
builder.ifAllConditionsTrue (
{
"\"$(PROCESSOR_ARCHITECTURE)\" == " + getVisualStudioArchitectureId (Architecture::win32).quoted(),
// This only exists if the process is x86 but the host is x64.
"defined PROCESSOR_ARCHITEW6432"
}, MSVCScriptBuilder{}.append (x86ToolchainErrorMessage));
}
return builder.build();
}
String getExtraPreBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const String getExtraPreBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const
{ {
const auto createBundleStructure = [&] (const StringArray& segments) const auto createBundleStructure = [&] (const StringArray& segments)
@ -1959,24 +2085,8 @@ public:
MSVCScriptBuilder builder; MSVCScriptBuilder builder;
if (arch == Architecture::win64) builder.append (generatePluginCopyStepPathValidatorScript (type, config, arch));
{ builder.append (generateToolchainValidatorScript (arch));
const auto x86ToolchainErrorMessage =
"echo : Warning: Toolchain configuration issue!"
" You are using a 32-bit toolchain to compile a 64-bit target on a 64-bit system."
" This may cause problems with the build system."
" To resolve this, use the x64 version of MSBuild. You can invoke it directly at:"
" \"<VisualStudioPathHere>/MSBuild/Current/Bin/amd64/MSBuild.exe\""
" Or, use the \"x64 Native Tools Command Prompt\" script.";
builder.ifAllConditionsTrue (
{
"\"$(PROCESSOR_ARCHITECTURE)\" == " + getVisualStudioArchitectureId (Architecture::win32).quoted(),
// This only exists if the process is x86 but the host is x64.
"defined PROCESSOR_ARCHITEW6432"
}, MSVCScriptBuilder{}.append (x86ToolchainErrorMessage));
}
if (type == LV2PlugIn) if (type == LV2PlugIn)
{ {
@ -2010,8 +2120,14 @@ public:
return builder.build(); return builder.build();
} }
if (type == UnityPlugIn)
return builder.build();
if (type == AAXPlugIn) if (type == AAXPlugIn)
return createBundleStructure (getAaxBundleStructure (config, arch)); return builder.build() + "\r\n" + createBundleStructure (getAaxBundleStructure (config, arch));
if (type == VSTPlugIn)
return builder.build();
if (type == VST3PlugIn) if (type == VST3PlugIn)
return builder.build() + "\r\n" + createBundleStructure (getVst3BundleStructure (config, arch)); return builder.build() + "\r\n" + createBundleStructure (getVst3BundleStructure (config, arch));