From ripley at stats.ox.ac.uk  Thu Aug  2 18:29:39 2007
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Thu, 2 Aug 2007 17:29:39 +0100 (BST)
Subject: [Rd] Package portability issues
Message-ID: <Pine.LNX.4.64.0708021051470.5770@gannet.stats.ox.ac.uk>

We have some new Solaris boxes (both Sparc and amd64), and as they are not 
yet in production use I borrowed some time on them to run tests over CRAN 
packages, using the Solaris make and Sun Studio compilers.  The results 
were quite depressing.  Sun Studio 12 compilers are also available for 
Linux, and there the problems are worse (for C++ code).


Line endings
============

We checked in R CMD check for CRLF line endings on C/C++/Fortran source 
files.  However, two packages have CR line endings, which apparently gcc 
accepts but no other compiler I can find.  R CMD check now checks for CR 
or CRLF line endings.

Apparently GNU make accepts makefiles with CRLF line endings, but Solaris 
make does not. 28 packages had src/Makevars[.in] or src/Makefile with CRLF 
line endings.  R CMD check now checks for this.


Fortran portability
===================

The GNU compilers have never implemented the exact Fortran standards: g77 
was said to be a 'GNU Fortran' compiler, and gfortran has '--std=legacy'. 
So they are not a good check of portability.

There is a comprehensive checker available at
http://www.dsm.fordham.edu/~ftnchek/ .  This is picky, but does pick up 
the main portability problems I found:

- the use of non-integer variables for array indices
- naming variables with the names of builtin functions.
- calling functions with the wrong argument type.

gfortran -Wall does warn on the first and you will see examples in the 
CRAN check summaries.

Although REAL*8 is non-standard it does not seem to cause any actual 
problems.


Make dialects
=============

R does not require GNU make, and if possible packages should not do so.
If your package does, please follow the example of Matrix and declare

SystemRequirements:   GNU make

in the DESCRIPTION file.  (I found 4 other instances: seems an Urbanek 
speciality.)  I think most people would have access to GNU make, but do 
need to be warned that it is needed.


Compiler flags
==============

Flags such as -Wall and -pedantic have no place in distributed Makevars.
Neither do optimization flags, nor does -Wno-conversion.

(Packages that fail because of this include Cairo, amap, gmp. 
FortranCallsR defines FFLAGS but fortunately that is always 
overridden.)


C++ issues
==========

Most of the packages using C++ failed.  Please resist the temptation to 
write C in C++: writing it in C is much more portable.  (About 40 packages 
could not be installed because of C++ issues even after changing the R 
headers.)


1) One common error message is

    An integer constant expression is required within the array subscript
    operator.

Here is an example:

         double data[(*nrow)+2*env][(*ncol)+2*env];

This affects at least packages

GammaTest MCMCpack MasterBayes clusterSim dprep edci epsi knnFinder pbatR 
rmetasim zicounts


2) Including C header files is fraught with difficulties.  Unfortunately 
that includes the R header files, because they in turn include system C 
headers.

The checking of which features were available was done using the C 
compiler with particular flags, and glibc has a habit of hiding features 
depending on the flags set.  So a C header called from the C++ compiler 
may not declare things that the same header called from the C compiler 
does.  This means that C99 features such as isfinite may not be seen from 
the C++ compiler.  (I have since modified R-devel not to use isfinite in 
packages.)

Another example (from MSBVAR)

"/usr/include/stdbool.h", line 42: Error: #error "Use of<stdbool.h> is 
valid only in a c99 compilation environment.".

In a Linux environment the Sun Studio CC compiler will not compile some 
standard C headers such as stdlib.h and math.h (and really cstdlib and 
cmath should be used).


3) Using features of particular sets of headers, e.g.

"General.h", line 3: Error: Could not open include file<map.h>.
"Scythe_Matrix.h", line 193: Error: __PRETTY_FUNCTION__ is not defined.
"mstructs.cc", line 733: Error: The function "isinf" must have a prototype.
"unf.cpp", line 459: Error: The function "finite" must have a prototype.
"matrix.h", line 142: Error: Could not open include file<stdexcep>.
"gnm.c", line 113: identifier redeclared: single
"data.cpp", line 129: Error: _Ios_Openmode is not a member of std.
"./metasim.h", line 32: Error: Could not open include file<ext/algorithm>.
"gbmentry.cpp", line 703: Error: NAN is not defined.


4) There are several instances on Solaris of things like

"GCDcrt.cpp", line 46: Error: Overloading ambiguity between 
"std::sqrt(double)" and "std::sqrt(long double)".


-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



[Rd] Package portability issues
Prof Brian Ripley