Symbols ($(bindir), $(sysconfdir),...) unknown in (sub) Makefiles - makefile

I'm working with autotools for the first time, for a tool that's written in perl (SQLTeX), so only installation is required, no compilation.
The toplevel contains a simple Makefile.am:
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src man doc
EXTRA_DIST = README.md
.PHONY: all-am
all-am:
#echo "Done!"
If I create Makefile.am files in the sub-directories too, nothing seems to happen there so I just stick to Makefile. A snippet from src/Makefile (EDIT: this file is now renamed to Makefile.am):
SQLTeX: SQLTeX.pl
cat $^ | sed -e 's#{PERLDIR}#$(PL)#;s#{SYSCONFDIR}#$(sysconfdir)#' > $#
#chmod +x $#
The symbol PL is set as expect (defined in the same makefile), but sysconfdir is empty, although it is defined in the top-level Makefile generated by ./configure.
What am I doing wrong?
Thanks in advance!

What am I doing wrong?
Although the Autotools support, with some caveats, recursing into directories where you provide pre-built makefiles, you cannot expect those pre-built makefiles to be able to rely on autotools-provided variables such as the standard directory variables bindir and sysconfdir. Thus, although it is allowed to rely on hand-written makefiles in subdirectories, this is probably a false trail for you.
I recommend going back to this:
If I create Makefile.am files in the sub-directories too, nothing seems to happen there
and working out what's wrong. The Autotools definitely support generating recursive build systems, and one Makefile.am per directory is part of the usual approach to that. If it didn't work for you then my first guess would be that you forgot to list the extra makefiles in your AC_CONFIG_FILES list.
As an alternative, just because you have multiple directories does not mean that you need to use recursive make. It is quite possible to build such a project with the support of a single makefile, and the Autotools can help with such a makefile.

Related

Number Files to get rebuilt by Make

Is there a way to let make determine the number of files to be recompiled before actually compiling? The problem is this: Consider having a quite big project with hundreds of source files. It would very convenient to have a rough idea of how long compilation will take, but to know that, one needs to know the number of files to be compiled.
The general answer is no, because your build could generate files which themselves are inputs to other rules which generate more files. And so on. However if a rough answer is good enough you can try the --dry-run flag. From the GNU make documentation...
“No-op”. Causes make to print the recipes that are needed to make the targets up to date, but not actually execute them. Note that some recipes are still executed, even with this flag (see How the MAKE Variable Works). Also any recipes needed to update included makefiles are still executed (see How Makefiles Are Remade).
As you can see, despite its name even the --dry-run flag will change the state of your build.
"make -n" will do the dry run. But you can't get the list of files to be rebuilt. May be you can write shell script to store the last modified time of files and get the list of files.
I think a found a decent solution for unix. Here SRC are your source files, HDR your headers and DEP the dependency files (something like DEP:=$(OBJ:.o=.d) )
isInDepFile+=$(shell grep -q $(modifiedFile) $(depFile) 1>&2 2> /dev/null && echo $(depFile))
COMPFILES=
checkDepFiles=$(foreach depFile,$(DEP), $(eval filesToCompile+=$(isInDepFile))) $(thinOutDepFiles)
thinOutDepFiles=$(foreach fileToCompile,$(filesToCompile),$(eval DEP=$(filter-out $(fileToCompile),$(DEP))))
countFilesToCompile: $(SRC) $(HDR)
$(eval modifiedFiles=$?)
$(foreach modifiedFile,$(modifiedFiles), $(call checkDepFiles))
$(eval numOfFilesToCompile = $(words $(filesToCompile)))
$(eval numDepFiles = $(words $(DEP)))
$(eval NumSRCFiles = $(words $(SRC)))
#echo $(NumSRCFiles) sources
#echo $(numDepFiles) files to leave
#echo $(numOfFilesToCompile) files to compile
#touch $#
This first generates a list of modified files within your source and header files lists. Then for each modified file it checks all dependency files for its filename. If a dependency file contains the current file we are looking at, it is added to the list of filesToCompile. It is also removed from the list of dependency files to avoid duplication.
This can be invoked in the main building rule of your project. The advantage of that over the dry run is that it gives you a simple number to work with.

Makefile pattern rules not working

I am learning makefiles, and can't just wrap my head around this problem i am having, and would like to understand how/why this fail.
I have half a dozen erlang files in a src directory. I want to compile these into a ebin directory, without having to define a rule for each and every one of them. According to the Gnu make documentation, pattern rules should be right up my alley.
However, with the following makefile, all I get from make is make: *** No targets. Stop. Why is that?
ebin/%.beam: src/%.erl
mkdir -p ebin
erlc -o ebin $<
Edit: Based on this answer, I now understand that i would have to explicitly declare the targets, for instance by using make ebin/cmplx.beam. However, i still do not understand how i should write my makefile to get my desired behaviour - since I have half a dozen targets (and in other projects even more), this seems like an unnecessary hassle. Is there not a way to define targets based on the source file names?
The target rule tells make that whenever it needs to produce a beam file in the ebin directory, and there exists a corresponding erl file in the src directory, it can use erlc.
However, this doesn't tell make that this is what it needs to do. You could explicitly tell make what it needs to do by giving it a target on the command line:
make ebin/foo.beam
If you don't give a target on the command line, make will pick the first non-pattern rule in the makefile as its target. However, your makefile doesn't have any non-pattern rules, so there is no target.
What you probably want is that for each existing erl file in src, make should consider the corresponding beam file in ebin to be a target. You can achieve that by calling wildcard and patsubst:
erl_files=$(wildcard src/*.erl)
beam_files=$(patsubst src/%.erl,ebin/%.beam,$(erl_files))
ebin/%.beam: src/%.erl
mkdir -p ebin
erlc -o ebin $<
all: $(beam_files)
(The indented lines need to be actual physical tabs, not spaces.)
That way, running make will rebuild all beam files that are out of date. all gets chosen as the default target, and it in turn depends on all beam existing or potential, each of which in turn depends on the corresponding erl file.
This trick is described in the GNU make manual.

GNU Make -- Append to a variable all targets matching a pattern

Before I start, I'll mention that I'm not using GNU Make in this case for building a C/C++ project.
Makefile:
DEST_DIR = build/
SRC_DIR = src/
$(SRC_DIR)a/ : $(SOMETHING_ELSE)
$(DO_SOMETHING_TO_GENERATE_A_DIR)
$(DEST_DIR)% : $(SRC_DIR)%
cp -r $^ $#
ALL_DEPS += <SOMETHING>
... more code which appends to ALL_DEPS ...
.PHONY: all
all : $(ALL_DEPS)
I've got some files not generated via Make rules in $(SRC_DIR). (For the sake of this example, let's say there's a directory $(SRC_DIR)b/ and a file $(SRC_DIR)c .)
I want to append to ALL_DEPS all targets which represent files or directories in $(DEST_DIR) so that "make all" will run all of the available $(DEST_DIR)% rules.
I thought to do something like this:
ALL_DEPS += $(addprefix $(DEST_DIR),$(notdir $(wildcard $(SRC_DIR)*)))
But of course, that doesn't catch anything that hasn't yet been made. (i.e. it doesn't append $(DEST_DIR)a/ to the list because $(SRC_DIR)a/ doesn't yet exist when the $(wildcard ...) invocation is evaluated and the shell doesn't include it in the results returned by the $(wildcard ...) invocation.)
So, rather than a function which finds all (currently-existing) files matching a pattern, I need one which finds all targets matching a pattern. Then, I could do something like this:
ALL_DEPS += $(addprefix $(DEST_DIR),$(notdir $(targetwildcard $(SRC_DIR)*)))
If it matters any, I've got much of the GNU Make code split across multiple files and included by a "master" Makefile. The ALL_DEPS variable is appended to in any of these files which has something to add to it. This is in an attempt to keep the build process modular as opposed to dropping it all in one monster Makefile.
I'm definitely still learning GNU Make, so it's not unlikely that I'm missing something fairly obvious. If I'm just going about this all wrong, please let me know.
Thanks!
It is simply not possible to do what you're trying to do; you're trying to get make to recognise something that doesn't exist.
This is part of the reason why, in general, wildcards are bad (the other being that you can end up including stuff you didn't mean to). The right thing to do here is to explicitly create a list of source files (ls -1 | sed -e 's/\(.*\)/sources+=\1/' > dir.mk) and perform the patsubst transformation on that list.
If you have additional files that are generate as part of the build, then you can append them to that list and their rules will be found as you'd expect.

How do you compile without linking in Automake?

I am new to Automake and I am attempting to compile without linking. My goal is to generate a simple Makefile as shown below using Automake.
CFLAG = -Wall
build: Thread.o
Thread.o: Thread.cc Thread.h
g++ $(CFLAG) -c Thread.cc
clean:
rm -f *.o
My attempt so far has brought me to the following Makefile.ac.
noinst_PROGRAMS = thread
thread_SOURCES = Thread.cc
EXTRA_DIST= Thread.h
How can I simulate my original Makefile?
One way is to do this is to fool Automake by providing link command that does not link:
thread_LINK = true
Other than that, I wouldn't be suprised if Automake did not have such feature.
For your example, you can just ask Automake to build your .o file directly, e.g.:
$ make Thread.o
I believe this is an implicit rule, so you won't see it in the output Makefile.
In general, Automake generates variables containing all the objects required for each executable or library target. It's pretty straightforward to use them in your Makefile, since it just generates their names by appending _OBJECTS to the target name. You could make your own target in Makefile.am like this:
build-thread: $(thread_OBJECTS)
Then you could build just Thread.o (and any other objects needed for thread) like this:
$ make build-thread
Or if you had multiple targets foo, bar, and baz, you could make your compile-only target in Makefile.am like this:
build: $(foo_OBJECTS) $(bar_OBJECTS) $(baz_OBJECTS)
The only pain here is that you'll need to maintain this list yourself based on the targets in your Makefile.am. You can invoke it at the command line like this:
$ make build
Automake is not designed to produce object. It will build either programs or libraries.
It's hard to answer your question without knowing why you'd want to compile a single object file and not something else. Maybe there is a cleaner answer to your "real" problem.
A Makefile.am you could write is
noinst_LIBRARIES = libThread.a
libThread_a_SOURCES = Thread.cc Thread.h # No need to put headers in EXTRA_DIST
The resulting Makefile would build a library libThread.a containing only libThread.o, ans because *.a libraries are just a collection of object files there is no linking involved.
The above Makefile.am also causes the emitted Makefile to contain rules to compile libThread.o, so you can add a build: rule if you like.
If you really want Automake to emit this compile rule, but not build the library, you could go with
EXTRA_LIBRARIES = libThread.a # EXTRA here means "output build rules but don't
# build unless something depends on it".
libThread_a_SOURCES = Thread.cc Thread.h
build: Thread.$(OBJEXT)
Now you are explicitely requiring the file Thread.$(OBJEXT) to be built only when you type make build, as in your original Makefile.
(Automake uses .$(OBJEXT) rather than .o to support extensions like .obj in DOS variants.)
First off, automake is a tool to auto make making Makefiles; make in and of itself is a whole different beast (and I'm pretty sure that what you were looking for was a make solution).
Here's the easiest GNU based Makefile to accomplish what you want:
all: Thread.o
This fills in something (by default) like the following (please change 4-space whitespace to hard tabs):
all: Thread.o
Thread.o: Thread.cc
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
The COMPILE.cpp and OUTPUT_OPTION macros of course expand by default to GNU make specified values and aren't portable; $< is AT&T Make standard syntax though according to pmake(1)'s manpage though.
GNU make has a concept of implicit vs explicit rules, patterns, suffixes, etc that you could use, but that's not portable to all versions of make, and hence that's why all of the Makefile is plainly spelled out in terms of targets and variables as POSIX doesn't describe many of the desired scenarios for how one should write a Makefile.
Run gmake -p for more details and take a look at the texinfo manual for gmake in the topic of implicit, explicit rules, patterns, suffixes, etc.

Separating objects and source with a makefile

I have been having troubles getting my makefiles to work the way I want. First off, I would like to say this is POSIX make, as in http://www.opengroup.org/onlinepubs/009695399/utilities/make.html I am needing my build system to work with both BSDs and GNUs(Linux).
What I am wanting is a zero maintenance makefile. I want it to just compile all .c and .asm files in src/ and place the object files in objs/ and then to link everything in objs/ to a binary file.
I can do a lot, but I can't get it to separate the source and obj files.
I am ok if this requires a little built-in shell scripting (using POSIX defined /bin/sh), but I can just not get the dependencies to work right. I want it to only build the object file if the source file is newer.
My closest is this:
${C_OBJS}: ${HDRS} ${*:objs/%=src/%}.c
${CC} ${CFLAGS} -c ${*:objs/%=src/%}.c -o $*.o
This has the problem that I must still specify C_OBJS=objs/foo.o and such and also it is just barely not POSIX and therefore, compiles with BSD make but not GNU make.
The POSIX version of make does not explicitly support file names with slashes in them, nor does it make provision for separating source files in a different directory from the object files. And, as noted by #caskey, it does not support any notation using '%' characters, though it notes that such rules exist and recommends that they be reserved for use as metacharacters.
Consequently, you probably cannot do what you want with standard POSIX make.
In practice, you can often do what you seek with specific implementations of make, but the resulting makefile has limited portability.
Consider using a makefile generation systems of some sort - cmake or the auto-tools (autoconf, libtool, automake, etc). Or one of the many reworkings of the basic concepts of make:
scons
ant
cake
cook
bras
...and a dozen I've forgotten or not heard of...
POSIX make doesn't support constructs like?
objs/%.o : src/%.c
${CC} ${CFLAGS} -c $< -o $#
Forgot the question mark at the end, hope that makes my comment more clear.

Resources