Skip to content

Commit 270063a

Browse files
committed
Projucer: (MSVC) Emit message on plugin install location and config error
1 parent cb69856 commit 270063a

File tree

1 file changed

+134
-18
lines changed

1 file changed

+134
-18
lines changed

extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h

Lines changed: 134 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,17 @@ class MSVCScriptBuilder
7777

7878
MSVCScriptBuilder& deleteFile (const StringOrBuilder& path)
7979
{
80+
jassert (path.value.isQuotedString());
81+
8082
script << "del /s /q " << path.value;
8183
script << newLine;
8284
return *this;
8385
}
8486

8587
MSVCScriptBuilder& mkdir (const StringOrBuilder& path)
8688
{
89+
jassert (path.value.isQuotedString());
90+
8791
script << "mkdir " << path.value;
8892
script << newLine;
8993
return *this;
@@ -175,7 +179,8 @@ class MSVCScriptBuilder
175179

176180
MSVCScriptBuilder& append (const StringOrBuilder& string)
177181
{
178-
script << string.value << newLine;
182+
if (string.isNotEmpty())
183+
script << string.value << newLine;
179184
return *this;
180185
}
181186

@@ -1723,6 +1728,17 @@ class MSVCProjectExporterBase : public ProjectExporter
17231728
return aaxSdk.getChildFile ("Utilities").getChildFile ("PlugIn.ico");
17241729
}
17251730

1731+
static bool shouldPerformCopyStepForPlugin (Target::Type pluginType,
1732+
const MSVCBuildConfiguration& config,
1733+
Architecture arch)
1734+
{
1735+
if (! config.isPluginBinaryCopyStepEnabled())
1736+
return false;
1737+
1738+
const auto binaryLocationId = getPluginTypeInfo (pluginType).second;
1739+
return binaryLocationId.isValid() && config.getBinaryPath (binaryLocationId, arch).isNotEmpty();
1740+
}
1741+
17261742
String getExtraPostBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const
17271743
{
17281744
using Builder = MSVCScriptBuilder;
@@ -1742,7 +1758,7 @@ class MSVCProjectExporterBase : public ProjectExporter
17421758
+ " "
17431759
+ (directory + "\\" + segments[0] + "\\").quoted();
17441760

1745-
return config.isPluginBinaryCopyStepEnabled() ? copyStep : "";
1761+
return shouldPerformCopyStepForPlugin (type, config, arch) ? copyStep : "";
17461762
};
17471763

17481764
if (type == AAXPlugIn)
@@ -1778,7 +1794,7 @@ class MSVCProjectExporterBase : public ProjectExporter
17781794

17791795
auto pkgScript = String ("copy /Y ") + scriptPath.toWindowsStyle().quoted() + " \"$(OutDir)\"";
17801796

1781-
if (config.isPluginBinaryCopyStepEnabled())
1797+
if (shouldPerformCopyStepForPlugin (type, config, arch))
17821798
{
17831799
auto copyLocation = config.getBinaryPath (Ids::unityPluginBinaryLocation, arch);
17841800

@@ -1813,7 +1829,9 @@ class MSVCProjectExporterBase : public ProjectExporter
18131829
+ ".lv2\"\r\n";
18141830

18151831
builder.runAndCheck (writer,
1816-
config.isPluginBinaryCopyStepEnabled() ? copyStep : Builder{}.info ("Sucessfully generated LV2 manifest").build(),
1832+
shouldPerformCopyStepForPlugin (type, config, arch)
1833+
? copyStep
1834+
: Builder{}.info ("Successfully generated LV2 manifest").build(),
18171835
Builder{}.error ("Failed to generate LV2 manifest.")
18181836
.exit (-1));
18191837

@@ -1923,7 +1941,7 @@ class MSVCProjectExporterBase : public ProjectExporter
19231941
.build();
19241942
}
19251943

1926-
if (type == VSTPlugIn && config.isPluginBinaryCopyStepEnabled())
1944+
if (type == VSTPlugIn && shouldPerformCopyStepForPlugin (type, config, arch))
19271945
{
19281946
const String copyCommand = "copy /Y \"$(OutDir)$(TargetFileName)\" \""
19291947
+ config.getBinaryPath (Ids::vstBinaryLocation, arch)
@@ -1938,25 +1956,90 @@ class MSVCProjectExporterBase : public ProjectExporter
19381956
return {};
19391957
}
19401958

