Desktop icon formats are a mess. No platforms share formats - Windows uses .ico (and for various reasons so does the web), Mac OS X uses .icns, and desktop GNU/Linux doesn't even have an icon format, you just throw PNGs into the air and pray.
But let's say you are foolishly trying to write a cross-platform application, yet intelligently want to automate creating most of these from source data.
A reasonable "source data" for icons is a directory full of
PNGs.1 Apple uses a format called .iconset for this, with filenames
example.iconset/icon_64x64.png. Since it's just a directory of
images, it'll serve for making Windows/website icons as well, and
GNU/Linux build scripts can copy files out of it directly.
Now for the Makefile:
ICONUTIL := $(word 1, $(shell command -v iconutil icnsutil) iconutil) .SECONDEXPANSION: %.icns: %.iconset $$(wildcard $$(@D)/$$*.iconset/icon_*.png) $(ICONUTIL) -c icns -o $@ $< .SECONDEXPANSION: %.ico: %.iconset $$(wildcard $$(@D)/$$*.iconset/icon_*[0-9].png) convert -background transparent -colors 256 $(filter-out $<,$^) $@
(You'll need to replace those spaces with tabs. Sorry. Complain here.)
This uses a couple unusual tricks.
ICONUTIL assignment figures out whether you've got the
iconutil from Mac OS X, or the compatible
libicns. If you don't have either, it picks
iconutil so you get a
Second, it uses GNU Make's secondary expansion feature. This specifies a wildcard dependent on the pattern and target name when generating the list of source names.
Third, it depends on the source directory. This is uncommon in
Makefiles because directories update when contained files are added or
deleted, not when files are modified. The modification case is covered
.SECONDEXPANSION trick but we also need to handle the
case where an icon size was removed, because the target files need to
be rebuilt without the removed file.
Finally, please note the slightly different glob patterns.
files support high-DPI ("Retina") icons using the format
icon_WxH@2.png - so
email@example.com is actually 32 pixels on each
.ico files, as far as I can determine, have no such feature;
they will use the 32x32 icon instead. So
@2x files should not
be included when building the
Assigning a .ico to a .exe
$ wine ResHacker.exe -addoverwrite "example.exe,example-new.exe,example.ico,ICONGROUP,MAINICON,0"
Assigning a .icns to a .app
Mac OS X
.app files are directories. The usual place to put an
icon would be
Contents/Resources/Icon.icns, and you may simply need to
copy it over the file already there.
Another reasonable source format is one or multiple SVGs. Turning an SVG into a directory of PNGs is left as an exercise for the reader. ↩