blob: 94acb9b329e5714cdfc0e62f3704830d781541c9 [file] [log] [blame]
import os
import StringIO
import DEUtils
from lit import Test
import lit.util
def describeFailure(output, cmd, out, err, exitCode):
print >>output, "Command:",
print >>output, ' '.join(cmd)
print >>output, "Failed with exit code: %r" % exitCode
if out:
print >>output, "Command output (stdout):"
print >>output, "--"
output.write(out)
print >>output, "--"
if err:
print >>output, "Command output (stderr):"
print >>output, "--"
output.write(err)
print >>output, "--"
def compareCommands(cmds, args, cwd=None):
def executeOne(cmd):
return DEUtils.executeCommand(cmd + args, cwd)
results = map(executeOne, cmds)
failed = False
# Check that all commands exited with the same code.
out,err,commonExitCode = results[0]
for result in results:
out,err,exitCode = result
if exitCode != commonExitCode:
failed = True
break
# TODO: Consider comparing command output as well as the exit codes.
if not failed:
return (Test.PASS, None)
# Failure.
output = StringIO.StringIO()
for cmd,result in zip(cmds,results):
out,err,exitCode = result
if exitCode != 0:
describeFailure(output, cmd + args, out, err, exitCode)
return (Test.FAIL, output.getvalue())
def generateFortranModules(cmd, srcPath, OutputDir):
# Fortran 90 code often fails to compile because it needs modules defined by
# other files in the same directory. If this seems to be happening then try
# to generate all of the required modules by compiling every Fortran file in
# the same directory.
srcDir,srcBase = os.path.split(srcPath)
cmd = cmd + ['-I', srcDir, '-fsyntax-only']
# If the file compiles OK or isn't failing because of lacking modules then
# there is no point in trying to generate modules.
out,err,exitCode = DEUtils.executeCommand(cmd + [srcPath], OutputDir)
if exitCode == 0 or err is None or "Can't open module file" not in err:
return
# Drat, it fails to compile. Generate modules for every Fortran file in the
# source directory.
fortranSuffixes = DEUtils.getSuffixesForLanguage('fortran')
filesToCompile = []
for filename in os.listdir(srcDir):
filepath = os.path.join(srcDir, filename)
if not os.path.isdir(filepath):
base,ext = os.path.splitext(filename)
if ext in fortranSuffixes:
filesToCompile.append(filepath)
# Compile every file, returning triumphantly once the original file manages
# to compile, or giving up miserably if no progress is being made.
newFilesToCompile = []
while filesToCompile != newFilesToCompile:
newFilesToCompile = []
# Compile each file in turn.
for path in filesToCompile:
out,err,exitCode = DEUtils.executeCommand(cmd + [path], OutputDir)
if exitCode != 0 and err is not None and "Can't open module file" in err:
# It failed to compile due to a missing module. Remember it for
# the next round.
newFilesToCompile.append(path);
elif path == srcPath:
# The original file compiled, or at least didn't fail to compile
# due to a lacking module. Return triumphantly!
return
# Arrange for the next iteration to compile the files that were missing
# modules this time round.
filesToCompile, newFilesToCompile = newFilesToCompile, filesToCompile
# The set of files missing modules didn't change, give up miserably.
return
def executeCompilatorTest(test, litConfig, compilers, flags, language_flags,
skip, xfails):
test_path = '/'.join(test.path_in_suite)
# Skip this test if requested to do so.
if test_path in skip:
return (Test.UNSUPPORTED, None)
# Create the output directory if it does not already exist.
execPath = test.getExecPath()
execDir,execBase = os.path.split(execPath)
tmpDir = os.path.join(execDir, 'Output')
tmpDir = os.path.join(tmpDir, execBase)
lit.util.mkdir_p(tmpDir)
# Is this test expected to fail?
isXFail = test_path in xfails
# The file should be compiled to assembler.
srcPath = test.getSourcePath();
common_args = ['-S', srcPath]
# Look for headers and such-like in the directory containing the source.
srcDir,srcBase = os.path.split(srcPath)
common_args += ['-I', srcDir]
# Add any file specific flags.
srcBase,srcExt = os.path.splitext(srcPath)
language = DEUtils.getLanguageForSuffix(srcExt)
if language in language_flags:
common_args += language_flags[language]
# Fortran files may not compile because they need modules provided by other
# Fortran files. Workaround this by generating missing modules if possible.
if language == 'fortran':
generateFortranModules(compilers[0], srcPath, tmpDir)
# Compile the test.
for args in flags:
result,output = compareCommands(compilers, common_args + args, tmpDir)
if result != Test.PASS:
return (Test.XFAIL if isXFail else result,output)
return (Test.XPASS if isXFail else Test.PASS, None)