configure - check for availability of Perl headers (solved) - configure

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

Related

gfortran specify source file option

In gcc we have -x option that use to specify how to treat source file.
For example suppose we have a csourcecode file without any extension like .c.
In gcc simply using -x c before express csourcecode force compiler to use it as valid c source code.
gcc -x c csourcecode -o out
Is there any similar option for gfortran?
From the helpful gcc manual: [Note 1]
You can specify the input language explicitly with the -x option:
-x language
Specify explicitly the language for the following input files
(rather than letting the compiler choose a default based on the
file name suffix). This option applies to all following input
files until the next -x option. Possible values for language
are:
(snip)
f77 f77-cpp-input f95 f95-cpp-input
If you're using a Unix-y system and you took the precaution of installing the gcc documentation package (apt-get install gcc-doc on debian/ubuntu-like systems), then you could have found that information directly by typing
info gcc --index-search=x
because the GCC info files are index by option name. Most of the time you don't need to type --index-search=; info gcc x would suffice.
Notes:
In case it's not obvious, gfortran is just another front-end for the Gnu compiler collection ("gcc" for short), and accepts any options that would be accepted by the gcc command.

Running GCC preprocessor -fdirectives-only *without* implicit -dD

Basically, I want to do what the title says.
I have some mildly complex header files, and I want to generate a single header file I can release as the public interface of a DLL.
I'm generating the header file as follows:
${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} -fdirectives-only -P \
-E ${CMAKE_CURRENT_SOURCE_DIR}/dll_header_base.h -o generated_public_header.h
If I run the compiler without -fdirectives-only, the precompiler is much more aggressive about stripping out contents of the header. The output of -fdirectives-only is almost what I want, but that particular flag forces the -dD flag on as well, which prepends all the compiler-defined macros to the generated header (450 lines of them!).
I don't really understand why -fdirectives-only forces -dD in the first place, and for my case, the later flag basically makes it useless. Looking at the options for -dLETTER, there also seems to be no way to turn it off.
How do I extract the directives-only preprocessed output without all the additional cruft?
Yes, I could pretty easily solve this with command line tools, but I want to keep the solution entirely constrained to the compiler/CMAKE. Eventually, I'd like to also support building on windows.

Detect when only preprocessing, i.e. gcc -E

