-1

I'm using autotools on a C project that, after installation, needs a particular directory structure in /var/lib as follows:

/var/lib/my-project/
    data/
    configurations/
        local/
        extra/
    inputs/

I'm currently using the directive AS_MKDIR_P in configure.ac like so:

AS_MKDIR_P(/var/lib/my-project/data)
AS_MKDIR_P(/var/lib/my-project/configurations/local)
AS_MKDIR_P(/var/lib/my-project/configurations/extra)
AS_MKDIR_P(/var/lib/my-project/inputs)

But it needs the configure script to be run with root permissions which I don't think is the way to go. I think the instructions to create this directory structure needs to be in Makefile.am, so that make install creates them rather than configure, but I have no idea how to do that.

ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • I thought (hoped) that cmake killed automake, autoconf etc. I guess not – pm100 Apr 15 '22 at 16:26
  • 1
    To each their own, I guess, @pm100. I much prefer the Autotools to CMake, though not caring much about building native Windows software does make that easier. – John Bollinger Apr 15 '22 at 16:30

2 Answers2

3

You really, really, really do not want to specify /var/lib/my-project. As the project maintainer, you have the right to specify relative paths, but the user may change DESTDIR or prefix. If you ignore DESTDIR and prefix and just install your files in /var/lib without regard for the user's requests, then your package is broken. It is not just slightly damaged, it is completely unusable. The autotool packaging must not specify absolute paths; that is for downsteam packagers (ie, those that build *.rpm or *.deb or *.dmg or ...). All you need to do is add something like this to Makefile.am:

configdir = $(pkgdatadir)/configurations
localdir  = $(configdir)/local
extradir  = $(configdir)/extra
inputdir  = $(pkgdatadir)/inputs
mydatadir = $(pkgdatadir)/data

config_DATA = cfg.txt
local_DATA = local.txt
extra_DATA = extra.txt
input_DATA = input.txt
mydata_DATA = data.txt

This will put input.txt in $(DESTDIR)$(pkgdatadir)/inputs, etc. If you want that final path to be /var/lib/my-project, then you can specify datadir appropriately at configure time. For example:

$ CONFIG_SITE= ./configure --datadir=/var/lib > /dev/null

This will assign /var/lib to datadir, so that pkgdatadir will be /var/lib/my-project and a subsequent make install DESTDIR=/path/to/foo will put the files in /path/to/foo/var/lib/my-package/. It is essential that your auto-tooled package honor things like prefix (which for these files was essentially overridden here by the explicit assignment of datadir) and DESTDIR. The appropriate time to specify paths like /var/lib is when you run the configure script. For example, you can add the options to the configure script in your rpm spec file or in debian/rules, or in whatever file your package system uses. The auto-tools provide a very flexible packaging system which can be easily used by many different packaging systems (unfortunately, the word "package" is highly overloaded!). Embrace that flexibility.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • This is definitely the idiomatic way to do it with the Autotools. – John Bollinger Apr 15 '22 at 16:32
  • Thank you for your response! I'm new to this autotooling. The thing is, those directories are empty initially, and will be used by the executables of my package to store and manage data later on (after install). This is not where the data files of the package itself are stored, those will be in `datadir` as usual. The directory structure will be used to store data generated by users as they use my package. – ibrahim mahrir Apr 15 '22 at 18:36
  • 1
    @ibrahimmahrir See https://stackoverflow.com/questions/8518979/makefile-am-create-empty-directory – William Pursell Apr 15 '22 at 18:50
  • Great! That uses the same approach as my answer (using the hook [`install-data-local`](https://www.gnu.org/software/automake/manual/html_node/Extending-Installation.html) instead of the `install-exec-hook` I used). I was worried that my approach is not the best way to do it but this seems to confirm it. Thank you so much for your help. I really appreciate it. – ibrahim mahrir Apr 15 '22 at 23:00
0

According to autotools documentation (here and here), there are hooks that you can specify in Makefile.am that will run at specific times during the installation. For my needs I will use install-exec-hook (or install-data-hook) which will be run after all executables (or data) have been installed:

install-exec-hook:
    $(MKDIR_P) /var/lib/my-project/data
    $(MKDIR_P) /var/lib/my-project/configurations/local
    $(MKDIR_P) /var/lib/my-project/configurations/extra
    $(MKDIR_P) /var/lib/my-project/inputs

MKDIR_P is a variable containing the command mkdir -p, or an equivalent to it if the system doesn't have mkdir. To make it available in Makefile.am you have to use the macro AC_PROG_MKDIR_P in configure.ac.

ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • 1
    This hook is broken in multiple ways: It should respect `$(DESTDIR)`. It should use `$(INSTALL)` instead of `$(MKDIR_P)`. It should not hard code `/var/lib/my-project`. You want at least two levels of directory variable defined here, let's call them `varlibdir` and `pkgvarlibdir`. You can `AC_ARG_VAR()` those, with `pkgvarlibdir` defaulting to `$(varlibdir)/$(PACKAGE)`. – ndim Apr 26 '22 at 14:34