Defining additional make targets using gnu autotools - makefile

I am beginning to learn autotools in order to first understand and later extend an existing project's build system. Currently the project builds a program as it's output. The build system is quite complex consisting of several subdirectories and Makefile.am's with files generated in a maintainer-mode and so on. I would like to optionally be able to create a library using much of the same source code, reusing much of the the existing build system.
What I am imagining is a new make target so that after running configure, I can then run either make to make the program, or, say, make library to build the library. What is the correct way to do this or something with a similar effect?
I do not want to build both the library and program when I run plain make (just the program as before), and I do not want to build the program when I run make library (I only want the library).
If someone could provide a simple example, e.g. a program made up of main.c, foo.c and bar.c and a library made up of foo.c and bar.c that would be really helpful too.
EDIT
To clarify, I originally thought that the program and lib could be built entirely separately. The library contains only a subset of the code of the main program, and I believed the two were separate entities. However, things are more complicated. The program itself is built and used to output some code which is then compiled into the program in a second step (I think). I have effectively got what I want by doing the following steps.
First add a conditional to configure.ac
dnl Adds LIBRARY conditional for --enable-foolib mode to
dnl build foo as a library
AC_ARG_ENABLE(foolib,
AS_HELP_STRING([--enable-foolib],
[enable qucslib build, default: no]),
[case "${enableval}" in
yes) foolib=true ;;
no) foolib=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-foolib]) ;;
esac],
[foolib=false])
AM_CONDITIONAL(FOOLIB, test x"$foolib" = x"true")
Then in the appropriate Makefile.am I did something similar to the following:
if FOOLIB
noinst_LIBRARIES = libbar.a libfoo.a
else
noinst_LIBRARIES = libbar.a
endif
bin_PROGRAMS = barprog
barprog_SOURCES = main.cpp src1.cpp src2.cpp etc.cpp
barprog_LDADD = libbar.a \
subdir1/libsubdir1.a \
subdir2/libsubdir2.a \
etcdir/libetc.a
... other stuff
if FOOLIB
libfoo_a_LIBADD = libbar.a \
subdir1/libsubdir1.a \
subdir2/libsubdir2.a \
etcdir/libetc.a
libfoo_a_SOURCES = src1.cpp src2.cpp etc.cpp
endif
Then when I want to make the library I do
configure --enable-foolib
make
This works for now, but seems kludgy. I wasn't sure though how to implement the provided answer in the build system.

If the program depends on the library, then it will not be possible to build the program without building the library. You already have the ability to build individual libraries: configure && make libfoo.a should work just fine (or make libfoo.la). If you wish a target named library, you can simply add the following to any Makefile.am:
library:
libfoo.a
(Or you may need libfoo.la. Basically, if the library is specified in Makefile.am under the LIBRARIES primary, then you would use libfoo.a, but if specified under an LTLIBRARIES primary, you would use libfoo.la.) This will only create a library target in each directory that contains a Makefile.am. If you have a complex recursive build (you should really simplify it, but that's another question), you can put something like the following in your top-level Makefile.am to build the libraries throughout the tree:
library:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) library
This assumes you have added a library target to subdir/Makefile.am as described above.
To be pedantic, you might want to use $(am__cd) instead of cd, but it's not strictly necessary.

Related

make is not using -std=c++11 option for g++

