Is there a way to have a conditional passed through automake so it is passed on to the resulting Makefile.in and Makefile later on?
I check whether JAVA_HOME is defined in the environment in a Makefile using
ifeq (undefined,$(origin JAVA_HOME))
#CALL with defaults
else
#CALL according to the variable
endif
But when I process this in a Makefile.am with automake I get two erros:
else without if
endif without if
Looks like automake does not digest the ifeq. Is there a way to pass this through it (if it makes sense doing so), or is there another autotools-friendly way of getting the same result?
The idea is also to allow setting/changing the variable just before running make to easily target different JDKs.
What I think's the right way:
Rely on $(JAVA_HOME) being set in Makefile.am and make sure a sensible value for it is set by configure.
Answering the Question as Written:
Because automake wants to generate Makefiles that work on POSIX make, it doesn't work too well with GNU-make conditionals.
So you do the test in configure.ac:
AC_SUBST([JAVA_HOME])
AM_CONDITIONAL([JAVA_HOME_SET], [test ! -z "$JAVA_HOME"])
Then in Makefile.am:
if JAVA_HOME_SET
## Something that relies on JAVA_HOME
else
## Defaults
endif
Related
I am stuck with a strange variable expansion. Let me explain.
I have a project that uses automake, composed by configure.ac, Makefile.am.
Basically, in Makefile.am I'm doing:
ARCH = $(shell ${CURDIR}/./arch.sh)
...
noinst_HEADERS = license/${ARCH}/lchecker.h
proj_SOURCES = main.c license/${ARCH}/lchecker.c
proj_LDFLAGS = -avoid-version -Llicense/${ARCH}
./arch is doing just uname -m to determine the architecture needed, because I have to enter the correct directory.
When I run the build, I have this error:
Makefile:622: license/x86_64/.deps/lchecker.Po: No such file or directory
make[1]: *** No rule to make target 'license/x86_64/.deps/lchecker.Po'. Stop.
and if I enter the license directory, I notice a new dir created called ${ARCH}/ where I find the missing .deps from license/x86_64.
I'm pretty sure it is an incorrect expansion problem; I've tried many ways but I failed.
Can anyone explain to me the right way to do this? Reading around the net I see that Makefile.am has a different syntax from Makefile.
UPDATE:
I tried to add some changes to see if the variable is corretly defined:
AC_DEFINE([ARCH], ["$ARCH"], [arch check])
echo ARCH = "$ARCH" printf x86_64
so the variable in defined in configure.ac, but the expansion is not correct again in Makefile.am.
In your configure.ac, use the macro AC_SUBST(varname,[value])
to create a make-variable varname in each the generated makefiles that will
have the value to which value was evaluated at the time when the makefile was generated.
value may be a shell-expansion. So e.g.
AC_SUBST(ARCH,[`./arch.sh`])
in configure.ac will create in each makefile the assignment:
ARCH = x86_64
assuming that x86_64 is the standard output of ./arch.sh at ./configure-time
in the build directory. You may then assume that this variable is so assigned
in your Makefile.am and write the like of:
noinst_HEADERS = license/${ARCH}/lchecker.h
I am dealing with autotools and here is the situation:
By default libdir is set to '${exec_prefix}/lib' with exec_prefix set to '${prefix}' and prefix set to '/usr/local'.
Key here recursion and at first level libdir variable contain another variable and a following path.
So how to convert ${libdir} into a variable containing '/usr/local/lib' ?
Info : all 3 (libdir, exec_prefix, prefix) can change according configuration.
Consider the following files:
configure.ac
AC_PREREQ([2.59])
AC_INIT([test], [0.0.0] )
AM_INIT_AUTOMAKE()
AC_CONFIG_SRCDIR([test.cpp])
AC_LANG([C++])
AC_PROG_CXXCPP
AC_PROG_CXX
AC_CONFIG_FILES([Makefile path.conf])
AC_MSG_NOTICE([">>> Before ac_output prefix=${prefix}"])
AC_OUTPUT
AC_MSG_NOTICE([">>> after ac_output prefix=${prefix}"])
Makefile.am
bin_PROGRAMS = test
test_SOURCES = test.cpp
test.cpp
int main()
{}
path.conf.in
#libdir#
Then after invoking :
aclocal && autoconf && automake -a --foreign && ./configure
configure log show:
configure: ">>> Before ac_output prefix=NONE"
...
...
...
configure: ">>> after ac_output prefix=/usr/local"
And generated file path.conf contains
${exec_prefix}/lib
The goal is to have a variable containing the expanded version of the path to be used in a path.conf.in so autotools generate path.conf with that expanded path.
Edit: Bash only solution
Digging related topics and helped by #Aserre answer, I manage to do the following with a regex.
while expr match "${libdir}" '^.*\$.*$' 1>/dev/null;
do
echo ">${libdir}"
libdir="$(eval echo ${libdir})"
done
Which means : While $libdir contain one $ expand with eval.
But does not work in configure.ac script before AC_OUTPUT
The goal is to have a variable containing the expanded version of the path to be used in a path.conf.in so autotools generate path.conf with that expanded path.
The Autotools provide special handling for default values of the installation-directory variables, in order to enable the user to specify or override the installation prefix at make install time:
make install prefix=/my/special/prefix
What you propose to do will break that. If a user specifies a different installation prefix at the installation stage than they tell configure (or that they let configure choose by default) then you will end up with a broken installation.
The best way to do address problems like this is to build the configuration file under make's control, at make install time, instead of doing it at configuration time. If the project uses Automake, then that might mean something like this:
install-data-local:
$(SED) -e 's,[#]libdir[#],$(libdir),' path.conf.in > $(sysconfdir)/path.conf
chmod 0644 $(sysconfdir)/path.conf
chown root:root $(sysconfdir)/path.conf
uninstall-local:
rm $(sysconfdir)/path.conf
You can of course substitute more output variables than that if you like. It's pretty close to what configure does itself.
And of course, if you do it this way then you do not need to worry about performing extra expansions.
If you are 100% sure of the content of the ${exec_prefix} variable, you could use the following line to achieve what you want :
libdir="$(eval echo ${exec_prefix})"
Note that in a lot of cases, the use of eval is discouraged. Here, if the user has overriden the content of the variable exec_prefix, for instance with exec_prefix='a; rm -rf /', all the code written will be executed.
If you are in total control of your environment (i.e. you are certain of the value of the variables when you launch the script), there should be no problem, otherwise be wary of the potential side effects
I have a makefile that looks something like this:
include anotherFile.mk
all:
someStuff
The file anotherFile.mk is like this:
include yetAnotherFile.mk
export SOME_VAR = 93
The problem is that anotherFile.mk and yetAnotherFile.mk are in a different directory from my Makefile. So my makefile can't just be changed to this:
include $(OTHER_PROJECT_PATH)/anotherFile.mk
all:
someStuff
The problem with this approach is that the include statement in anotherFile.mk will fail because it will be searching in the current directory.
A partial solution that I found is to pass the --include-dir=$OTHER_PROJECT_PATH flag to the invocation of make, but that's a bit user-unfriendly.
So my question is: Is there something I can put inside my makefile that will add to the directories that make searches for when executing an include? Something like MAKE_INCLUDE_DIRS += $(OTHER_PROJECT_PATH)
Surprisingly there doesn't seem to be a good answer to that question. Forcing .INCLUDE_DIR doesn't help and there doesn't seem to be any way around invoking make with --include-dir=$OTHER_PROJECT_PATH.
It is however possible to put the appropriate recursive make invocation inside the makefile but, in order to get it to work for all reasonable cases it quickly becomes too complicated to be worth it. In summary it requires:
a top level condition to check if the OTHER_PROJECT_PATH is in .INCLUDE_DIR
the appropriate target with the recipe invoking make recursively
possibly additional targets if there are multiple command goals
the real make file enclosed in the else part of the conditional
You Makefile would look like this:
OTHER_PROJECT_PATH := other
ifeq (,$(filter $(OTHER_PROJECT_PATH), $(.INCLUDE_DIRS)))
# this is the mechanism to add the include dir in a recursive make
$(or $(firstword $(MAKECMDGOALS)),all):
$(MAKE) -I$(OTHER_PROJECT_PATH) $(MAKECMDGOALS)
# add empty targets for additional goals if needed
ifneq (,$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)))
$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)):
endif
else
# this is where the real makefile starts
all more:
echo $#: $< $^
include a.mak
endif
It still does not seem possible from a makefile, but if you have a script that sets up environment variables, you can use MAKEFLAGS (e.g. export MAKEFLAGS=I/your/path ordentlich on Linux, or SET on Windows)
i have a Makefile (that is not really under my control and) that defines a number of variables used by implicit rules:
CPPFLAGS := $(CPPFLAGS) -I../../../../modules
CXXFLAGS += -std=c++11
now, I want to add some additional flags to these variables as make variables. Something like:
make CPPFLAGS="-D_FORTIFY_SOURCE=2" CXXFLAGS="-g -O2"
unfortunately this results in overwriting the entire CPPFLAGS/CXXLAGS defined in the Makefile, whereas I would like to accumulate them (actually I would like to append the externally set flags, even though the above code clearly tries to prepend)
For whatever reasons, specifying these variables as environment variables (instead of make variables) works:
CPPFLAGS="-D_FORTIFY_SOURCE=2" CXXFLAGS="-g -O2" make
now for external reasons, i'm having a hard time passing those flags via envvars (and instead need make vars).
So what is the proper way to add compiler flags used by implicit rules? Both overwriting and accumulating variables strike me as a common task for Makefiles; there must be some way to do this...I've searched the make documentation but haven't found anything!
A simplistic approach is obviously to introduce some helper variable:
CXXFLAGS = -std=c++11 $(EXTRA_CXXFLAGS)
and then set this helper variable from outside:
make EXTRA_CXXFLAGS="-g -O2"
But: is there a standard name for such helper variable? (If so, which one? where is that documented??) Even better, is there an other variable that is automatically added to implicit rules (so i don't have to manually append the FLAGS?)
What is the reason why both variants for accumulating variables in my original Makefile work only with envvars, and not with make vars?
Environment variables can be modified within makefile using normal assignments. And it is common to set variables like CFLAGS, CXXFLAGS which can be appended (or modified in some way) in makefile, in the environment:
CPPFLAGS="-D_FORTIFY_SOURCE=2" CXXFLAGS="-g -O2" make
As opposite, variables set in make command line, cannot be modified within makefile using normal assignments. Such way you can set variables which used as some switch within makefile:
make V=1
Example of Makefile:
V=0 # Will be overriden by variable set in `make` command line
ifneq ($(V),0)
# output some debug information
endif
The only way to override variable set in command line is using override directive:
override CPPFLAGS := $(CPPFLAGS) -I../../../../modules # Will append string to variable, even if it set by command line
override CXXFLAGS += -std=c++11 # Similar but in the simpler form
Modifying CXXFLAGS and other *FLAGS variables
Suppose concrete makefile allows user to affect flags (that is, it doesn't hardcode them using direct assignment such CXXFLAGS := -g). And you want to affect on the flags.
Normal way is to set environment variable which will prepend flags set in the makefile itself. These additional flags, set by the makefile, are needed for correct compilation and linking.
However, you can try to override whole flags using variable set in the command line. In that case nobody garantees you don't suddenly broke the compilation, but it may work.
As for appending flags.. Well, it is normally needed for overwrite flags set by makefile (otherwise prepending flags using environment variable is sufficient). Because of that, any garantees will be vanished again. So, why do not use the previos way (setting whole flags via command line variable assignment)? At least, if something will go wrong, you will definitely know that problem is with you flags, not with ones set by makefile.
I have a Makefile that starts with
prefix = /opt/$(PACKAGE)
and expects make prefix=/usr in case someone wants a non-/opt installation. There's no ./configure (and no need for one really).
The package is trivially debianizable via
%:
dh $#
as debian/rules except that, due to the prefix=/usr requirement, one would have to litter the rules with
override_dh_auto_install:
make prefix=/usr DESTDIR=debian/BUILD install
(also dh_auto_build).
What is the elegant way to tell debhelper to add a prefix= to all make invocations (preferably without touching the makefile, otherwise there are many workarounds)?
You can do this:
%:
prefix=/usr dh $#
This works because make converts environment variable into make variables, see https://www.gnu.org/software/make/manual/html_node/Environment.html
Just make sure that you upstream Makefile uses conditional assignment like in:
prefix ?= /usr/local
Ciao,
Antonio
Does exporting MAKEFLAGS=prefix=/usr in your rules file (or wherever that trivial snippet lives) do what you want?