7

I'm currently working on a C++ project which relies on recursive automake for building. I want to build a shared library and the Makefile.am in the src directory of the library looks like

# ...

# Library name
lib_LTLIBRARIES = libadapter-@MY_API_VERSION@.la

# Sources
libadapter_@MY_API_VERSION@_la_SOURCES = \
    $(top_builddir)/src/sourceA.cpp \
    $(top_builddir)/src/sourceB.cpp

# ...

Since version 1.14, automake issues a warning when the subdir-objects option is not specified in AM_INIT_AUTOMAKE in configure.ac. However, adding the subdir-objects option seems to break the build process with make complaining about missing .Plo files. I already searched the web for people experiencing similar problems but did not find any sensible hint on how to resolve the issue without changing the project to a non-recursive one. Any help is greatly appreciated.

EDIT: Diving more deeply into the problem, I noted that ./configure creates a directory literally named $(top_builddir) below the current source directory of the library, which contains all the required .Plo files for building the library. In the Makefile, however, I found that the .Plo equivalents of my library sources (sourceA.cpp and sourceB.cpp in the example) are prefixed by include $(top_builddir)/src/$(DEPDIR)/ and $(top_builddir) is a variable defined as a relative path (namely, ../../../src/.deps/). Now it becomes clear why make can't find the .Plo files because it searches the wrong directory. This looks like a possible duplicate of bug #16375. Any workarounds?

EDIT 2: Digging further in the web revealed two more threads which address the issue: #1327 and automake-bug. A known workaround seems to be passing the --disable-dependency-tracking option to ./configure. At least for me it works.

