0
votes

I am trying to understand a makefile from a project I am working on. It's using automake/autotools and contains this simple rule:

DEPS_SRC = $(shell cd $(srcdir); find . -name '*.ez')
DEPS = $(basename $(DEPS_SRC))
all : $(DEPS)

$(DEPS) : % : %.ez
  $(UNZIP) -o $<

Say the directory structure is:

my-app/deps/
build/

When executing make my-app in the build folder the rule will basically unpack *.ez files located in the my-app/deps/ folder into build/my-app/deps/ folder.

I don't know if that's enough information to solve the problem that I am going to explain as I don't know enough about automake/autotools. Please ask if any additional information is needed.

The problem is that I noticed that having the unpacked directory in the source folder prevents make from unpacking the archive in the target folder. For example, given the following structure in the source folder:

my-app/deps/archive1.ez
my-app/deps/archive2.ez
my-app/deps/archive2/

make will only unpack archive1.ez in the build folder:

build/my-app/deps/archive1/

I would like to know if this is a bug in my makefile or a feature of automake. If the later, is there any workaround or setting or variable available to disable it?

1
There is nothing specific to the Autotools in the Makefile fragments you have presented. They do rely on GNU extensions to make itself, however. - John Bollinger
I guess, though, we can assume that the Makefile overall contains the Autotools-standard tooling for supporting out-of-source builds. - John Bollinger

1 Answers

1
votes

This is primarily a GNU make question, not particularly specific to the Autotools. However, since the target system's make is of GNU's flavor (else none of this works), we can assume that the Makefile generated by configure uses GNU make's VPATH feature as part of its support for out-of-source (a.k.a. VPATH) builds such as the one you are performing.

The value of the VPATH variable that configure will have inserted into the Makefile is used as a search path for prerequisites that are not found relative to the build directory. The key point, however, is that it is also used as a search path for rule targets. That makes a certain amount of sense, especially for targets that are prerequisites of other rules.

In your case, however, that leads directly to the behavior you describe:

  • the default target depends on ./my-app/deps/archive2
  • resolving that name against the build directory does not produce a valid file name
  • before attempting to build that target, make looks in the directories listed in the VPATH, which, in your example case, will contain .. or an equivalent
  • make finds .././my-app/deps/archive2 in this VPATH search, and therefore determines that the specified target already exists, and does not need to be built

Thus, the behavior you observe is normal for GNU make, supposing the Makefile is constructed by Autoconf from an Automake-generated template.

is there any workaround or setting or variable available to disable it?

Do you really need one? If the archive file has already been unpacked in the source tree, then you can expect make to find its contents, too, via the VPATH. At least if the Makefile is well-prepared overall for for out-of-source builds.

But if you want to be certain to get the archive files unpacked in the build directory then you can specify that explicitly. This ought to do it:

DEPS_SRC = $(shell cd $(srcdir); find . -name '*.ez')
DEPS = $(basename $(DEPS_SRC))
LOCAL_DEPS = $(addprefix $(abs_builddir)/,$(DEPS))
all : $(LOCAL_DEPS)

$(LOCAL_DEPS) : $(abs_builddir)/% : %.ez
  $(UNZIP) -o $<

That prefixes the name of each dependency with the absolute path to the build directory, and updates the rule for unzipping the archives to accommodate it. Targets with absolute paths such as that cannot be located in the VPATH.