views:

328

answers:

4

In this instance I'm using c with autoconf, but the question applies elsewhere.

I have a glade xml file that is needed at runtime, and I have to tell the application where it is. I'm using autoconf to define a variable in my code that points to the "specified prefix directory"/app-name/glade. But that only begins to work once the application is installed. What if I want to run the program before that point? Is there a standard way to determine what paths should be checked for application data?

Thanks


Thanks for the responses. To clarify, I don't need to know where the app data is installed (eg by searching in /usr,usr/local,etc etc), the configure script does that. The problem was more determining whether the app has been installed yet. I guess I'll just check in install location first, and if not then in "./src/foo.glade".

A: 

If the program is installed globally:

/usr/share/app-name/glade.xml

If you want the program to work without being installed (i.e. just extract a tarball), put it in the program's directory.

Zifre
No, autoconf allows you to specify any install dir when you build, so the location has to come from autoconf. using a fixed path like that is a bad idea.
DaedalusFall
@Daedalus: I meant if you have it installed from a package. Even with autoconf, this would be what the path should come out to by default (assuming you set the prefix to /usr).
Zifre
+2  A: 

I dont think there's any standard way on how to locate such data.

I'd personally do it in a way that i'd have a list of paths and i'd locate if i can find the file from anyone of those and the list should containt the DATADIR+APPNAME defined from autoconf and CURRENTDIRECTORY+POSSIBLE_PREFIX where prefix might be some folder from your build root.

But in any case, dont forget to use those defines from autoconf for your data files, those make your software easier to package (like deb/rpm)

rasjani
A: 

I don't think there is a standard way of placing files. I build it into the program, and I don't limit it to one location.

It depends on how much customising of the config file is going to be required.

I start by constructing a list of default directories and work through them until I find an instance of glade.xml and stop looking, or not find it and exit with an error. Good candidates for the default list are /etc, /usr/share/app-name, /usr/local/etc.

If the file is designed to be customizable, before I look through the default directories, I have a list of user files and paths and work through them. If it doesn't find one of the user versions, then I look in the list of default directories. Good candidates for the user config files are ~/.glade.xml or ~/.app-name/glade.xml or ~/.app-name/.glade.xml.

codebunny
Most distributions disallow their packages to install anything into ~ folder. In multiuser host, you'd be waisting diskspace and causing multitude of parsing and access problems.
rasjani
But then again, i didnt notice you mentioned the "customizable" part, then obviously the only place is somewhere inside ~ =)
rasjani
+1  A: 

There is no prescription how this should be done in general, but Debian packagers usually installs the application data somewhere in /usr/share, /usr/lib, et cetera. They may also patch the software to make it read from appropriate locations. You can see the Debian policy for more information.

I can however say a few words how I do it. First, I don't expect to find the file in a single directory; I first create a list of directories that I iterate through in my wrapper around fopen(). This is the order in which I believe the file reading should be done:

  • current directory (obviously)
  • ~/.program-name
  • $(datadir)/program-name

$(datadir) is a variable you can use in Makefile.am. Example:

AM_CPPFLAGS = $(ASSERT_FLAGS) $(DEBUG_FLAGS) $(SDLGFX_FLAGS) $(OPENGL_FLAGS) -DDESTDIRS=\"$(prefix):$(datadir)/:$(datadir)/program-name/\"

This of course depends on your output from configure and how your configure.ac looks like.

So, just make a wrapper that will iterate through the locations and get the data from those dirs. Something like a PATH variable, except you implement the iteration.

After writing this post, I noticed I need to clean up our implementation in this project, but it can serve as a nice start. Take a look at our Makefile.am for using $(datadir) and our util.cpp and util.h for a simple wrapper (yatc_fopen()). We also have yatc_find_file() in case some third-party library is doing the fopen()ing, such as SDL_image or libxml2.

Ivan Vučica
thanks, and thanks for the example.But I'd argue $(datadir)/program-name ought to be done before current directory, just in case there is a similar file lying around. imagine if you did `sudo foo` and foo checked the local dir first for some file... result could potentially be disasterous!
DaedalusFall