Automake and external conditional sources - makefile

How to properly define external conditional sources in a Makefile.am file?
As an example, in GNU MPFR, we currently have in src/Makefile.am:
if MINI_GMP
nodist_include_HEADERS += $(mini_gmp_path)/mini-gmp.h
noinst_LTLIBRARIES = libminigmp.la
nodist_libminigmp_la_SOURCES = $(mini_gmp_path)/mini-gmp.h $(mini_gmp_path)/mini-gmp.c
libmpfr_la_LIBADD += libminigmp.la
endif
where MINI_GMP is true when mini_gmp_path is defined. The goal is to optionally build MPFR against a libminigmp library (mini-gmp), which is itself built with the autotools machinery (same compiler, same options, etc. as MPFR).
Everything seems to work well, except when one does not want to build against mini-gmp. In this case, the generated configure script fails with:
configure: creating ./config.status
config.status: creating Makefile
config.status: creating mpfr.pc
config.status: creating doc/Makefile
config.status: creating src/Makefile
config.status: creating tests/Makefile
config.status: creating tune/Makefile
config.status: creating src/mparam.h
config.status: creating tools/bench/Makefile
config.status: executing depfiles commands
config.status: error: in `/home/vlefevre/software/mpfr':
config.status: error: Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).
See `config.log' for more details
and in the config.log file:
config.status:19572: executing depfiles commands
config.status:19647: cd src && sed -e '/# am--include-marker/d' Makefile | make -f - am--depfiles
/bin/mkdir: cannot create directory '/.deps': Permission denied
make: *** [/tmp/GmlvxQJQ:720: /.deps/mini-gmp.Plo] Error 1
The reason is that the generated src/Makefile file contains things like $(mini_gmp_path)/$(DEPDIR)/mini-gmp.Plo while mini_gmp_path is not defined. But since one does not want to build against mini-gmp, such information about mini-gmp.Plo is incorrect, i.e. mini-gmp files should completely be ignored for automatic dependency tracking when MINI_GMP is false.
As a workaround, we currently define mini_gmp_path to . in configure.ac when one does not build against mini-gmp, so that the $(mini_gmp_path)/$(DEPDIR) directory exists, avoiding a configure failure. But this is not a clean solution, which might interfere with mini-gmp.{c,h} files that could be added in the MPFR source tree. The solution should just get rid of mini-gmp.Plo entirely.

I don't think incorporating external sources into your build is a supported use case. It certainly does not make much sense to me. Nevertheless, possible alternatives include
Bundle the minigmp sources with your project (their use can still be optional). This has the additional advantage that you can be sure you provide a compatible version.
Add standard make rules to create the minigmp sources in some existing directory inside the project by copying them from $(mini_gmp_path). You may also want to list the minigmp sources (in the internal directory) among your BUILT_SOURCES.
if MINI_GMP
noinst_LTLIBRARIES = libminigmp.la
libmpfr_la_LIBADD += libminigmp.la
nodist_libminigmp_la_SOURCES = minigmp/mini-gmp.h minigmp/mini-gmp.c
BUILT_SOURCES = $(nodist_libminigmp_la_SOURCES)
# Are you want the mini-gmp header to be installed?
nodist_include_HEADERS += minigmp/mini-gmp.h
else
noinst_LTLIBRARIES =
BUILT_SOURCES =
endif
minigmp/mini-gmp.c: $(mini_gmp_path)/mini-gmp.c
cp $< $#
minigmp/mini-gmp.h: $(mini_gmp_path)/mini-gmp.h
cp $< $#
Automake should not subject such rules to the same level of analysis that it does the variables that are meaningful to it.
Put the onus on the project builder to build and install a compatible version of minigmp. Link against that.

Related

GNU make - enforcing target order

Could someone please tell me if there is a way to enforce sequential execution of specific Makefile targets. For example, I have a Makefile that builds Libraries and Executables. Now, Executables depend on Libraries, so they must be built after the Libraries are built and staged. This is what I currently have in a single Makefile:
.PHONY: all
all: all_lib all_bin
.PHONY: all_lib
all_lib: $(dep_lib)
.PHONY: all_bin
all_bin: $(dep_bin)
I have two targets all_lib and all_bin, one builds all libraries and the other builds all binary executables. When I pass -j to make to run parallel jobs, I get build failures, because all targets run in parallel and binaries can't find shared library objects and staged header files.
I tried changing it to this to try and force some dependency order:
.PHONY: all
all: all_bin
.PHONY: all_lib
all_lib: $(dep_lib)
.PHONY: all_bin
all_bin: all_lib $(dep_bin)
But for some reason all targets still run in parallel I still get the same build failures. Any ideas?
Make is entirely built around the concept of dependencies. You are simply not using it that way.
If an executable depends on a library, then you should list that library in the prerequisites list of the executable. I can't give you a relevant example because you don't provide any details about the contents of dep_lib or dep_bin above, but for example:
exe1 : exe1.o liblib1.a liblib2.a
etc. Now, exe1 won't attempt to be linked until after the liblib1.a and liblib2.a targets have been created.