I am trying to compile c++ files using make. But, it is not using -std=c++11 flag by default. Whenever I need to compile a program which uses c++11 specific features, I have to explicitly compile it using g++.
So, I want to ask how can I have make automatically use the option -std=c++11 for all my c++ files on my system.
If I need to change some global makefile for g++ , what is the location of the makefile on Linux Mint 18 and what needs to be changed or added?
Or do I need to create a Makefile for myself?
EDIT 1: I am invoking make like make myfile
And there are only .cpp files and their binaries in the directory. I don't have any Makefile in the directory.
EDIT 2: Here, myfile is the name of the c++ file which I want to compile.
When I run make with the -d option, I get the following output (I can not paste all of the output as it is quite long and is exceeding the body size limit so, I am including the screenshots of the output).
Image 1
And this image(2) has some lines from the end.
Image 2
I intentionally made a change in the file "MagicalWord.cpp" so that make finds something to make!
There is no "global makefile" and there is no way to change the default flags for all invocations of make (unless you edit the source code to GNU make and compile it yourself, which is a bad idea in this situation).
In your makefile(s), add the line:
CXXFLAGS += -std=c++11
Assuming you're using the built-in rules for compiling things, or that you're using the standard variables with your own rules, that will do what you need.
If that doesn't work we'll need to see your makefile or at least the rules you use to build your C++ source files (things like the -d output aren't useful here--that would be interesting if files weren't being built, that you thought should be or similar).
Setting a system-wide language for all your C++ projects isn't necessarily a good idea. Instead, define a Makefile that specifies any compiler options you'd like:
CXXFLAGS := -std=c++11 $(CXXFLAGS)
The CXXFLAGS are then passed to your compiler when compiling a C++ program (assuming you're using the default GNU Make rules).
If the Makefile lives in your current working directory, you can now run make target in order to compile a target.cpp file into a target executable.
If the Makefile is in another directory, you must specify the path to it:
make -f path/to/your/Makefile target
If you want to add extra parameters just for one run, you can set an environment variable or a make variable on the command line:
# environment:
CXXFLAGS='-std=c++11' make target
# make variable:
make target CXXFLAGS='-std=c++11'
Any of these will cause the execution of g++ -std=c++11 target.cpp -o target or equivalent.
In theory you can edit your shell profile to export CXXFLAGS='-std=c++11' which will make that environment variable available to all programs you run. In practice, setting compiler options through environment variables tends to cause more problems than it solves.
Of all these solutions, just writing a normal Makefile is by far the easiest approach. That way, all of the build configuration is in one place and completely automated.

Allow automake to generate optional compile rules

I have made changes to a program which are part of a much larger project which use the Intel Performance Primitives. It turns out my recent changes use calls which are only available on the newest version of IPP, while a number of the users still use older versions. The program in question is not essential, so I want make it optional rather than back porting to the oldest versions of IPP (IPP has had a lot of API changes over the years).
We use automake/autoconf for generation of Makefiles. Ideally my particular program (single source file in C) would not be compiled by default, unless someone specifically runs "make myprog".
Is there a way to do this or do I have to support a "--with-myprog" option for the configure script?
The Makefile.am currently has (I think this is all that is relevant)
bin_PROGRAMS = \
stripVDIF \
{snip}
generateVDIF
generateVDIF_SOURCES = \
generateVDIF.c
generateVDIF_LDADD = $(IPP_LIBS) $(LDADD)
My program is generateVDIF
If you do not want it to be installed you can simply declared it as EXTRA_PROGRAMS rather than bin_PROGRAMS and that should do exactly what you want (only works with make myprog).
If you want it to be installed, you'll have to use AC_ARG_WITH and AM_CONDITIONAL in configure.ac and then have something like
bin_PROGRAMS = ....
if ENABLE_MYPROG
bin_PROGRAMS += myprog
endif
and the rest remains the same.
The right way to do this is to place the build of your optional
program under the control of a ./configure option, so that ./configure
can manage it appropriately. See e.g. how to add configure options
If that sounds too much like hard work you could exploit the fact that
additional make code within a Makefile.am is simply passed through to the
generated Makefile.
So, e.g. if the following is the Makefile.am for target foo:
EXTRA_DIST = README
bin_PROGRAMS = foo
foo_SOURCES = foo.c
and you want to add an unmanaged target bar, a program built from bar.c,
then you can extend the Makefile.am to:
EXTRA_DIST = README bar.c
bin_PROGRAMS = foo
foo_SOURCES = foo.c
bar: bar.o
$(CC) $(LDFLAGS) -o$# $< $(LDLIBS)
The autotooled package will then support make bar, and you could document this fact
for the user, with the appropriate caveats - notably including the absence of the usual autotooled install and uninstall.
Obviously, this shortcut would detract from a knowledgeable user's impression
of your professional chops.

Out of tree kernel modules: Multiple module, single Makefile, same source file, different build options

I am building a set of Linux kernel modules using shared source code. From what I understand, the Makefile has to be named "Makefile" so I have to use the same Makefile to build two different modules. How can I build two different modules, within the same Makefile, with the same source code, but with two different build options?
For example, my modules are called module1 and module2. So I have the following line to define them:
obj-m := module1.o module2.o
Among other files, both module1 and module2 need to use the same source file code.c, but built with different build options. So say for example, the Makefile contains the following lines:
module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o
I want module1_code.o and module2_code.o to be built from code.c, but with different options. Specifically, I want one module1_code.o with a macro defined -DPREPROCEFFOR_FLAG=1, and module2_code.o built without the macro.
From what I understand, the system of Makefiles used in Linux implicitly infers that for an object file called "code.o", the source file is called "code.c", so how would I achieve this? Is is possible? Is there a better way to do this?
You have a problem here, because you obviously have code.c being compiled differently when -DPREPROCEFFOR_FLAG=1 is defined, but once it's compiled into code.o, make won't care about preprocessor flags or whatever because code.o will be already up to date.
You need a way to build code.c to different object files with different C flags. There's probably a clean way to do this (had no chance with O= for out of tree modules), but here's my innelegant yet effective solution for the moment:
my_modules:
cp code.c code_noflags.c
cp code.c code_withflags.c
make -C $$KDIR M=$$PWD modules
rm code_noflags.c code_withflags.c
# module objects
obj-m := module1.o module2.o
# module1 specifics
module1-y := code_withflags.o
CFLAGS_code_withflags.o := -DPREPROCEFFOR_FLAG=1
# module2 specifics
module2-y := code_noflags.o
Just call:
$ make KDIR=/path/to/kernel
You can verify the preprocessor flag is passed to the source file for the right object with:
$ make KDIR=/path/to/kernel V=1 | grep PREPRO
You could also have two separate directories for each module, if this is possible, and have a symbolic link code.c in each one pointing to the common real code.c. However, this is still hackish and doesn't feel right.
One simple solution is, continuing from your Makefile
obj-m := module1.o module2.o
module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o
to add two more source files, module1_code.c and module2_code.c.
Then module1_code.c just looks like:
#define PREPROCEFFOR_FLAG 1
#include "code.c"
and module2_code.c is:
#include "code.c"
Or if you like, change the names in the Makefile and source files so that the second include without a define isn't necessary. Also you could make the two source files nothing but an include and use the CFLAGS_module1_code.o variable to add the -D... option to the compiler if you prefer.
This is similar to what happens in the upstream kernel with arch/x86/boot/video-vesa.c and arch/x86/realmode/rm/video-vesa.c etc., where the realmode file just contains:
#include "../../boot/video-vesa.c"
and the video-vesa.c code ends up getting compiled twice with different compiler flags.
This seems preferable to copying the source files, since you end up with a mess there if you want to use the O=... option to the kernel build to keep a clean source tree and build in a separate object tree.

Evaluate automake variable only once

We are using automake & autoconf to build our multi-package software. I was wondering how to fill a variable with the output of e.g. shell-scripts once and reuse this, e.g. for needed include dirs
INCLUDES := -I`some-ext-config --incdir`
Using := instead of = here makes this variable filled once so some-ext-config will only be called once (AFAIK this comes from plain make). Of course INCLUDES is the depreciated cousin of AM_CPPFLAGS, but would I have used that one instead, the shell script would have been called for each compile.
Using INCLUDES instead of AM_CPPFLAGS is an acceptable solution for me (though I imagine there might be portability issues), but I have no solution for e.g. LDFLAGS for a libtool library
libmylib_la_LDFLAGS := `some-ext-config --ldflags` # will always be evaluated
What is the general solution inside automake if I want to make sure these external tools are not called multiple times? I would like to stay away from using an obvious AC_SUBST in configure.ac since we have to make sure our packages can be build both from subdirectories (some configure.ac in there) and with an recursive make from the top-level and a configure.ac there which shouldn't need to know too much about the different subprojects.
:= is GNU-make specific, so you are advised to use just = in automake. If you do not want to run the shell script everytime INCLUDES (or AM_CPPFLAGS, does not matter, it would occur with either), then run the script in configure.ac and use variable substitution via AC_SUBST. That is essentially what pkg-config would do — and come to speak of it, you could just use that instead of some-ext-config if there is a .pc file.
# configure.ac
libfoo_CPPFLAGS=$(some-ext-config --incdir);
libfoo_LIBS=$(some-ext-config --libs);
AC_SUBST([libfoo_CPPFLAGS])
AC_SUBST([libfoo_LIBS])
# Makefile.am
AM_CPPFLAGS = -Iwhatever ${libfoo_CPPFLAGS}
bin_PROGRAMS = foo
foo_LDADD = ${libfoo_LIBS}
This is a more lengthy explanation of what I suggested in a comment to jørgensen's answer.
I understand your top-level configure.ac must generate the makefiles of multiple sub-projects, and performs the required tests so that you don't have to run the configure in any subproject (a sub-configure serves only when you want to work on this particular sub-project).
In that case, you want to avoid duplicating as much stuff as possible from various configure.ac. I suggest you factor all the code of the sub-configure that must also be performed by the top-level configure in an m4 macro. This includes tests, AC_SUBSTS, and Makefile declarations.
For instance using only one-subproject. Here is a top-level ./configure.ac:
AC_INIT([toplevel], [1.0])
AM_INIT_AUTOMAKE([foreign -Werror])
SUB1_COMMON([sub1/]) dnl Stuff from the subproject
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
With ./Makefile.am:
ACLOCAL_AMFLAGS = -I sub1/m4
SUBDIRS = sub1
Now here is sub1/configure.ac for the sub-project:
AC_INIT([sub1], [1.0])
AM_INIT_AUTOMAKE([foreign -Werror])
AC_CONFIG_MACRO_DIR([m4])
SUB1_COMMON
AC_OUTPUT
With SUB1_COMMON defined in m4/common.m4:
AC_DEFUN([SUB1_COMMON],
[AC_SUBST([PYTHON3LIB], [`pkg-config --libs python3`])
AC_CONFIG_FILES([$1Makefile])])
And finally sub1/Makefile.am is just:
ACLOCAL_AMFLAGS = -I m4
# Build something.
...
The SUB1_COMMON contains all the code you want to share between the two configure.ac files, and use argument $1 to relocate the config files appropriately. In this example, the variable PYTHON3LIB will be defined regardless of which configure were run.

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