Leo
Leo

Reputation: 2072

Locating data files in C program built with Autotools

I have a C program built using Autotools. In src/Makefile.am, I define a macro with the path to installed data files:

AM_CPPFLAGS = -DAM_INSTALLDIR='"$(pkgdatadir)"'

The problem is that I need to run make install before I can test the binary (since it needs to be able to find the data files).

I can define another macro with the path of the source tree so the data files can be located without installing:

AM_CPPFLAGS = -DAM_INSTALLDIR='"$(pkgdatadir)"' -DAM_TOPDIR='"$(abs_top_srcdir)"'

Now, I would like the following behavior:

  1. If the binary was installed via make install, use AM_INSTALLDIR to fetch data files.
  2. If the binary was not installed, use AM_TOPDIR to fetch data files.

Is this possible? Is there a better approach to this problem?

Upvotes: 2

Views: 523

Answers (3)

Leo
Leo

Reputation: 2072

A bit of additional information first: The data files are under active development, and I have various scripts that need to call binaries using local data files, whereas installed binaries should use stable, installed data files.

My original solution made use of an environment variable, as proposed by reece. But I didn't want to manage setting up environment variables in various places, and I didn't want any risk of the wrong data files being picked up due to a mistake.

So the solution I ended up with was to define macros for both locations at build time, and add a flag (-local) to the binaries to force local data files to be used.

Upvotes: 0

William Pursell
William Pursell

Reputation: 212454

Making the program able to use a run-time configuration as proposed by reece is a good solution. If for some reason you do not want it to be configurable at run-time, a common solution is to build a test binary differently than the installed binary (there are other problems associated with this, in particular ensuring that the program you are testing has behavior that is consistent with the program that is installed.) An easy way to do that is something like:

bin_PROGRAMS = foo
check_PROGRAMS = test-foo
test_foo_SOURCES = $(foo_SOURCES)
AM_CPPFLAGS = -DINSTALLDIR='"$(pkgdatadir)"'
test_foo_CPPFLAGS = -DINSTALLDIR='"$(abs_top_srcdir)"'

Rather than using a binary with a different name, you might want to have a dedicated tests directory and build the program using the same name as the original.

Note that I've changed the name from AM_INSTALLDIR to INSTALLDIR. Automake reserves names beginning with "AM_" for its own use, and by using that name you are stomping on Automake's namespace.

Upvotes: 3

reece
reece

Reputation: 8155

What I do (in https://http://rhdunn.github.com/cainteoir/) is:

const char *basedir = getenv("CAINTEOIR_DATADIR");
if (!basedir)
    basedir = DATADIR "/" PACKAGE; // e.g. /usr/share/cainteoir-engine

and then run it (in tests/harness.py) as:

CAINTEOIR_DATADIR=`pwd`/data src/apps/metadata/metadata test_file.epub

This then allows the user to change the location of where to get the data if they wish.

Upvotes: 5

Related Questions