How to choose a compiler version in Automake? - configure

I have several compilers with the same name but of different versions or location.
The ./configure script seems to stop at the first it finds in PATH. How can I tell Automake to choose one of them according to a custom rule ? I already have a macro which can check the compiler version.
I would like to avoid setting the path by hand (with the FC variable) as it can be cumbersome to type each time the whole path.
In my case, several MPI wrapper compilers are located in different directories with the same name (and added to the PATH by the user).
The idea would be to use something like ./configure --with-intel to find and select the IntelMPI compiler.

My solution is to set up CC and other "precious" variables via a shell script, lots of them for cross compilation. So I have a bunch of shell scripts sitting around with contents like:
export CROSS_COMPILE=arm-linux
export CC=${CROSS_COMPILE}-gcc
...
PATH=$PATH:/some/arm/compiler/bin:/some/arm/compiler/usr/bin # for arm compiler tools
export CFLAGS="..."
to set up the configure configuration. So at configure time I do:
source /path/to/configuration/some-arm-compiler.sh
./configure ...
It saves a lot of typing.
EDIT: So it could work for your particular case something like:
mpi-a.sh
export FC=mpif90
PATH=$PATH:/path/to/mpi-a/bin:/path/to/mpi-a/usr/bin
mpi-b.sh
export FC=mpif90
PATH=$PATH:/path/to/mpi-b/bin:/path/to/mpi-b/usr/bin
So for compiling with one of them:
source /path/to/mpi-a.sh
./configure ...
and the other:
source /path/to/mpi-b.sh
./configure ...

My solution : copy the search strategy of configure in a macro, with a custom matching criterion. Parsing PATH is done by setting the IFS variable (which is already defined in configure). In Bash, finding all the executables would be something like :
#!/bin/bash
IFS=":"
exe="mpif90"
for dir in $PATH
do
if test -f "$dir/$exe"; then
custom_test($dir/$exe)
fi
done
Note: This is recommanded in the manual
If you need to check the behavior of a program as well as find out whether it is present, you have to write your own test for it.

Related

How to Change the Default Command That make Executes?

By default, when running make to compile a C source code file named prog.c
make prog
the default command that executes is
cc prog.c -o prog
Sometimes I really need to include some additional flags. I know that when there are no Makefiles, make relies on some environment variables.
On Ubuntu 14.04, how to configure these variables to change the command that gets executed by default?
Step by step answers will be appreciated!
When no makefile is present (or no rule exists in that makefile) make relies on a default built-in database of rules. Run make -p to get make to spit out all the rules it knows about (in the no makefile case that will be the default ones).
When you look at that list you will find a pattern rule for building C source into object files or executables. Those rules have variables in them (like CFLAGS, LDFLAGS, etc.) that can be used to control exactly what you are trying to. That's why they are there (and are why that default command has such funny spacing, in case you ever wondered about that).

GNU Make Under Windows: Check for cygwin in PATH

I have been putting together a makefile in a Windows environment for my team to use. I decided to use MinGW's version of make for Windows. I put that executable with its dependencies into a repository location that should be in everyone's PATH variable. The executable was renamed "make.exe" for simplicity.
Then I realized that I have to account for the case when someone has cygwin's bin folder in their path. Commands like echo, rmdir, and mkdir will call echo.exe, rmdir.exe, and mkdir.exe from cygwin's bin folder. This means that I need to appropriately catch this scenario and use different flags for each command.
I see three cases here:
Cygwin's bin path comes before the path where make.exe is located in the repository. When a team member executes make.exe, they will be executing cygwin's make. Unix-style commands must be used.
Cygwin's bin path comes after the path where make.exe is located in the repository. The correct make.exe will be executed, but I still have to use Unix-style commands.
Cygwin is not installed or not in the PATH. I can use all Windows commands in this case.
I am fine with treating cases 1 and 2 the same. Since MinGW's make and cygwin's make are both based on GNU Make, then I don't see this being much of an issue other than incompatibility issues between versions of GNU Make. Let's just assume that isn't a problem for now.
I have come up with the following check in my makefile.
ifneq (,$(findstring cygdrive,$(PATH))$(findstring cygwin,$(PATH))$(findstring Cygwin,$(PATH)))
#Use Unix style command variables
else
#Use Windows style command variables
endif
Finding "cygdrive" in the path variable means that we are most likely in case 1. Finding "cygwin" or "Cygwin" in the path variable most likely means that we are in case 2. Not finding either string in the path most likely means that we are in case 3.
I am not completely fond of this solution because the cygwin's folder can be renamed or the string "cygwin" or "cygdrive" can be put in the PATH variable without having cygwin installed. One team member is still having issues as he has cygwin's bin path in the PATH variable, but the above does not catch that. I am assuming that he renamed the folder to something else, but I haven't been able to check on that.
So is there a better way to figure out what syntax that I should be using?
Here is another solution that I thought up.
ifeq (a,$(shell echo "a"))
#Use Unix style command variables
else
#Use Windows style command variables
endif
This is based on the fact that 'echo "a"' in Unix will print a (without quotes) but windows will print "a" (with the quotes). If I am using the Unix style echo then I can assume that I am using all Unix commands.
I don't find this solution very elegant though, so I am not marking it as the solution for this question. I think this is better than what I originally had though.
Cygwin make v. MinGW make: Does mingw make support the jobserver, as in can you do make -j5? If not, ${.FEATURES} has jobserver for cygwin make. Maybe load is a good test too.
Cygwin before non-cygwin on path: cygpath.exe is unique to cygwin. You could just look for this in ${PATH}. Unfortunately, Windows users like using spaces in folder names, and there's no way of dealing with this in pure make. $(shell which make) will return /usr/bin/make for cygwin, though a shell invocation on every make run is very smelly.
You don't install a compiler from a repository, is not make a similar case? Just get your users to install cygwin and be done with it.

