mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
CLion: Added support for application icons
This commit is contained in:
parent
e7750ecd92
commit
4d6921ff7d
3 changed files with 148 additions and 95 deletions
|
|
@ -149,8 +149,8 @@ public:
|
|||
<< "Add these exporters to the project to enable CLion builds." << newLine
|
||||
<< newLine
|
||||
<< "Not all features of all the exporters are currently supported. Notable omissions are AUv3 "
|
||||
<< "plug-ins, embedding resources and fat binaries on MacOS, and adding application icons. On "
|
||||
<< "Windows the CLion exporter requires a GCC-based compiler like MinGW.";
|
||||
<< "plug-ins, embedding resources and fat binaries on MacOS. On Windows the CLion exporter "
|
||||
<< "requires a GCC-based compiler like MinGW.";
|
||||
|
||||
return description;
|
||||
}
|
||||
|
|
@ -372,16 +372,47 @@ private:
|
|||
out << " " << fileInfo.first.quoted() << newLine;
|
||||
|
||||
auto isCMakeBundle = exporter.isXcode() && target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle;
|
||||
String pkgInfoPath = File (getTargetFolder().getChildFile ("PkgInfo")).getFullPathName().quoted();
|
||||
auto pkgInfoPath = String ("PkgInfo").quoted();
|
||||
|
||||
if (isCMakeBundle)
|
||||
out << " " << pkgInfoPath << newLine;
|
||||
|
||||
auto xcodeIcnsFilePath = [&] () -> String
|
||||
{
|
||||
if (exporter.isXcode() && target->getTargetFileType() == ProjectType::Target::TargetFileType::executable)
|
||||
{
|
||||
auto xcodeIcnsFile = getTargetFolder().getParentDirectory()
|
||||
.getChildFile ("MacOSX")
|
||||
.getChildFile ("Icon.icns");
|
||||
|
||||
if (xcodeIcnsFile.existsAsFile())
|
||||
return xcodeIcnsFile.getRelativePathFrom (getTargetFolder()).quoted();
|
||||
}
|
||||
|
||||
return {};
|
||||
}();
|
||||
|
||||
if (xcodeIcnsFilePath.isNotEmpty())
|
||||
out << " " << xcodeIcnsFilePath << newLine;
|
||||
|
||||
if (exporter.isCodeBlocks() && target->getTargetFileType() == ProjectType::Target::TargetFileType::executable)
|
||||
{
|
||||
auto windowsRcFile = getTargetFolder().getParentDirectory()
|
||||
.getChildFile ("CodeBlocksWindows")
|
||||
.getChildFile ("resources.rc");
|
||||
|
||||
if (windowsRcFile.existsAsFile())
|
||||
out << " " << windowsRcFile.getRelativePathFrom (getTargetFolder()).quoted() << newLine;
|
||||
}
|
||||
|
||||
out << ")" << newLine << newLine;
|
||||
|
||||
if (isCMakeBundle)
|
||||
out << "set_source_files_properties (" << pkgInfoPath << " PROPERTIES MACOSX_PACKAGE_LOCATION .)" << newLine;
|
||||
|
||||
if (xcodeIcnsFilePath.isNotEmpty())
|
||||
out << "set_source_files_properties (" << xcodeIcnsFilePath << " PROPERTIES MACOSX_PACKAGE_LOCATION \"Resources\")" << newLine;
|
||||
|
||||
for (auto& fileInfo : fileInfoList)
|
||||
if (! fileInfo.second)
|
||||
out << "set_source_files_properties (" << fileInfo.first.quoted() << " PROPERTIES HEADER_FILE_ONLY TRUE)" << newLine;
|
||||
|
|
@ -643,7 +674,7 @@ private:
|
|||
if (! isWindowsAbsolutePath (path))
|
||||
out << "${CMAKE_CURRENT_SOURCE_DIR}/";
|
||||
|
||||
out << path.replace ("\\", "/") << "\\\"\"" << newLine;
|
||||
out << path.replace ("\\", "/").unquoted() << "\\\"\"" << newLine;
|
||||
}
|
||||
|
||||
for (auto& flag : exporter.getLinkerFlags (config, *target))
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "jucer_ProjectExport_MSVC.h"
|
||||
|
||||
//==============================================================================
|
||||
class CodeBlocksProjectExporter : public ProjectExporter
|
||||
|
|
@ -396,6 +397,7 @@ private:
|
|||
StringArray getCompilerFlags (const BuildConfiguration& config, CodeBlocksTarget& target) const
|
||||
{
|
||||
StringArray flags;
|
||||
|
||||
if (auto* codeBlocksConfig = dynamic_cast<const CodeBlocksBuildConfiguration*> (&config))
|
||||
flags.add (codeBlocksConfig->getArchitectureTypeString());
|
||||
|
||||
|
|
@ -793,10 +795,27 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
bool hasResourceFile() const
|
||||
{
|
||||
return ! projectType.isStaticLibrary();
|
||||
}
|
||||
|
||||
void addCompileUnits (XmlElement& xml) const
|
||||
{
|
||||
for (int i = 0; i < getAllGroups().size(); ++i)
|
||||
addCompileUnits (getAllGroups().getReference(i), xml);
|
||||
|
||||
if (hasResourceFile())
|
||||
{
|
||||
auto iconFile = getTargetFolder().getChildFile ("icon.ico");
|
||||
MSVCProjectExporterBase::writeIconFile (*this, iconFile);
|
||||
auto rcFile = getTargetFolder().getChildFile ("resources.rc");
|
||||
MSVCProjectExporterBase::createRCFile (project, iconFile, rcFile);
|
||||
|
||||
auto* unit = xml.createNewChildElement ("Unit");
|
||||
unit->setAttribute ("filename", rcFile.getFileName());
|
||||
unit->createNewChildElement ("Option")->setAttribute ("compilerVar", "WINDRES");
|
||||
}
|
||||
}
|
||||
|
||||
void createProject (XmlElement& xml) const
|
||||
|
|
|
|||
|
|
@ -698,7 +698,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (getOwner().iconFile != File())
|
||||
if (getOwner().iconFile.existsAsFile())
|
||||
{
|
||||
auto* e = otherFilesGroup->createNewChildElement ("None");
|
||||
e->setAttribute ("Include", prependDot (getOwner().iconFile.getFileName()));
|
||||
|
|
@ -884,7 +884,7 @@ public:
|
|||
addFilesToFilter (group, group.getName(), *cpps, *headers, *otherFilesGroup, *groupsXml);
|
||||
}
|
||||
|
||||
if (getOwner().iconFile.exists())
|
||||
if (getOwner().iconFile.existsAsFile())
|
||||
{
|
||||
auto* e = otherFilesGroup->createNewChildElement ("None");
|
||||
e->setAttribute ("Include", prependDot (getOwner().iconFile.getFileName()));
|
||||
|
|
@ -1434,6 +1434,94 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
static void writeIconFile (const ProjectExporter& exporter, const File& iconFile)
|
||||
{
|
||||
Array<Image> images;
|
||||
int sizes[] = { 16, 32, 48, 256 };
|
||||
|
||||
for (int i = 0; i < numElementsInArray (sizes); ++i)
|
||||
{
|
||||
auto im = exporter.getBestIconForSize (sizes[i], true);
|
||||
|
||||
if (im.isValid())
|
||||
images.add (im);
|
||||
}
|
||||
|
||||
if (images.size() > 0)
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
writeIconFile (images, mo);
|
||||
overwriteFileIfDifferentOrThrow (iconFile, mo);
|
||||
}
|
||||
}
|
||||
|
||||
static void writeRCValue (MemoryOutputStream& mo, const String& name, const String& value)
|
||||
{
|
||||
if (value.isNotEmpty())
|
||||
mo << " VALUE \"" << name << "\", \""
|
||||
<< CppTokeniserFunctions::addEscapeChars (value) << "\\0\"" << newLine;
|
||||
}
|
||||
|
||||
static void createRCFile (const Project& project, const File& iconFile, const File& rcFile)
|
||||
{
|
||||
auto version = project.getVersionString();
|
||||
|
||||
MemoryOutputStream mo;
|
||||
|
||||
mo << "#ifdef JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< " #include JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< "#else" << newLine
|
||||
<< newLine
|
||||
<< "#undef WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#define WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#include <windows.h>" << newLine
|
||||
<< newLine
|
||||
<< "VS_VERSION_INFO VERSIONINFO" << newLine
|
||||
<< "FILEVERSION " << getCommaSeparatedVersionNumber (version) << newLine
|
||||
<< "BEGIN" << newLine
|
||||
<< " BLOCK \"StringFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " BLOCK \"040904E4\"" << newLine
|
||||
<< " BEGIN" << newLine;
|
||||
|
||||
writeRCValue (mo, "CompanyName", project.getCompanyNameString());
|
||||
writeRCValue (mo, "LegalCopyright", project.getCompanyCopyrightString());
|
||||
writeRCValue (mo, "FileDescription", project.getProjectNameString());
|
||||
writeRCValue (mo, "FileVersion", version);
|
||||
writeRCValue (mo, "ProductName", project.getProjectNameString());
|
||||
writeRCValue (mo, "ProductVersion", version);
|
||||
|
||||
mo << " END" << newLine
|
||||
<< " END" << newLine
|
||||
<< newLine
|
||||
<< " BLOCK \"VarFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " VALUE \"Translation\", 0x409, 1252" << newLine
|
||||
<< " END" << newLine
|
||||
<< "END" << newLine
|
||||
<< newLine
|
||||
<< "#endif" << newLine;
|
||||
|
||||
if (iconFile.existsAsFile())
|
||||
mo << newLine
|
||||
<< "IDI_ICON1 ICON DISCARDABLE " << iconFile.getFileName().quoted()
|
||||
<< newLine
|
||||
<< "IDI_ICON2 ICON DISCARDABLE " << iconFile.getFileName().quoted();
|
||||
|
||||
overwriteFileIfDifferentOrThrow (rcFile, mo);
|
||||
}
|
||||
|
||||
static String getCommaSeparatedVersionNumber (const String& version)
|
||||
{
|
||||
auto versionParts = StringArray::fromTokens (version, ",.", "");
|
||||
versionParts.trim();
|
||||
versionParts.removeEmptyStrings();
|
||||
while (versionParts.size() < 4)
|
||||
versionParts.add ("0");
|
||||
|
||||
return versionParts.joinIntoString (",");
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String createRebasedPath (const RelativePath& path) const
|
||||
|
|
@ -1722,98 +1810,13 @@ protected:
|
|||
{
|
||||
if (hasResourceFile())
|
||||
{
|
||||
Array<Image> images;
|
||||
int sizes[] = { 16, 32, 48, 256 };
|
||||
|
||||
for (int i = 0; i < numElementsInArray (sizes); ++i)
|
||||
{
|
||||
auto im = getBestIconForSize (sizes[i], true);
|
||||
if (im.isValid())
|
||||
images.add (im);
|
||||
}
|
||||
|
||||
if (images.size() > 0)
|
||||
{
|
||||
iconFile = getTargetFolder().getChildFile ("icon.ico");
|
||||
|
||||
MemoryOutputStream mo;
|
||||
writeIconFile (images, mo);
|
||||
overwriteFileIfDifferentOrThrow (iconFile, mo);
|
||||
}
|
||||
|
||||
createRCFile();
|
||||
iconFile = getTargetFolder().getChildFile ("icon.ico");
|
||||
writeIconFile (*this, iconFile);
|
||||
rcFile = getTargetFolder().getChildFile ("resources.rc");
|
||||
createRCFile (project, iconFile, rcFile);
|
||||
}
|
||||
}
|
||||
|
||||
void createRCFile() const
|
||||
{
|
||||
rcFile = getTargetFolder().getChildFile ("resources.rc");
|
||||
|
||||
auto version = project.getVersionString();
|
||||
|
||||
MemoryOutputStream mo;
|
||||
|
||||
mo << "#ifdef JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< " #include JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< "#else" << newLine
|
||||
<< newLine
|
||||
<< "#undef WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#define WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#include <windows.h>" << newLine
|
||||
<< newLine
|
||||
<< "VS_VERSION_INFO VERSIONINFO" << newLine
|
||||
<< "FILEVERSION " << getCommaSeparatedVersionNumber (version) << newLine
|
||||
<< "BEGIN" << newLine
|
||||
<< " BLOCK \"StringFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " BLOCK \"040904E4\"" << newLine
|
||||
<< " BEGIN" << newLine;
|
||||
|
||||
writeRCValue (mo, "CompanyName", project.getCompanyNameString());
|
||||
writeRCValue (mo, "LegalCopyright", project.getCompanyCopyrightString());
|
||||
writeRCValue (mo, "FileDescription", project.getProjectNameString());
|
||||
writeRCValue (mo, "FileVersion", version);
|
||||
writeRCValue (mo, "ProductName", project.getProjectNameString());
|
||||
writeRCValue (mo, "ProductVersion", version);
|
||||
|
||||
mo << " END" << newLine
|
||||
<< " END" << newLine
|
||||
<< newLine
|
||||
<< " BLOCK \"VarFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " VALUE \"Translation\", 0x409, 1252" << newLine
|
||||
<< " END" << newLine
|
||||
<< "END" << newLine
|
||||
<< newLine
|
||||
<< "#endif" << newLine;
|
||||
|
||||
if (iconFile != File())
|
||||
mo << newLine
|
||||
<< "IDI_ICON1 ICON DISCARDABLE " << iconFile.getFileName().quoted()
|
||||
<< newLine
|
||||
<< "IDI_ICON2 ICON DISCARDABLE " << iconFile.getFileName().quoted();
|
||||
|
||||
overwriteFileIfDifferentOrThrow (rcFile, mo);
|
||||
}
|
||||
|
||||
static void writeRCValue (MemoryOutputStream& mo, const String& name, const String& value)
|
||||
{
|
||||
if (value.isNotEmpty())
|
||||
mo << " VALUE \"" << name << "\", \""
|
||||
<< CppTokeniserFunctions::addEscapeChars (value) << "\\0\"" << newLine;
|
||||
}
|
||||
|
||||
static String getCommaSeparatedVersionNumber (const String& version)
|
||||
{
|
||||
auto versionParts = StringArray::fromTokens (version, ",.", "");
|
||||
versionParts.trim();
|
||||
versionParts.removeEmptyStrings();
|
||||
while (versionParts.size() < 4)
|
||||
versionParts.add ("0");
|
||||
|
||||
return versionParts.joinIntoString (",");
|
||||
}
|
||||
|
||||
static String prependDot (const String& filename)
|
||||
{
|
||||
return FileHelpers::isAbsolutePath (filename) ? filename
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue