Create data file by Automake - automake

I want Automake to create an .img file in my hobby project (to test the compiled program in a virtual machine).
I can use Automake to compile programs, eg.:
noinst_PROGRAMS = loader.elf
loader_elf_SOURCES = init.s console.c disk.c elf.c ext2.c fat.c lib.c loader.c multiboot.c
loader_elf_LDFLAGS = $(AM_LDFLAGS) -T $(srcdir)/loader.ld
loader_elf_LDADD = $(LDADD) -lgcc
But it doesn't work for data files:
noinst_DATA = x.img
x_img_DEPENDENCIES = loader.elf
x_img_LINK = makeimg.sh
When I execute autoreconf -i then I get this error message:
automake: warnings are treated as errors
arch/i386/emulator/Makefile.am:14: warning: variable 'x_img_DEPENDENCIES' is defined but no program or
arch/i386/emulator/Makefile.am:14: library has 'x_img' as canonical name (possible typo)
autoreconf: automake failed with exit status: 1
I'm trying to turn my Makefile into Makefile.am. It was as simle in Makefile as:
x.img: loader.elf
makeimg.sh $# $<
I studied the Automake manual at the gnu ftp page, and I think there is no possibility to add sources or dependencies to a DATA file in Automake. What should I do? Should I put the .img file into the PROGRAMS primary instead of DATA?
I'm using Automake 1.16.1 and Autoconf 2.69 (if that matters).

Simply add this to the Makefile.am:
noinst_PROGRAMS = loader.elf
loader_elf_SOURCES = ...
noinst_DATA = x.img
x.img: loader.elf
makeimg.sh x.img loader.elf
(I have changed the $# and $< to use the explicit names as there are apparently some versions of make which have difficulties with $# and $< in rules which are defined by explicit file names, instead of by patterns or suffixes.)

Related

With autotools how do I get pandoc to run in the src dir next to c programs

I am creating a c program where I use a design.md document inside the src directory so the design is close to the source code. I use autotools, but I do not know how to get automake to run pandoc next to the c compiler. This is my Makefile.am:
bin_PROGRAMS = brun
AM_CFLAGS = -Wall -Wextra -std=c11
AM_LDFLAGS = -rdynamic
lib_LTLIBRARIES = libbrun.la
libbrun_la_SOURCES = Object.c Box.c Module.c
libbrun_la_LDFLAGS = -version-info 0:0:0
brun_SOURCES = main.c
brun_LDADD = libbrun.la
include_HEADERS = Object.h Object.r.h Box.h Box.r.h Module.h Module.r.h
# EXTRA_DIST = Object.r Box.r Module.r
#
%.pdf: %.md
pandoc -o $# $<
The above code does nothing to generate my files design.md and todo.md which are in the src directory.
I have searched for clues how to do this but most results point to how to use autotools for compiling or just contain general tutorials. I have been searching for a day or so and my have become blind to the obvious.
Does anyone know how to get automake to run pandoc, next to compiling my c sources?
You have provided a make rule that describes how to build PDFs from your .md files, but your Makefile.am doesn't anywhere express that any PDF files actually should be built, much less which ones.
For files that you want to have installed (and why are you building docs if you don't want to install them) the specifics depend on where you want them to go, but for example,
pkgdata_DATA = design.pdf todo.pdf
That would build them as part of make all and install them to a subdirectory of $(datadir) during make install (probably something like /usr/local/share/brun).
If for some reason you want the files built, but not installed, then you could instead use
noinst_DATA = design.pdf todo.pdf
Either way, since you're relying on a suffix rule for unusual suffixes, you'll probably also have to tell Automake about them:
SUFFIXES = .md .pdf
Note well that make recognizes a similar construct, but you should not use make's variation in Automake; instead, use the above variable-assignment form, and Automake will handle converting that for make's use.

GNU autotool:No rule to make target

my first question in stack overflow!
Quick overview of my question: I use autotool to generate a C program. When I use make command, I meet the error:
No rule to make target `../lib_foo/libfoo.a', needed by `mistery_foo'. Stop.
Something detail of my questions:
I am doing an assignment of my teacher, in which I should use GNU autotool to generate a very simple C program.
File structure: /project: main, lib_foo, Makefile.am, configure.ac
/project/main: main.c, main.h, Makefile.am
/project/lib_foo: foo.c, foo.h, Makefile.am
Following is what I write for configure.ac and makefile.am:
I. "project/configure.ac":
AC_PREREQ([2.67])
AC_INIT([project1],[0.01],[cwentai01#gmail.com])
AM_INIT_AUTOMAKE([1.9 foreign])
AC_CONFIG_SRCDIR([./lib_foo/foo.c])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_PROG_RANLIB
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <mistery.h>]],\
[[ mistery_value(1);]])],\
[AC_DEFINE([MISTERY_VALUE_ONEPARAM], [],[CONSTANT])],[])
AC_SEARCH_LIBS([mistery_value],[magic vadoo mistery],[],[AC_MSG_ERROR([Libraries (mistery, magic, vadoo) not found])])
AC_CONFIG_FILES([Makefile lib_foo/Makefile main/Makefile])
AC_OUTPUT
P.S. the AC_COMPLIE_IFELSE is used to judge the number of the parameters in function mistery_value(). I think it has nothing to do with the error.
II. project/Makefile.am:
SUBDIRS = main lib_foo
III. project/main/Makefile.am
LDADD = ../lib_foo/libfoo.a
mydir = ../uselessbin
my_PROGRAMS = mistery_foo
mistery_foo_SOURCES = main.c main.h
mistery_foo_LDADD = ../lib_foo/libfoo.a
IV. project/lib_foo/Makefile.am
noinst_LIBRARIES = libfoo.a
libfoo_a_SOURCES = foo.c foo.h
Then I run with the order of commands:
>cd project
> aclocal
> autoheader
> automake -a
> autoconf
> ./configure
> make
> make install
> ./uselessbin/mistery_foo
When I run make command, I got the error:
No rule to make target `../lib_foo/libfoo.a', needed by `mistery_foo'. Stop.
I suppose the problem may be that I don't have libfoo.a properly installed. But the library libfoo.a should not be installed but only compiled so I have to use 'noinst_' in lib_foo/Makefile.am. That's why I get stucked here.
Any answers will be appreciated.
Thanks for your help!
The problem is that you're using recursive automake, and in this case, dependencies crossing directory paths will just not resolve to extra rules: main/Makefile.am does not know how to make targets in lib_foo.
The quick fix up is to change your SUBDIRS declaration in the top-level Makefile.am to:
SUBDIRS = lib_foo main
This way main/mystery_foo will only be built after lib_foo and its targets are built. Of course this does not allow you to just make in main/ and have it work.
The other suggestion from the previous post, to use non-recursive automake is a more proper solution, because then all the dependencies can be resolved from a single Makefile.am.
Your procedure looks mostly totally fine. I just found a few possible mistakes:
Your configure.ac should have LT_INIT instruction
In project/main/Makefile.am I would change ../lib_foo/libfoo.a to libfoo.a
If the previous doesn't work, I would recommend to have a single Makefile.am and not recursive Makefile.am (Recursive Makefile.am can be harder to code and might damage the performance of the compilation)

Compile multiple executables from multiple source directories to single bin directory using makefile

I'm trying to create a makefile for a suite of programs that I am working on. The programs are all written in fortran and the source files are contained in different directories. I can't seem how to figure out how to get things to work. My current sumfile is
#Compiler and compiler flag variables
FCOMP=/usr/local/bin/gfortran
F_FLAGS=-O2 -fbounds-check -Wall
F_FLAGSDB=-g -fbounds-check -Wall
#paths to libraries
COMMON_LIB=/usr/local/lib/libspc_common.a
SPICE_LIB=/usr/local/lib/spicelib.a
# Paths to directories
BIN_DIR=BIN
# Get file names of component source files
#get names of files in src1
FORT_FILES=$(wildcard ./SRC1/*.f)
#get names of files in src2
FORTFILES+=$(wildcard ./SRC2/*.f)
#get names of files in src3
FORTFILES+=$(wildcard ./SRC3/*.f)
#get file names for output
EXE_FILES=$(addprefix $(BIN_DIR),$(notdir $(patsubst %.f, % , $(FORTFILES))))
# make commands
# Set the default option to compile the library with optimization
default: all
# create all command
all: $(EXE_FILES)
#echo toolkit has been built with optimization
#If compiling for debugging replace the compiler flags to remove optimization and add debugging
debug: F_FLAGS=$(F_FLAGSDB)
#Run compiler with debugging flags
debug: $(EXE_FILES)
#echo toolkit has been built with debugging
# Compile all of the source files into executables
$(EXE_FILES): % : %.f
$(FCOMP) $(F_FLAGS) $^ $(COMMON_LIB) $(SPICE_LIB) -o $(BIN_DIR)/$#
# install the library in /usr/local/lib
install:
cp -p $(BIN_DIR)* /usr/local/bin/toolkit/
# remove executable files for a clean build
clean:
rm $(BIN_DIR)*
The problem I am running into is that I get the following error when I try to run make:
make: *** No rule to make target `Display.f', needed by `Display'. Stop.
which I am assuming is because I have lost the directory that the source file comes from. Can someone help me here? I am totally stuck and don't know how to proceed.
In addition (this is more a general question about make), is there a way to tell make to recompile everything if the COMMON_LIB changes?
Thanks for your help!
Suppose your source files are
SRC1/alpha.f
SRC1/beta.f
SRC2/gamma.f
SRC3/delta.f
1) There is a flaw here:
EXE_FILES=$(addprefix $(BIN_DIR),$(notdir $(patsubst %.f, % , $(FORTFILES))))
This will produce
BINalpha BINbeta BINgamma BINdelta
when I think you intended
BIN/alpha BIN/beta BIN/gamma BIN/delta
A simple fix:
EXE_FILES=$(addprefix $(BIN_DIR)/,$(notdir $(patsubst %.f, % , $(FORTFILES))))
2) Now look at the static pattern rule:
$(EXE_FILES): % : %.f
...
So to build BIN/alpha, Make must first find BIN/alpha.f, which doesn't exist. To make it look for alpha.f, do this:
$(EXE_FILES): $(BIN_DIR)/% : %.f
...
3) How to find the sources?
You could do some delicate coding to help Make remember where it found alpha.f, but there's no need when we can use the vpath directive:
vpath %.f SRC1 SRC2 SRC3
4) One last look at that rule:
This command:
$(FCOMP) $(F_FLAGS) $^ $(COMMON_LIB) $(SPICE_LIB) -o $(BIN_DIR)/$#
Will produce e.g. BIN/BIN/alpha, which is silly. A non-PHONY Make rule should produce a file whose name is the target of the rule. It prevents a lot of trouble.
$(FCOMP) $(F_FLAGS) $^ $(COMMON_LIB) $(SPICE_LIB) -o $#
A few further refinements may be possible, once you have this working perfectly.

Makefile.am - Manual target prerequisite + addprefix?

I have a autotool project where part of the source code is downloaded dynamically from the net (because of IP rights preventing direct redistribution) and then built.
I have a Makefile.am that works but I'm not happy about some of it's aspects.
Here it is:
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS = -fPIC -Wall ${SYMBOL_VISIBILITY}
LIBVERSION=0:0:0
REFSRC_PATH=refsrc
REFSRC_SRC=refsrc/dtx.c refsrc/globdefs.c refsrc/host.c refsrc/mathhalf.c refsrc/sp_enc.c refsrc/sp_rom.c refsrc/vad.c refsrc/err_conc.c refsrc/homing.c refsrc/mathdp31.c refsrc/sp_dec.c refsrc/sp_frm.c refsrc/sp_sfrm.c
${REFSRC_PATH}/.downloaded:
./fetch_sources.py "${REFSRC_PATH}"
for f in `ls -1 "${REFSRC_PATH}"/*.{c,h}`; do \
sed -i -e"s/round/round_l2s/" "$$f"; \
done
touch $#
${REFSRC_PATH}/dtx.c: ${REFSRC_PATH}/.downloaded
lib_LTLIBRARIES = libgsmhr.la
libgsmhr_la_SOURCES = libgsmhr.c $(REFSRC_SRC)
clean-local:
-rm -rf ${REFSRC_PATH}
So essentially, libgsmhr.c is my main wrapper, then I download the source code in a refsrc/ subdirectory and patch it a little.
First problem is that in REFSRC_SRC I would have loved to use a $(addprefix ...) instead of repeating refsrc/ in front of each .c file. But that doesn't seem to work and autoreconf complains a little.
Failure details (when removing the refsrc/ prefix from REFSRC_SRC= and using $(addprefix ${REFSRC_PATH}/, ${REFSRC_SRC}) on the dependency list):
bash$ autoreconf -i
libgsmhr/Makefile.am:19: addprefix ${REFSRC_PATH}/, ${REFSRC_SRC}: non-POSIX variable name
libgsmhr/Makefile.am:19: (probably a GNU make extension)
(configure works fine)
bash$ make
...
make[2]: Entering directory `/tmp/ram/gapk.build/libgsmhr'
CC libgsmhr.lo
CCLD libgsmhr.la
make[2]: Leaving directory `/tmp/ram/gapk.build/libgsmhr'
...
(So as you see it didn't include any of the downloaded .c files, didn't even download them at all. The compile works because libgsmhr.c is a stub that doesn't use the symbols in those file yet)
Second problem is this rule:
${REFSRC_PATH}/dtx.c: ${REFSRC_PATH}/.downloaded
I have to explicitely list the first file (dtx.c) instead of using a wildcard like:
${REFSRC_PATH}/%.c: ${REFSRC_PATH}/.downloaded
If I try to use the wildcard, then autoreconf complains and also it just doesn't work ... (pattern doesn't match somehow).
Failure detail:
bash$ autoreconf -i
libgsmhr/Makefile.am:16: `%'-style pattern rules are a GNU make extension
(configure works fine)
bash$ make
...
make[2]: *** No rule to make target `refsrc/dtx.c', needed by `dtx.lo'. Stop.
...
Sylvain
You seem to be writing a makefile in GNUMake style, but actually running some other version of Make. If it's not obvious what autoreconf is calling, you could insert a rule in the makefile:
dummy:
#echo using $(MAKE)
$(MAKE) -v
If this theory proves correct, you can either persuade autoconf to use GNUMake, or write for the version it's using.

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.

Resources