4

I am trying to convert a project to use non-recursive automake. Based on a search on SO I could see that the topic has been covered to some extend. But there are not really any questions on how to convert a recursive automake project to a non recursive one. I have already read Karel Zak's blog and of course the autotools-mythbuster. There is a question with experiences regarding non-recursive automake but it does not explain how to convert a project. The only question that explains a bit seems to be regarding the subdir-objects option. But I could not get my project converted with these resources. Hence this question.

Lets start with a simple project setup:

project/
   \-- configure.ac
   |-- Makefile.am
   \-- src/
      \-- Makefile.am
      |-- foo.c
      |-- foo.h
      \-- main.c

In configure.ac I just add the subdir-objects option:

AM_INIT_AUTOMAKE([subdir-objects])

In Makefile.am I removed the src directory from the root Makefiles.am's SUBDIRS variable. Then I removed the src/Makefile entry from the AC_CONFIG_FILES macro in `configure.ac.

Karel Zak's blog suggests to name the included Makefiles of the subdirectories Makemodule.am but Makefile.am seem to work too, if the sub folder is removed for the SUBDIRS variable and if the Makefile entry is removed from the AC_CONFIG_FILES config files macro.

Next I defined a global variable for the programs in the root Makefile.am and included the src/Makefile.am

bin_PROGRAMS=
include src/Makefile.am

In src/Makefile.am I changed:

bin_PROGRAMS=foo

to:

bin_PROGRAMS+=src/foo

and I also changed all occurences of foo_XXX to src_foo_XXX. And I added the prefix src/ to all .c and .h file names in src_foo_SOURCES.

But the program was not building and gave errors about include files not being found, for example:

fatal error: debug.h: No such file or directory
 #include <debug.h>

Originally my src directories Makefile.am only hat the content variables src_foo_SOURCES, src_foo_CFLAGS, src_foo_LDFLAGS and src_foo_LDADD. My solution to this problem was to add src_foo_CPPFLAGS like this:

src_foo_CPPFLAGS = \
    $(AM_CPPFLAGS) \
    -I$(top_builddir)/src \
    -DDATADIR='"$(datadir)"' \
    -DMODULEDIR='"$(moduledir)"' \
    -DLIBEXECDIR='"$(libexecdir)"'

But I dont' really understand why this was necessary and why it built fine when I was using recursive automake?

I have another question regarding the answer of Brett Hale in this question. He writes:

You could use "$(srcdir)/sourceA.cpp", but this directory is implicit anyway. All you need is:

libadapter_la_SOURCES = sourceA.cpp sourceB.cpp

But I could not get it to work without prefixing the path, so that seems wrong to me, can someone confirm my experience?

Update: I am also having problems with the po/ subdir, how can I make that non-recursive? There is no Makefile.am in po/ just a Makevars file. There is a post on autotools-mythbuster, that indicates non-recursive make with gettext is not supported, but that post is from 2011. I'm not sure if anything might have changed in the mean time.

Community
  • 1
  • 1
lanoxx
  • 12,249
  • 13
  • 87
  • 142

1 Answers1

1

I'll start from the bottom up: nothing changed with respect to gettext since 2011, and po/ directories should still be handled recursively, unfortunately. The same is true for gtk-doc. The reason is that they build somewhat-automake-compatible Makefile.in files, but they are not really automake-based.

As for the header file not found, the reason why it now fails is because you're using the wrong #include statement format: you should use #include "debug.h" and then it would work without having to add the -Isrc to the command line. The preprocessor will look for "" enclosed headers in the same directory as the source file, and for <> enclosed header in the include path; automake by default adds the current directory to the include path with -I. and that meant that it was satisfied when using recursive Makefile.am, but now the "current directory" no longer matches your source file's directory.

I would also suggest both against re-using the name Makefile.am if you're using Karel's suggested approach (automake, or at least some versions of it, will then generate a Makefile.in file for the subdirectory that will not work properly), and to consider not using Karel's approach at all if your software is self-contained enough, for instance if it only has one binary target. Karel's use case was linux-utils which is a fairly sparse project with a few dozen targets each with its own set of source files.

I'll try to comment on the Brett Hale answer you noted, as I think there's a misunderstanding there altogether.

Diego Elio Pettenò
  • 3,152
  • 12
  • 15
  • Okay it looks like I can't comment to Brett's answer as I don't have enough reputation here (even though I wrote the guide itself). The short answer is, don't use $(srcdir) in _SOURCES, ever. It can cause issues with many tools when doing out-of-tree builds, and it brings you nothing. `automake` uses `VPATH` to find the sources anyway. What you can use (but also brings you nothing) is [reldir](https://blog.flameeyes.eu/2013/06/autotools-mythbuster-what-s-new-in-automake-1-14) so you can define your sources as `foo_SOURCES = %D%/foo.c %D%/foo.h` – Diego Elio Pettenò Jun 02 '14 at 11:26
  • My project is http://github.com/lanoxx/tilda, which is indeed a very small project with only one binary. But I was mainly using that as a learning example so I can start to refactor another bigger project such as gnome-panel. I am not sure what you mean with the statement that `reldir` will bring me nothing? If I don't use `reldir`, then I have to prefix every source file with the folder name, but that means its more difficult to move the folder around or rename it. – lanoxx Jun 03 '14 at 15:36
  • Yes if you're going to refactor a much larger project then using reldir (%D%) is a good idea, if you plan to ever move the directory around. On the other hand, it still does not allow you to change the output directory of the binary, as, if I'm not mistaken, you can't declare it as %D%_foo_SOURCES. Nothing stops you from building everything at top-level and use reldir though. – Diego Elio Pettenò Jun 04 '14 at 14:59
  • Thanks for the clarification. But you are wrong about %D%. You can infact use bin_PROGRAMS += %D%/foo and then use `%C%_foo_SOURCES=...`. The difference is to use `%C%` or `%canon_reldir%` in the prefix as the canonicalized form. The binary will then be build in the respective source directory. – lanoxx Jun 04 '14 at 19:33
  • About `Makefile.am`, according to the automake manual: *The AC_CONFIG_FILES macro declares the list of files that configure should create from their *.in templates. Automake also scans this list to find the Makefile.am files it must process. [...] when adding a new directory to your project, you should add its Makefile to this list, otherwise Automake will never process the new Makefile.am [...])*. Since %C% and %D% are automake 1.14 specific, I conclude that it should be save to call it `Makefile.am`. Fell free to refute this if this wrong. – lanoxx Jun 04 '14 at 19:55