I am using a custom compilation chain, and I have multiple targets that needs to be compiled, however they need to be compiled using different cxx compilers. Is this possible to do using automake? It seems it is not possible to do something like:
target_CXX = ...
Ideally I would want something like:
target1_SOURCES = ...
target2_SOURCES = ...
target1_CXX = ...
target1_CXXFLAGS = ..
target2_CXX = ...
targer2_CXXFLAGS = ...
Or even better actually, having target1 use the defined target1_CXX and target2 using the normal CXX flag.
Target1 should be a noinst, and only generate object files. These object files should be then used in target2 (defined using LDADD) to generate the full binary.
Thanks!
What you are describing can be done with autotools, but not easily. By default, autotools only uses one toolchain (the host toolchain, e.g. CC, CXX, etc.). It's also possible to use the build toolchain also.
What you're going to have to do in this situation will be very similar to what AX_PROG_CXX_FOR_BUILD (the build toolchain macro referenced above, and its dependent macros) does. Basically, it makes another copy of all the C++ compiler tests with a different set of output variables.
Then something like:
$(target1_OBJECTS) := $(target1_SOURCES:.cc=.o)
$(target1_OBJECTS) : CXX = $(CXX_FOR_BUILD)
$(target1_OBJECTS) : CXXFLAGS = $(target1_CXXFLAGS)
$(target1_OBJECTS) : CPPFLAGS = $(CPPFLAGS_FOR_BUILD)
...
target2_LDADD = $(target1_OBJECTS)
might work to link them together.
Related
I am building a library (using Autotools) that looks like the following. The building of the library works fine when I add a *.cpp file to libmytest_la_SOURCES.
lib_LTLIBRARIES = libmytest.la
libmytest_la_SOURCES = test.capnp.c++
libmytest_la_CXXFLAGS = -I/usr/include -I$(top_srcdir)/src/includes
libmytest_la_LDFLAGS = -version-info 0:0:0 -L/usr/lib64
libmytest_la_LIBADD = -lcapnp
The problem is that I need to call a third-party compiler to generate code before doing the normal compile process. The following capnp tool will generate a c++ output file named test.capnp.c++.
capnp compile -oc++ test.capnp
And if I plug the output of that (test.capnp.c++) into the makefile above, my library is built. What I don't get is how to invoke that command into the Makefile.am to generate the needed source file and plug it into the libmytest_la_SOURCES variable.
Any thoughts?
Automake does not have direct support for capnp, and adding support for a new language or tool would involve hacking the program. But you can provide ordinary make rules in your Makefile.am file, and these will be carried through to the final generated Makefile. This is Automake's primary extension point.
Thus, you might add this to your Makefile:
test.capnp.c++ : test.capnp
capnp compile -oc++ $<
# or
# $(CAPNP) compile -oc++ $<
# where $(CAPNP) is the capnp binary as discovered by configure
You would want to also designate test.capnp as an additional file to distribute:
EXTRA_DIST = test.capnp
You should also consider whether you want the .c++ file to be included in distribution packages, to relieve the build-time dependency on capnp. If not, then instead of listing it in libmytest_la_SOURCES you should list it in nodist_libmytest_la_SOURCES, plus also in CLEANFILES:
#
# test.capnp.c++ is a built file that we choose not to distribute
#
nodist_libmytest_la_SOURCES = test.capnp.c++
CLEANFILES = test.capnp.c++
# or: CLEANFILES = $(nodist_libmytest_la_SOURCES)
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.
I couldn't find anything in the GNU Makefile Conventions.
This is the implicit naming convention followed by GNU Makefile documentation:
Targets
Target names should use lower case letters. Words are separated with a hyphen - or not separated. E.g.:
test-debug:
$(build_dir)/debug/bin
or
testdebug:
$(build_dir)/debug/bin
Variables
Variables that are not special to make, and that are not inherited from the environment, should be in lowercase. Words should be separated with underscore symbol _. E.g.:
src_dir = $(CURDIR)/src
build_dir = $(CURDIR)/build
References:
Makefile style guide (based on GNU Makefile
documentation)
GNU Makefile Standard Targets
targets: you can find targets like install, install-strip, installcheck
variables: you can read "This includes the directories specified as the values of the variables prefix and exec_prefix" within the install target documentation
The most used (I think) are all, clean, compile, run, install, test, and all common task that you may need to build whatever you're buinding.
You could study makefiles inside big projects such as Linux, Vim, etc, but if you want to get standards into your project you will want to use Autotools as well.
For small projects, I usually use meaningful names based on the context, so I can do something like this:
$make compile (to compile)
$make lib (to create the libraries)
$make link (to link the objects into the executable)
$make run (to run the program)
$make all (to make all of them at once)
and, to make this happen as expected, I have to insert dependencies like:
all: run
run: link
# Instructions for run
link: lib
# Instructions for link
lib: compile
# Instructions for make the lib
compile:
#Instructions for compilation
Makefile's implicit rules use a set of common variable names which are used by convention for explicit rules, such as:
CC: C compiler
CFLAGS: C compiler flags
CXX: C++ compiler (CPP is for C preprocessor)
CXXFLAGS: C++ compiler flags
LDFLAGS: Extra flags for linker, such as -L
LDLIBS: Library flags, such as -lm
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.
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.