Marcel
  • 616
  • 1
  • 5
  • 15
  • Are you using [relative paths](https://www.flameeyes.eu/autotools-mythbuster/automake/nonrecursive.html) for the SOURCES? – Brett Hale Feb 06 '14 at 19:25
  • FWIW, I get this message too with automake 1.14 (non-recursive build, no relative paths). Currently, my strategy is to ignore the warning until I find a way to not goof up the build. Seems to build OK (for now...). – ldav1s Feb 06 '14 at 20:45
  • @ldav1s - Interesting. Do you use ACLOCAL_AMFLAGS in top-level Makefile.am? What about the AM_INIT_AUTOMAKE options? – Brett Hale Feb 06 '14 at 21:57
  • I use `ACLOCAL_AMFLAGS` just to set the macro path (`-I ...`). The `AM_INIT_AUTOMAKE` options are set by `AUTOMAKE_OPTIONS`: `1.11 foreign`. That's it. – ldav1s Feb 06 '14 at 22:51
  • OTOH, maybe I'm _not_ using relative paths. Maybe I have to switch `top_srcdir` to `abs_top_srcdir` and `top_builddir` to `abs_top_builddir`. Hmm... – ldav1s Feb 06 '14 at 22:57
  • @ldav1s - Sounds about the same as what I use. Don't seem to have any trouble with `top_builddir` or `top_srcdir`, but this issue seems to be popping up with 1.14.x in a lot of places. – Brett Hale Feb 06 '14 at 23:31
  • @ldav1s - Actually, it looks like a warning to smooth the transition to 2.0, which will "unconditionally activate the 'subdir-objects' option..." (in the automake NEWS file). – Brett Hale Feb 06 '14 at 23:40
  • @Marcel - if you could provide the offending `Makefile.am`? – Brett Hale Feb 06 '14 at 23:54
  • @Brett I added the contents of the `Makefile.am` to my question. – Marcel Feb 07 '14 at 12:06
  • @ldav1s I also tried changing from `top_builddir` to `abs_top_builddir` but get the same error (missing `.Plo` files). – Marcel Feb 07 '14 at 12:07
  • @Brett Answering your first comment: Yes, I did use relative paths but also tried absolute paths (see my previous comment) but still get the same error (missing `.Plo` files). Do you see any problems in using relative paths? – Marcel Feb 07 '14 at 12:19
  • @BrettHale, I remember reading that NEWS file a couple months ago when I ran into this issue the first time I tried building with automake 1.14. Then I remember trying `subdir-objects`, which broke my build. – ldav1s Feb 07 '14 at 16:02
  • Can you tell me the detailed steps to solve it because I have met the same problem. And I am a Chinese student at libproess ,I can't understand what they wrote bellow. – shengfu zou Jul 26 '16 at 01:45
  • I had exact same issue, with automake-1.14.1. Originally I had `libMyLib_la_SOURCES=$(top_srcdir)/external/http_parser.c` which failed (it created a directory called top_srcdir). I replaced it with a relative path and it worked: `libMyLib_la_SOURCES=../external/http_parser.c`. Also added the `subdir-objects` as advised. – Darren Smith Aug 17 '16 at 20:02

1 Answers1

11

From the automake-1.14.1 NEWS file:

The next major Automake version (2.0) will unconditionally activate
the 'subdir-objects' option.  In order to smooth out the transition,
we now give a warning (in the category 'unsupported') whenever a
source file is present in a subdirectory but the 'subdir-object' is
not enabled.  For example, the following usage will trigger such a
warning:

        bin_PROGRAMS = sub/foo
        sub_foo_SOURCES = sub/main.c sub/bar.c

So in preparation for this, you need subdir-objects as one of the options in AM_INIT_AUTOMAKE, if you use subdirectories in 'object' names as described above. This option will be 'on' by default in 2.0.

If you could provide the Makefile.am for the directory that fails, it might provide a clue as to why the relative directories aren't matching up.


Ok, there a couple of things about this Makefile.am. Firstly, there are ways to correctly version a libtool library, and @MY_API_VERSION@ substitutions aren't the way to go. You could form a numeric string for example, in configure.ac, followed by AC_SUBST(MY_API_VERSION).

In Makefile.am : libadapter_la_LDFLAGS = -release $(MY_API_VERSION) will put this information in the libadapter.la libtool meta-file.

For serious version control, where interface compatibility, revisions, binary compatibility, etc., are desirable, you can have a look at the libtool reference on versioning. Important system libraries, particularly GNOME/GTK (look at their configure.ac files!), go all-out on this stuff. I certainly don't, unless I'm considering releasing something into the wild. I still find it confusing.

Omitting @MY_API_VERSION@, you can also stick with libadapter_la_SOURCES. However, the source files aren't found relative to any builddir path, which was perhaps the source of your .Plo file issue. The builddir variables describe where the built components are found - you can also build out-of-tree, and this is a good test to see if your automake setup is robust. Some packages promote this, e.g., go to the top of the package, make a directory there called build or my_build or whatever suits:

cd my_build; ../configure <options>; make

The package, it's source tree and recursive directories will be left alone, everything will be built under the my_build directory, and the subdirectories will mirror those of your source tree, only they will be full of built objects, libraries, executables, etc. make install should also work perfectly using the generated my_build/Makefile.

But returning to the point - those source files are relative to the $(srcdir) directory, which corresponds to the current (recursive) Makefile.am's directory. The various builddir and srcdir variables are described here.

If your src directory is located under the top-level directory, you could use: "$(top_srcdir)/src/sourceA.cpp" - notice that "$(srcdir)/src/sourceA.cpp" would be wrong, as it would be like specifying "$(top_srcdir)/src/src/sourceA.cpp" in this case.

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

libadapter_la_SOURCES = sourceA.cpp sourceB.cpp

It is also perfectly acceptable to put any header files in the src directory used by libadapter in the SOURCES list. A change of a header will rebuild what's required.


Anyway, I didn't mean to write this much, but I know how frustrating it is get clear information about the autotools. The Autotools Mythbuster provides excellent 'walk-through' tutorials, and stays very up to date.

Brett Hale
  • 21,653
  • 2
  • 61
  • 90
  • I already was aware of this snippet from the `automake` `NEWS` file but from what I understand, `automake` should work smoothly if the `subdir-objects` option is simply added to `AM_INIT_AUTOMAKE` in `configure.ac` - no matter if relative or absolute paths are used in `Makefile.am`. Please correct me if I'm wrong. – Marcel Feb 07 '14 at 12:18
  • @Marcel - I've tried to address the issues in your `Makefile.am`. I hope you find it helpful. – Brett Hale Feb 07 '14 at 19:22
  • Thank you very much for this exhaustive answer. I see the difference between `top_srcdir` and `top_builddir` but I don't understand why exchanging the latter by the former should make any difference for in-tree builds, which is what I do at the moment. Also, omitting the `MY_API_VERSION` should not contribute to resolving the issue. In the meantime, I think I have found the reason for the failing build, see my updated question. – Marcel Feb 10 '14 at 11:39
  • Yes, I did, but without any effect - the error remains. – Marcel Feb 11 '14 at 07:57
  • Adding "subdir-objects" to my AM_INIT_AUTOMAKE fixed my issue. thanks. – thedoctar Sep 06 '20 at 12:41