Libtool: Makefile.am call a Makefile in some other directory

Deal All,
I have a library that is built with libtool. I have an additional module that has been built using a Makefile but not using libtool. I want to be able to use this library object along with the ones that libtool builds. Since I do not want to integrate the additional module with libtool, I just want to expand the Makefile generated from libtool on the lines of:
all: all-am
(instead:)
all: new-module all-am
new-module:
-cd new-module-src && $(MAKE)
Thanks
How can I do this in the Makefile.am?

"Makefile:26: *** missing separator" - Makefile condition

I am having some trouble to compile GCC. When I try to compile it, this error appears:
Makefile:26: *** missing separator. Stop.
The line 26 refers to the first line of this condition:
#if gcc
ifeq (,$(.VARIABLES)) # The variable .VARIABLES, new with 3.80, is never empty.
$(error GNU make version 3.80 or newer is required.)
endif
#endif gcc
I already tried to insert a TAB between the keywords but it didn't work. The only thing I tried and seems to work is to change the condition to:
ifeq ($(gcc),)
ifeq (,$(.VARIABLES)) # The variable .VARIABLES, new with 3.80, is never empty.
$(error GNU make version 3.80 or newer is required.)
endif
endif
Informations:
Make log: http://pastebin.com/t5eNYJd5
Make log (after changing the condition): http://pastebin.com/HHjQKdDx
My make version is: 4.0.
GCC version I am trying to build: 5.2.0
I am using fedora 22.
I've got a workaround. The problem is that the Makefile contains hundreds of '#if', therefore, I would like to know why is it using '#if' if they do not work ?
Thanks in advance.
I stumbled upon this same problem. This question is a little old and it looks like you found a workaround, but I'll document my findings here as well for the People of the Future.
Background
GCC currently requires you to perform an out-of-source build. Based on the commands shown, some of the documentation and online QA implies that this is valid:
svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc;
gcc/configure <configure options>;
make -j 8 && make install;
This nests the source directory in the build directory, but I would expect that to count as "out-of-source." Running without -j 8 still produced the problem. I did this on a RHEL6 system, using GNU make 4.2. I was attempting to build GCC 8.0.0.
Solution
I found that making the source and build directories adjacent rather than creating builddir/sourcedir resolved the problem.
Additional info
Here's are relevant snippets from the GCC build instructions:
We use srcdir to refer to the toplevel source directory for GCC; we use objdir to refer to the toplevel build/object directory.
...
If you obtained the sources via SVN, srcdir must refer to the top gcc directory, the one where the MAINTAINERS file can be found, and not its gcc subdirectory, otherwise the build will fail.
...
First, we highly recommend that GCC be built into a separate directory from the sources which does not reside within the source tree. This is how we generally build GCC; building where srcdir == objdir should still work, but doesn’t get extensive testing; building where objdir is a subdirectory of srcdir is unsupported.
Depending on your definition of "source tree", these instructions may or may not proscribe building the way I first attempted. They should probably be updated to clarify this case.
As to the specific reason that Makefile won't run, that snippet is not valid make syntax - if is not a make keyword, and referenced variables must be enclosed like so: $(varname). # simply prevents the command from being echoed.
Rather, this is supposed to be multiline interpolated bash. This StackOverflow answer shows this being done in a Makefile, but it's done as part of a recipe. I see no evidence that this is valid as a standalone entity.
In the correctly-generated Makefile, the section you posted is absent, and all interpolated bash appears in a recipe.

libtool and Windows DLLs