1941-
String getExtraPreBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const
1959+
static std::pair<String, Identifier> getPluginTypeInfo (Target::Type targetType)
19421960
{
1943-
const auto createBundleStructure = [&] (const StringArray& segments)
1961+
if (targetType == AAXPlugIn) return { "AAX", Ids::aaxBinaryLocation };
1962+
if (targetType == VSTPlugIn) return { "VST (Legacy)", Ids::vstBinaryLocation };
1963+
if (targetType == VST3PlugIn) return { "VST3", Ids::vst3BinaryLocation };
1964+
if (targetType == UnityPlugIn) return { "Unity", Ids::unityPluginBinaryLocation };
1965+
if (targetType == LV2PlugIn) return { "LV2", Ids::lv2BinaryLocation };
1966+
1967+
return {};
1968+
}
1969+
1970+
static String generatePluginCopyStepPathValidatorScript (Target::Type targetType,
1971+
const MSVCBuildConfiguration& config,
1972+
Architecture arch)
1973+
{
1974+
MSVCScriptBuilder builder;
1975+
1976+
if (config.isPluginBinaryCopyStepEnabled())
19441977
{
1945-
auto directory = getOwner().getOutDirFile (config, "");
1946-
MSVCScriptBuilder script;
1978+
const auto [projectTypeString, binaryLocationId] = getPluginTypeInfo (targetType);
19471979

1948-
std::for_each (segments.begin(), std::prev (segments.end()), [&] (const auto& s)
1980+
if (projectTypeString.isNotEmpty())
19491981
{
1950-
directory += (directory.isEmpty() ? "" : "\\") + s;
1982+
const auto binaryPath = config.getBinaryPath (binaryLocationId, arch);
19511983

1952-
script.ifelse ("not exist " + (directory + "\\").quoted(),
1953-
MSVCScriptBuilder{}.deleteFile (directory.quoted())
1954-
.mkdir (directory.quoted()).build());
1955-
});
1984+
if (binaryPath.isEmpty())
1985+
{
1986+
String warningMessage =
1987+
"Plugin Configuration Warning: Plugin copy step is enabled but no target "
1988+
"path is specified in the Projucer.";
19561989

1957-
return script.build();
1958-
};
1990+
warningMessage << " This can be configured via the \""
1991+
<< getArchitectureValueString (arch) << " "
1992+
<< projectTypeString << " "
1993+
<< "Binary Location\" option in the relevant Exporter configuration panel.";
1994+
1995+
builder.warning (warningMessage.quoted());
1996+
}
1997+
else
1998+
{
1999+
constexpr auto errorMessage =
2000+
"Plugin Copy Step Failure: Either the install path does not exist or you "
2001+
"do not have permission to write to the target directory. Ensure you "
2002+
"have the necessary permissions to write to the directory, or choose "
2003+
"a different install location (e.g., a folder in your user directory).";
2004+
2005+
MemoryOutputStream script;
2006+
2007+
const auto validProjectName = build_tools::makeValidIdentifier (config.project.getProjectNameString(),
2008+
false,
2009+
true,
2010+
false,
2011+
false);
2012+
const auto validPluginName = build_tools::makeValidIdentifier (projectTypeString,
2013+
false,
2014+
true,
2015+
false,
2016+
false);
2017+
script << "set TOUCH_NAME=\".touch_\""
2018+
<< validProjectName << "_"
2019+
<< validPluginName << "_"
2020+
<< "\"%RANDOM%\"" << newLine;
2021+
2022+
String tempPath = binaryPath;
2023+
tempPath << "\\%TOUCH_NAME%";
2024+
2025+
script << "(" << newLine;
2026+
script << "echo \".\" > " << tempPath.quoted() << newLine;
2027+
script << ") > nul 2>&1" << newLine;
2028+
2029+
builder.append (script.toString());
2030+
builder.ifelse ("exist " + tempPath.quoted(),
2031+
MSVCScriptBuilder{}.deleteFile (tempPath.quoted()),
2032+
MSVCScriptBuilder{}.error (String { errorMessage }.quoted())
2033+
.exit (1));
2034+
}
2035+
}
2036+
}
19592037

2038+
return builder.build();
2039+
}
2040+
2041+
static String generateToolchainValidatorScript (Architecture arch)
2042+
{
19602043
MSVCScriptBuilder builder;
19612044

19622045
if (arch == Architecture::win64)
@@ -1978,6 +2061,33 @@ class MSVCProjectExporterBase : public ProjectExporter
19782061
}, MSVCScriptBuilder{}.append (x86ToolchainErrorMessage));
19792062
}
19802063

2064+
return builder.build();
2065+
}
2066+
2067+
String getExtraPreBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const
2068+
{
2069+
const auto createBundleStructure = [&] (const StringArray& segments)
2070+
{
2071+
auto directory = getOwner().getOutDirFile (config, "");
2072+
MSVCScriptBuilder script;
2073+
2074+
std::for_each (segments.begin(), std::prev (segments.end()), [&] (const auto& s)
2075+
{
2076+
directory += (directory.isEmpty() ? "" : "\\") + s;
2077+
2078+
script.ifelse ("not exist " + (directory + "\\").quoted(),
2079+
MSVCScriptBuilder{}.deleteFile (directory.quoted())
2080+
.mkdir (directory.quoted()).build());
2081+
});
2082+
2083+
return script.build();
2084+
};
2085+
2086+
MSVCScriptBuilder builder;
2087+
2088+
builder.append (generatePluginCopyStepPathValidatorScript (type, config, arch));
2089+
builder.append (generateToolchainValidatorScript (arch));
2090+
19812091
if (type == LV2PlugIn)
19822092
{
19832093
const auto crossCompilationPairs =
@@ -2010,8 +2120,14 @@ class MSVCProjectExporterBase : public ProjectExporter
20102120
return builder.build();
20112121
}
20122122

2123+
if (type == UnityPlugIn)
2124+
return builder.build();
2125+
20132126
if (type == AAXPlugIn)
2014-
return createBundleStructure (getAaxBundleStructure (config, arch));
2127+
return builder.build() + "\r\n" + createBundleStructure (getAaxBundleStructure (config, arch));
2128+
2129+
if (type == VSTPlugIn)
2130+
return builder.build();
20152131

20162132
if (type == VST3PlugIn)
20172133
return builder.build() + "\r\n" + createBundleStructure (getVst3BundleStructure (config, arch));

0 commit comments

Comments
 (0)