I currently invoke clang or gcc as
cc -E -DPREPROCESSING ...
when debugging macros.
It has occurred to me that the define is redundant. Is there an expression I could write in the source to detect when the compiler will stop after preprocessing, and so drop this definition from my build scripts?
#if magic
#define PREPROCESSING
#ending
A look at the docs suggests not, but with luck I'm missing something.
Whatever solution you come up with is going to be compiler-specific, since the C standard does not have anything to say about separate preprocessing.
In gcc, you could implement the magic by adding a custom spec file:
%rename cpp old_cpp
*cpp:
%{E:-DPREPROCESSING} %(old_cpp)
You would need to tell gcc to use this spec file (-specs=/path/to/specfile), unless you compiled your own gcc with the above definition added to the built-in cpp spec. If you are using a Makefile, you could add the -specs option above to your CFLAGS.
(I should add that I don't think this is a particularly good idea. But it is possible.)

Disable optimizations for a specific file with autotools

I'm working on setting up autotools for a large code base that was once just a bash script compile and later just hand written Makefiles.
We have a set of files that require that compiler optimizations be turned off. These files are already in their own subdirectory, so they will have their own Makefile.am.
What's the proper way to drop any existing compiler optimizations and force a -O0 flag on the compiler for these specific files?
I went with Brett Hale's comment to use subpackages. I was able to insert
: ${CFLAGS="-O0"}
before AC_PROG_CC, which sets the appropriate optimization. The other solutions do not work, since the -g -O2 was getting added very last. You can never get another -O variable after it.
You don't have to remove existing optimizations: the last value of -O on the compiler invocation will be used, so it's good enough to just add -O0 at the end.
This is not directly supported by automake, but there's a trick you can use defined in the documentation.
Otherwise if you know you'll only ever invoke your makefile with GNU make you can play other tricks that are GNU make specific; you may have to disable automake warnings about non-portable content.

How to compile OpenSSL with relative rpath

I have been trying to compile openssl 1.0.0g with the following rpath:
$ORIGIN/../lib64
Everytime I readelf -d apps/openssl, I am getting results like the following depending on what escaping variation I tried:
\RIGIN/../lib64
RIGIN/../lib64
ORIGIN/../lib64
I want to setup my rpath without using external tools like chrpath. Is it at all possible? I will basically accept anything that does not involve using external tools like chrpath (though I would already be done with that).
Ideally, I would like to do it by passing options on the command line (any form of -Wl,-rpath,$ORIGIN/../lib64).
I don't mind editing the generated Makefile, which is what I have been trying last. If only I could get it to print a stupid dollar sign!!! I tried modifying LIBRPATH under the BUILDENV= block with no luck. My best results so far:
LIBRPATH=$$'ORIGIN/../lib64 # result: /../lib64
LIBRPATH=$$$$'ORIGIN/../lib64 # result: 12345<pid>/../lib64
I have read various rpath related questions and tried various escaping and quoting tricks but nothing worked so far!
In your makefile try:
-Wl,-rpath,${ORIGIN}/../lib64
I am assuming that the ORIGIN is a shell variable.
EDIT
I have just found an answer to your question (better late then never):
You need to prevent make from interpolating variables, to do that you need to use $$ (double dolar sign):
-Wl,-rpath,'$$ORIGIN/../lib64'
I know that it works because I have tested it with my own application, enjoy :)
I went the chrpath way.
http://enchildfone.wordpress.com/2010/03/23/a-description-of-rpath-origin-ld_library_path-and-portable-linux-binaries/
It is quite complicated to counter shell expansion of `$$ORIGIN`` in openssl. Sooner or later, it gets expanded because of the dollar sign. If you really want to go this way, you can do it. I have found the following to work with openssl 1.0.1g on Linux. In Makefile.shared, look for this line:
DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)"
Replace it with the following. This quoting-fu neutralize the expansion of $. The double $$ is the way to get a single dollar sign in makefiles.
DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,'"'$$'"ORIGIN/../lib64'"
After compiling:
readelf -d apps/openssl | grep RPATH
0x000000000000000f (RPATH) Library rpath: ['$ORIGIN/../lib64']
OK I spent several hours fighting with this same issue and trying all manner of crazy escaping, at one point I was up to eight $ signs, at which point I decided that there must be another way.
In fact, it appears that there is, at least with GNU ld.
Instead of -Wl,-rpath,\\$$$\$\$\$$$\$\\\\$ or some other elder god invoking monstrosity, just do this:
echo '-rpath=$ORIGIN/../lib64' > rpathorigin
./config -Wl,#$(pwd)/rpathorigin ...
I don't see that ld.gold documents the # flag, and I have no idea about, say, lld. But if you are using GCC and it is invoking BFD ld, the above may just work for you.
Of course, the actual path used with origin should be customized as needed, and I have no opinion on ./config vs ./Configure. But using the response file trick seems to entirely sidestep the shell/make escaping nightmare.
I don't mind editing the generated Makefile, which is what I have been trying last...
I'm not sure you can set it with a shell variable and relative path. I don't think ldd expands the $ORIGIN in $ORIGIN/../lib64. In this case, I think you need to use ldconfig to add $ORIGIN/../lib64 to the library search paths. See finding ldd search path on Server Fault for more details.
Since I'm not sure, I'll provide the instructions anyway. You don't need to change the Makefiles. As a matter of fact, I did not have any luck doing so in the past because things get overwritten, and other things like CFLAGS and LDFLAGS get ignored.
Also see Build OpenSSL with RPATH? Your question and the cited question are different question that converge on similar answers (no duplicates between them). But it provides the OpenSSL dev's position on RPATHs. It was a private email, so I shared the relevant details rather than the whole message.
If you manage to embed $ORIGIN/../lib64 in the ELF section and it works, then please report back. Below, I am using /usr/local/ssl/lib for my RPATH. You should substitute $ORIGIN/../lib64 for /usr/local/ssl/lib.
OpenSSL supports RPATH's out of the box for BSD targets (but not others). From Configure:
# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
# .so objects. Apparently application RPATH is not global and does
# not apply to .so linked with other .so. Problem manifests itself
# when libssl.so fails to load libcrypto.so. One can argue that we
# should engrave this into Makefile.shared rules or into BSD-* config
# lines above. Meanwhile let's try to be cautious and pass -rpath to
# linker only when --prefix is not /usr.
if ($target =~ /^BSD\-/)
{
$shared_ldflag.=" -Wl,-rpath,\$(LIBRPATH)" if ($prefix !~ m|^/usr[/]*$|);
}
The easiest way to do it for OpenSSL 1.0.2 appears to be add it to linker flags during configuration
./config -Wl,-rpath=/usr/local/ssl/lib
You can also edit Configure line and hard code the rpath. For example, I am working on Debian x86_64. So I opened the file Configure in an editor, copied linux-x86_64, named it linux-x86_64-rpath, and made the following change to add the -rpath option:
"linux-x86_64-rpath", "gcc:-m64 -DL_ENDIAN -O3 -Wall -Wl,-rpath=/usr/local/ssl/lib::
-D_REENTRANT::-Wl,-rpath=/usr/local/ssl/lib -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:
${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
Above, fields 2 and 6 were changed. They correspond to $cflag and $ldflag in OpenSSL's builds system.
Then, Configure with the new configuration:
$ ./Configure linux-x86_64-rpath shared no-ssl2 no-ssl3 no-comp \
--openssldir=/usr/local/ssl enable-ec_nistp_64_gcc_128
Finally, after make, verify the settings stuck:
$ readelf -d ./libssl.so | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./libcrypto.so | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/usr/local/ssl/lib]
$ readelf -d ./apps/openssl | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/usr/local/ssl/lib]
Once you perform make install, then ldd will produce expected results:
$ ldd /usr/local/ssl/lib/libssl.so
linux-vdso.so.1 => (0x00007ffceff6c000)
libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007ff5eff96000)
...
$ ldd /usr/local/ssl/bin/openssl
linux-vdso.so.1 => (0x00007ffc30d3a000)
libssl.so.1.0.0 => /usr/local/ssl/lib/libssl.so.1.0.0 (0x00007f9e8372e000)
libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00007f9e832c0000)
...
Don't ask me why but this worked for me in OpenSSL 1.1.1i in getting around the $ sign issue:
\$\$\$$ORIGIN
Example:
./Configure linux-x86_64 '-Wl,-rpath,\$\$\$$ORIGIN'
Alternatively, if this command line hack isn't congruent with you, you can always use chrpath after building as others have suggested:
./Configure linux-x86_64 '-Wl,-rpath,XORIGIN'
make depend
make all
chrpath -r "\$ORIGIN" libssl.so

Resources