I have an difficult relationship with the GNU autotools, especially libtool. But because they kick ass when it comes to portability and cross compilation I started using them again.
Unfortunately I can't get libtool to build proper windows DLLs. Yet with vanilla make gcc
will happily build the DLL for me.
For example:
LIBEXT = .dll
pkzo$(LIBEXT): $(patsubst %.cpp, %.o, $(pkzo_SOURCES)) resources.o
$(CXX) -shared -fPIC $(CXXFLAGS) $^ $(LDFLAGS) -Wl,--out-implib=libpkzo.lib -o $#
Will haily build a DLL and import library. (Even without any annoying decelspec).
Yet if I use libtool like so:
lib_LTLIBRARIES = libpkzo.la
libpkzo_la_CXXFALGS = ...
libpkzo_la_LDADD = ...
libpkzo_la_SOURCES = ...
Libtool comes complaining:
*** Warning: linker path does not have real file for library -lSDL2main.
*** I have the capability to make that library automatically link in when
*** you link to this library. But I can only do this if you have a
*** shared version of the library, which you do not appear to have
*** because I did check the linker path looking for a file starting
*** with libSDL2main and none of the candidates passed a file format test
*** using a file magic. Last file checked: /usr/local/lib/libSDL2main.a
*** Since this library must not contain undefined symbols,
*** because either the platform does not support them or
*** it was explicitly requested with -no-undefined,
*** libtool will only create a static version of it.
Well guess what libSDL2main.a is a static library and has no DLL.
It there a way to build a DLL with automake not using libtool or telling libtool to stop making a fuss about nothing?
PS: Before anyone mentions it, I am configuring libtool with LT_INIT([shared static win32-dll])
For the first problem, make sure you have a shared version of the SDL library installed.
If you absolutely must link your DLL to static libs, you can trick libtool into doing it by editing the libtool script. E.g., if you want all of the dependent libs statically linked to your DLL, you can do that by putting this at the end of your configure.ac:
sed -i '/^whole_archive_flag_spec=/s/"$/ \\${wl}-static"/' libtool
Now, this is a gross hack and relies on the particular way that libtool builds command lines right now, so there's no guarantee that it will continue to work---but it does work with libtool 2.4.2. Since you have just one library which you want statically linked, you could achieve that by applying sed a bit differently. Probably you'll want
sed -i '/^whole_archive_flag_spec=/s/"$/ \\${wl}-static \\${wl}-lSDL2main \\${wl}-shared"/' libtool
in order to keep shared linking with whatever other shared libs you have, and then you'll need to take -lSDL2main out of wherever else you have it. This is gimpy, but the thing you're trying to do is also gimpy and libtool isn't made for this.
For the second problem, add -no-undefined to libpkzo_la_LDFLAGS.

autotools: force make not to rebuild configure/Makefile

I have a project with autotools: automake, autoconf.
I want to prohibit make from remaking files configure, Makefile.in, etc; just to do compile job.
Some of files are edited by hand, and I know that I should not to do this. (Or the project was updated from CVS with all generated files stored in CVS).
But at the moment I have no correct version autotools installed.
What must be modification times of this files (which must be newer/older):
aclocal.m4
configure.in
confdb/ax_prefix_config_h.m4
Makefile.am
Makefile.in
Makefile
configure
config.status
Or: what sequence of touch commands must I do to achieve my goal?
First of all, if you edit a generated file directly, it wouldn't be rebuilt anyway, because it is then newer then its prerequisites.
Then, there are two separate things going on here: config.status and Makefile are created during the build. It's hard to prevent these from being remade during the build unless you make their timestamps newer.
The other files are generated by the various autotools. Recent versions of Automake do not create rules by default that remake them automatically. Depending on your package, you might want to use the configure option --disable-maintainer-mode. The Automake documentation contains some more interesting information about that option.
One trick I sometimes use with a package that I don't know much about or that has a pretty messed up build system is to run something like
make all AUTOCONF=: AUTOHEADER=: AUTOMAKE=: ACLOCAL=:
so that if these programs happen to be called, a noop would be substituted.
touch confdb/*.m4
touch configure.in
touch *.m4
touch *.am
touch Makefile.in */Makefile.in
touch *config.h.in */*config.h.in
touch configure
touch config.status
touch config.h
touch Makefile
Problems with automake & cvs are described here http://www.gnu.org/s/hello/manual/automake/CVS.html
Try to explicitly tell make those files should not be remade, via command-line
$ make -o configure -o Makefile.in
or by using MAKEFLAGS
$ MAKEFLAGS="-o configure -o Makefile.in" make
The excerpt from GNU make's manual
‘-o file’
‘--old-file=file’
‘--assume-old=file’
Do not remake the file file even if it is older than its prerequisites, and do not remake
anything on account of changes in file. Essentially the file is treated as very old and
its rules are ignored. See Avoiding Recompilation of Some Files.
If yours autotools template correctly uses $(MAKE) for subdirs, there should be no problems.

Resources