I am writing a C++ program using gtkmm as the window library and autotools as my build system. In my Makefile.am, I install the icon as follows:
icondir = $(datadir)/icons/hicolor/scalable/apps
icon_DATA = $(top_srcdir)/appname.svg
EDIT: changed from prefix
to datadir
This results in appname.svg
being copied to $(datadir)/icons/hicolor/scalable/apps
when the program is installed. In my C++ code, I would like to access the icon at runtime for a window decoration:
string iconPath = DATADIR + "/icons/hicolor/scalable/apps/appname.svg";
// do stuff with the icon
I am unsure how to go about obtaining DATADIR
for this purpose. I could use relative paths, but then moving the binary would break the icon, which seems evident of hackery. I figure that there should be a special way to handle icons separate from general data, since people can install 3rd party icon packs. So, I have two questions:
Edit: gtkmm has an IconTheme class that is the standard way to use icons in gtkmm. It appears that I add_resource_path()
(for which I still need the installation prefix), and then I can use the library to obtain the icon by name.
A prefix is the path on your host computer a software package is installed under. Packages that have a prefix will place all parts under the prefix path. Packages for your host computer typically use a default prefix of /usr/local on FreeBSD and Linux. You have to select a prefix for your installation.
Autotools configurationThis file is used by autoconf to create the configure shell script that users run before building. The file must contain, at the very least, the AC_INIT and AC_OUTPUT M4 macros.
Autoconf essentially runs the preprocessor on your script to produce a portable shell script which will perform all the requisite tests, produce handy log files, preprocess template files, for example to generate Makefile from Makefile.in and and take a standard set of command line arguments.
To convey data determined by configure
to your source files, the primary methods available are to write them in a header that your sources #include
or to define them as macros on the compiler command line. These are handled most conveniently via the AC_DEFINE
Autoconf macro. Under some circumstances, you might also consider converting source files to templates for configure
to process, but except inasmuch as Autoconf itself uses an internal version of that technique to build config.h
(when that is requested), I wouldn't normally recommend it.
HOWEVER, the installation prefix and other installation directories are special cases. They are not finally set until you actually run make
. Even if you set them via the configure
's command-line options, you can still override that by specifying different values on the make
command line. Thus, it is not safe to rely on AC_DEFINE
for this particular purpose, and in fact, doing so may not work at all (will not work for prefix
itself).
Instead, you should specify the appropriate macro definition in a command-line option that is evaluated at make
time. You can do this for all targets being built by setting the AM_CPPFLAGS
variable in your Makefile.am
files, as demonstrated in another answer. That particular example sets the specified symbol to be a macro that expands to a C string literal containing the prefix. Alternatively, you could consider defining the whole icon directory as a symbol. If you need it only for one target out of several then you might prefer setting the appropriate onetarget_CPPFLAGS
variable.
As an aside, do note that $(prefix)/icons/hicolor/scalable/apps
is a nonstandard choice for the installation directory for your icon. That will typically resolve to something like /usr/local/icons/hicolor/scalable/apps
. The conventional choice would be $(datadir)/icons/hicolor/scalable/apps
, which will resolve to something like /usr/local/share/icons/hicolor/scalable/apps
.
In your Makefile.am, use the following
AM_CPPFLAGS = -DPREFIX='"$(prefix)"'
See Defining Directories in autoconf's manual.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With