source a script from gdb

Before I debug or execute a program on my system at work, I have to source a file that contains numerous paths and settings that are specific to each project. Is there a way I can do this from gdb? I tried putting it into a .gdbinit file in the working directory, but that doesn't seem to be working. I tried to see if the environmental variable was set by typing
(gdb) shell echo $MY_VAR
and it was blank. Any ideas?
Basically to set the environment variable in the command prompt, you can use the set environment varname [=value]. More information is present here. Since you have noted down there are huge number of paths to be set, you can add them to a file like myGdbSrc and then load them explicitly using source [-s] [-v] filename. You can find details on loading a file here.
I have tried both of them and it works.
HTH.
PS: I have tried it on GNU GDB 6.6 version on SUSE Linux. However, it must work across all version since it seems to be basic command.
How about writing a wrapper script which sources your settings before loading gdb?
E.g. some trivial example:
#!/bin/sh
source my-script-which-sets-up-the-environment
gdb $*
This can of course also add arguments to the gdb invocation to setup paths, load a gdb script, etc.

Choosing a different executable in bash

When I want to run make to generate some executables it always uses the Sun make located
at /usr/local/bin/make rather than GNU make which can be found at /usr/sfw/bin/gmake.
How can I tell the OS to use GNU make rather than Sun's? Do I need to overwrite the path somehow?
For two executables named identically, reorder paths in the PATH variable, since the first match will be used.
Otherwise, define an alias in your ~/.profile or ~/.bashrc file:
alias make="/usr/sfw/bin/gmake"
Or a function:
make() { /usr/sfw/bin/gmake "$#"; }
Note, that aliases work only in interactive mode. Scripts will not see them. Use functions in such case.
you can link /usr/sfw/bin/gmake to /usr/bin for example as long as the directory where you link it to is before /usr/local/bin in the PATH variable
thus
cd /usr/bin
ln -s /usr/sfw/bin/gmake make
just be sure there is no make already in the path.
otherwise you always can call gmake instead of make to use gnu-make and leave make for the sun-version-make.
otherwise you can use the alias as in the previous post
If you're manually running the make command, then simply type gmake instead of make. It will run the GNU version (assuming that your PATH) variable is set properly.
If there's an IDE or some other tool that's invoking make, you need to tell it to use gmake rather than make and the way to do that depends on which tool you're using.

Building R Packages using Alternate GCC

The systems I work with have GCC 4.5 (experimental) in /usr/local/bin/gcc which has proven to be problematic for some R packages. I would like to instead use system GCC in /usr/bin/gcc.
I have tried setting CC and CXX in the Bash configuration files (.bashrc, .bash_profile etc.) as well as on the command line, but although Bash recognizes the change, R does not.
How can I get R to use the version of GCC in /usr/bin instead of the one in /usr/local/bin/?
This is not that well documented (e.g. I failed to locate it in either 'R Extension' or 'R Admin' right now) but Brian Ripley mentioned it a few times on the lists.
Basically, at R compile time, settings are registered and the stored in $R_HOME/etc/Makeconf. One possibility is to edit that file directly, but you may not have root privileges or may not want to affect all other users. So the better may be to create
~/.R/Makevars
with entries
CC=gcc-4.4
CXX=g++-4.4
plus whichever optmisation flags etc you want to set. That will the affect all subsequent uses of R CMD INSTALL or R CMD check or ... that you run.
Other files in $R_HOME/etc/ can similarly be overridden locally from ~/.R/.
I had a very similar problem.
What worked for me was to define a project directory (rstudio can do that for you), and then add a .Renviron file that modifies the PATH and LD_LIBRARY_PATH, to include the directory with the new gcc.
In your case, for example, the .Renviron will look something like:
LD_LIBRARY_PATH=/usr/local/bin/gcc/lib:/usr/local/bin/gcc/lib64:/usr/local/bin/gcc/libexec:other paths
PATH=/usr/local/bin/gcc/bin:/usr/local/bin:other paths
Check your path to see if /usr/local/bin comes before /usr/bin. If it does, just make sure /usr/bin comes first:
PATH=/usr/bin:${PATH}
(it's okay if /usr/bin is duplicated appears twice).
Look at configure.args part of ?install.packages and compare this to ./configure --help on e.g. the r source tree.
You can also, from bash, CC=clang R CMD INSTALL /path/to/package/source.
HTH

Resources