Here is some code in my configure.ac:
THIS="h5cc"
AC_MSG_WARN([$THIS])
AC_MSG_WARN(m4_bmatch([h5pcc],
[h5pcc], [parallel],
[h5cc], [serial],
[neither]
))
AC_MSG_ERROR(m4_bmatch([$THIS],
[h5pcc], [parallel],
[h5cc], [serial],
[neither]
))
I autoconf and then configure, which results in this:
configure: WARNING: h5cc
configure: WARNING: parallel
configure: error: neither
As far as I can tell, that's not supposed to happen, right? What am I missing?
You're mixing M4 code within your configure, but m4 only executes before expansion (i.e. when you run autoconf), while THIS=h5cc is a shell construct that gets executed by your shell (when you run ./configure).
So what m4_bmatch sees is a literal $THIS which indeed is neither.
Short version, don't use m4_* functions for things that you want to change at configure time.
Related
I'm developing an open source application where I'd like to include Perl conditionally (for different text processing purposes - that's just for information, not to be criticized as a concept :-). How would you normally check for availability of Perl headers using autoconf?
In my configure.ac I use the following for stuff that has pkg-config files:
PKG_CHECK_MODULES(GTK, gtk+-3.0, [AC_DEFINE([HAVE_GTK_3], 1, [Define to 1 if GTK+ 3 is present])])
PKG_CHECK_MODULES(SQLITE, sqlite3, [AC_DEFINE([HAVE_SQLITE], 1, [Define to 1 if SQLite is present])])
Unfortunately AFAIU Perl doesn't ship any .pc-s. In my Makefile.in to generate compiler flags I use their perl -MExtUtils::Embed -e ccopts -e ldopts instead of executing pkg-config.
Here rises the question - how would you do this in a prettier way?
I tried this:
AC_CHECK_HEADER([perl.h], AC_DEFINE(HAVE_PERL, 1, [Define to 1 if Perl headers are present]))
But it doesn't work unfortunately:
checking for perl.h... no
In my system (and probably much everywhere else) it's not in just /usr/include:
gforgx#shinjitsu nf $ locate perl.h | tail -n 1
/usr/lib64/perl5/CORE/perl.h
Is there at all a 'legal' way to extend search path for AC_CHECK_HEADER without using automake and AM_ macros?
So far I tried manipulating CPPFLAGS, and it's much better but still (probably due to other inclusions in perl.h):
configure: WARNING: perl.h: present but cannot be compiled
configure: WARNING: perl.h: check for missing prerequisite headers?
configure: WARNING: perl.h: see the Autoconf documentation
configure: WARNING: perl.h: section "Present But Cannot Be Compiled"
configure: WARNING: perl.h: proceeding with the compiler's result
configure: WARNING: ## ------------------------------------ ##
configure: WARNING: ## Report this to gforgx#protonmail.com ##
configure: WARNING: ## ------------------------------------ ##
checking for perl.h... no
Many thanks!
Update
Finally this works:
PERL_CPPFLAGS=`perl -MExtUtils::Embed -e ccopts`
PERL_LIBS=`perl -MExtUtils::Embed -e ldopts`
old_CPPFLAGS="$CPPFLAGS"
old_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $PERL_CPPFLAGS"
LIBS="$LIBS $PERL_LIBS"
# TODO: figure out why first option doesn't work
#AC_CHECK_HEADER([perl.h], AC_DEFINE(HAVE_PERL, 1, [Define to 1 if Perl headers are present]))
AC_CHECK_FUNCS(perl_construct, AC_DEFINE(HAVE_PERL, 1, [Define to 1 if Perl headers are present]))
CPPFLAGS="$old_CPPFLAGS"
LIBS="$old_LIBS"
Not much of an autoconf expert, but I think: you can put plain shell snippets like
PERL_CFLAGS=`perl -MExtUtils::Embed -e ccopts`
PERL_LDFLAGS=`perl -MExtUtils::Embed -e ldopts`
into your configure.ac. Probably the right way to do it is to use AC_ARG_WITH to let the user specify those vars, and only get them from EU::E if the user hasn't overridden them. (likewise you can use one to have --with-perl override the HAS_PERL check entirely).
Then you can use AC_SUBST to make the values from configure-time available in the Makefile (so you don't need to call EU::E in Makefile.in).
And finally, the heart of the issue, I don't think there's a nice way to make AC_CHECK_HEADER aware that it needs some nonstandard flags, but you can do
old_CFLAGS="${CFLAGS}"
CFLAGS="${PERL_CFLAGS}"
AC_CHECK_HEADER(...)
CFLAGS="${old_CFLAGS}"
to run AC_CHECK_HEADER with PERL_CFLAGS in effect.
Note that you need Perl's C header(s) only if you want to build a Perl extension or embed a Perl interpreter in your binary. The latter seems more likely to be what you have in mind, but in that case, do consider whether it would work as well or better to simply use an external Perl interpreter, launched programmatically by your application at need. Use of an external Perl interpreter would not involve the C header at all.
However, you seem already committed to binary integration with Perl. In that case, configure is the right place to test for the availability and location of Perl's development headers, and to determine the appropriate compilation and linker flags. Putting it there also gives you the ability to use Automake conditionals to help you configure for and manage both with-Perl and without-Perl builds, if you should want to do that.
To that end, even though Autoconf does not provide built in macros for Perl detection / configuration, the Autoconf Archive has a few of them. In particular, ax_perl_ext_flags self describes its behavior as ...
Fetches the linker flags and C compiler flags for compiling and linking programs that embed a Perl interpreter.
... which I take to be appropriate for your purposes. After adding that macro to your project, you might incorporate it into your configure.ac like so:
PERL_CFLAGS=
PERL_LDFLAGS=
AX_PERL_EXT_FLAGS([PERL_CFLAGS], [PERL_LDFLAGS])
# ...
AC_SUBST([PERL_CFLAGS])
AC_SUBST([PERL_LDFLAGS])
That macro uses a technique similar to what you describe doing in your Makefile.in, but in a rather more robust way.
As for checking on the header, once you have the appropriate C compiler flags for Perl, you put those into effect (just) for the scope of the header check. This is necessary because configure uses the compiler to test for the presence of the header, and if the compiler requires extra options (say an -I option) to find the header at compile time, then it will need the same at configuration time. Something like this, then:
CFLAGS_SAVE=$CFLAGS
# Prepend the Perl CFLAGS to any user-specified CFLAGS
CFLAGS="${PERL_CFLAGS} ${CFLAGS}"
# This will automatically define HAVE_PERL_H if the header is found:
AC_CHECK_HEADERS([perl.h])
# Restore the user-specified CFLAGS
CFLAGS=$CFLAGS_SAVE
I execute the following code on AIX box using TCL and it fails
The reason for failure is that somehow 'gcc' is ENABLED by DEFAULT on that AIX LPAR.
I want to DISABLE gcc. How can I do that?
AC_DEFUN(SC_ENABLE_GCC, [
AC_ARG_ENABLE(gcc, [ --enable-gcc allow use of gcc if available [--disable-gcc]],
[ok=$enableval], [ok=no])
if test "$ok" = "yes"; then
CC=gcc
AC_PROG_CC
else
CC=${CC-cc}
fi
])
Please help me to resolve the issue
You probably need to do two things:
Specify the --disable-gcc option to configure.
Set the exported CC environment variable to the compiler you actually want to use prior to running configure.
This might be combined into:
CC=cc ./configure --disable-gcc ...
(I commonly have my CC variable set to a clang variant on my platform…)
I have a legacy makefile based build system that I am trying to make changes to. I am not familiar with make and so was making changes on a trial and error basis.
Not being able to deduce what the problem is I inserted this bit of code in the makefile:
ARG1 = GCC
ARG2 = ARM
ifeq($(ARG1),$(ARG2))
$(warning *** WARNING ***)
endif
When I run make, I always get the print:
\PathToBuildDirectory\makefile.options:54:*** WARNING ***
NOTE: I am using clearmake with the -C gnu option.
How or why does the condition evaulate to true?
If it behaves this way for a makefile consisting of only the above content then it's a bug in clearmake. I know that clearmake's emulation of GNU make is incomplete, but this seems pretty simple.
However, since you're already echoing an error wouldn't it be straightforward to also show the values of ARG1 and ARG2? Maybe they ARE equal. Maybe one or both are set on the command line. Maybe elsewhere one or both was assigned with the override option. Maybe clearmake is invoked with the -e option and one or both of those variables are set in the environment.
If you show their values, then you'll know.
ETA: Maybe the problem is this: in GNU make you must put a space after the ifeq, like this:
ifeq ($(ARG1),$(ARG2))
If you try your original version with GNU make, you'll get an error:
Makefile:3: *** missing separator. Stop.
but I guess clearmake just ignores the line without any error messages.
Is there a way to change the specs file so that it will pass -march=native if nothing is specified in command line?
Related things in the default specs file is:
*cc1:
%(cc1_cpu)
*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
I am not sure how specs works. Simply specifying -march=native before or after %(cc1_cpu) doesn't work. However, this line does take effect because GCC will report error if I put -something_wierd instead of -march=native.
Another thing I noticed is if I put %{march=i386:-something_wierd} before %(cc1_cpu), gcc reports error so looks like -march=i386 is always passed in if nothing is specified, so is there a way to distinguish between nothing specified and -march=i386 in specs file?
BTW, what does %> do? Seems like it is not specified in the documentation.
I am using MinGW's gcc-4.6.2.
Referring to your last question: The gcc 4.6.1 sources (gcc/gcc.c) contain the following comment on %>:
%>S Similar to "%<S", but keep it in the GCC command line.
For the sake of completeness following the comment for %< form the same file:
%<S remove all occurrences of -S from the command line.
Note - this command is position dependent. % commands in the
spec string before this one will see -S, % commands in the
spec string after this one will not.
To answer the first question in short: yes, but ....
... the only generic solution I found has the significant drawback that the -march option will be ignored, so every build is done as if -march=native had been specified. Anyhow there is a workaround to that.
1 The solution (without workaround)
Create a specs-file called let's say specs.nativealways containing:
*cc1_cpu:
%<march=* -march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
When using the specs-file (for example by invoking gcc with the option -specs=specs.nativealways) the build will be done as if -march=native was specified (with the mentioned drawback that any occurrence of option -march=<arch> would have simply been ignored).
2 The workaround
To still by able to override the newly configured default behavior one can use a modified version of the specs-file described above, introducing a new option called -myarch using the same syntax as -march (except for -myarch=native, which won't work, which does not metter as native now is the default).
The modfied specs-file looks like this:
*cc1_cpu:
%<march=* %{myarch=*:%<myarch* -march=%* ; :-march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
PS: This has been tested with with gcc 4.6.2 on Linux, but should work on MinGW.
While not a direct answer to your question, you can reach a very similar effect by defining CFLAGS and CXXFLAGS in your shell's initialization file. 99% of the Makefiles are sufficiently standard to pick up the environment values and pass the flags to gcc.
*cc1_cpu:
+ %{!march*:-march=native}
I have a project whose makefile uses features exclusive to GNU Make. Sadly, there are platforms we must support where GNU make is still not the default when running make.
One of my colleagues was bitten by this, when a non-GNU make implementation silently failed to build our code correctly (it expanded an automatic variable to an empty string). I want to prevent that from happening again, by generating an explicit error message instead.
What can I write in a Makefile to distinguish GNU make from non-GNU make, print a clear error, and exit?
I've already figured out a workaround in renaming my real makefile to GNUmakefile, and putting a small stub in Makefile, but I'd rather something more direct.
The answers by Beta and Dan Moulding look really nice and simple, but on AIX 6.1, the make implementation can't handle either of them:
$ cat testmake
foo:
touch foo
ifeq ($(shell $(MAKE) -v | grep GNU),)
$(error this is not GNU Make)
endif
ifeq "${MAKE_VERSION}" ""
$(info GNU Make not detected)
$(error ${MIN_MAKE_VER_MSG})
endif
$ /usr/bin/make -f testmake
"testmake", line 5: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 6: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 7: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 8: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 11: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 12: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 13: make: 1254-055 Dependency line needs colon or double colon operator.
make: 1254-058 Fatal errors encountered -- cannot continue.
I run into similar issues on both archaic and modern versions (Solaris 8 & 10) of Sun's make. That one's less critical, but would be nice to manage.
As noted, GNU make checks for GNUmakefile before makefile or Makefile, I've used a trivial fix such as you described, a default (decoy) Makefile that causes an error/warning:
default:
#echo "This requires GNU make, run gmake instead"
exit 70
The GNU make documentation recommends using the GNUmakefile name when the Makefile is GNU make specific, so that's my preferred solution.
On platforms where the native make prefers a different Makefile name, you can do a variation on this, e.g. on FreeBSD I have the above decoy in the BSDmakefile which is used in preference to Makefile (thus preventing the system make from mangling my build). AFAICT the AIX or Solaris make do not have an alternate name you could use in this way.
One problem with a wrapper Makefile which tries to call GNU make is passing all the arguments.
A seemingly portable test (so far, I've found it to work on a mix of ancient OSF1, BSD and Solaris systems) you can use SOMETHING=$(shell ...) to detect if GNU make is running, non GNU versions will not set SOMETHING. Because of deferred evaluation of variables, you cannot use this as easily as might be expected though. This relies on the implementation silently handling macro names with spaces when expanded with $() (i.e. treats $(shell foo) as a variable/macro name rather than a function, even though an assignment to such a name in that implementation would cause an error).
The only portable way you can print a clear error is to have a dummy target that is always run, using the above trick:
GNUMAKE=$(shell echo GNUMAKE)
default: gnumake all
gnumake:
#[ "$(GNUMAKE)" = "GNUMAKE" ] || { echo GNU make required ; exit 70; }
This assumes you have a POSIX sh shell.
(I have seen tests which inspect $(MAKE) -v fail when both system and GNU make are called "make", the system make conspires against you and invokes GNU make ... You'd need some carefully checking of environment variables PATH, MAKE and possibly SHELL to handle every case.)
I don't know of any internal feature that is definitely unique to GNUMake, but here's a kludge: call "make -v" and parse the output for "GNU" (since it seems unlikely that a non-GNU Make would have MAKE set to a GNU Make):
ifeq ($(shell $(MAKE) -v | grep GNU),)
$(error this is not GNU Make)
endif
EDIT:
Like Dan Moulding, I am starting to see the real size of this problem. As written, it requires a Makefile that is syntactically correct in all versions of Make. I don't have access to Sun Make (and I can't find manuals for it) so I don't know whether that's even possible, or how to write it if it is, or how to test it if I did.
But I can suggest an approach that might work. Maybe something like this can be made universal:
default:
./runGNUMake.pl
That's it, that's the whole makefile. Then write the runGNUMake script in Perl (or bash, or whatever you like) that will do something like my "make -v" kludge and then either print the error message or run "make -f realMakefile".