Fortran: Add support for GNU >= 4.9 compressed modules (#14975)

From the GCC 4.9 release notes for Fortran:

 https://gcc.gnu.org/gcc-4.9/changes.html
 "Module files: The version of the module files (.mod) has been
  incremented; additionally, module files are now compressed."

Teach cmDependsFortran::ModulesDiffer to look for the gzip magic numbers
at the beginning of the module file.  If found, assume the module was
produced by gfortran >= 4.9.  The modules do not appear to contain the
date as earlier versions did so we can compare the content directly
and do not actually need to decompress.
This commit is contained in:
Brad King 2014-06-19 09:11:29 -04:00
parent 55d6aa36a5
commit d90be200ec
1 changed files with 27 additions and 14 deletions

View File

@ -765,7 +765,11 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
const char* compilerId) const char* compilerId)
{ {
/* /*
gnu: gnu >= 4.9:
A mod file is an ascii file compressed with gzip.
Compiling twice produces identical modules.
gnu < 4.9:
A mod file is an ascii file. A mod file is an ascii file.
<bar.mod> <bar.mod>
FORTRAN module created from /path/to/foo.f90 on Sun Dec 30 22:47:58 2007 FORTRAN module created from /path/to/foo.f90 on Sun Dec 30 22:47:58 2007
@ -821,21 +825,30 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
*/ */
if (strcmp(compilerId, "GNU") == 0 ) if (strcmp(compilerId, "GNU") == 0 )
{ {
const char seq[1] = {'\n'}; // GNU Fortran 4.9 and later compress .mod files with gzip
const int seqlen = 1; // but also do not include a date so we can fall through to
// compare them without skipping any prefix.
if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen)) unsigned char hdr[2];
bool okay = finModFile.read(reinterpret_cast<char*>(hdr), 2)? true:false;
finModFile.seekg(0);
if(!(okay && hdr[0] == 0x1f && hdr[1] == 0x8b))
{ {
// The module is of unexpected format. Assume it is different. const char seq[1] = {'\n'};
std::cerr << compilerId << " fortran module " << modFile const int seqlen = 1;
<< " has unexpected format." << std::endl;
return true;
}
if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen)) if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
{ {
// The stamp must differ if the sequence is not contained. // The module is of unexpected format. Assume it is different.
return true; std::cerr << compilerId << " fortran module " << modFile
<< " has unexpected format." << std::endl;
return true;
}
if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
{
// The stamp must differ if the sequence is not contained.
return true;
}
} }
} }
else if(strcmp(compilerId, "Intel") == 0) else if(strcmp(compilerId, "Intel") == 0)