blob: f3c05879d0a2dc8a68e16d64eddd3a5d28c01b1c [file] [log] [blame]
#!/usr/bin/env python
# check-incremental - Check if incremental compilation works -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
#
# ----------------------------------------------------------------------------
#
# This is a wrapper for the swift compiler.
# It invokes the compiler multiple times and checks if the output object file
# is only written a single time.
# The main purpose of the check is to ensure that the compiler is
# deterministic.
#
# ----------------------------------------------------------------------------
import os
import subprocess
import sys
def main():
verbose = False
num_iterations = 4
write_obj_file = False
next_arg_is_output = False
compare_time = True
output_file = None
for arg in sys.argv:
if next_arg_is_output:
output_file = arg
next_arg_is_output = False
elif arg == '-c':
write_obj_file = True
elif arg == '-disable-incremental-llvm-codegen':
compare_time = False
elif arg == '-o':
next_arg_is_output = True
if not write_obj_file or output_file is None:
return
new_args = sys.argv[1:]
subprocess.check_call(new_args)
if verbose:
print "Reference compilation of " + output_file + ":"
reference_md5 = subprocess.check_output(["md5", "-q", output_file])
reference_time = os.path.getmtime(output_file)
if verbose:
print " time = {}".format(reference_time)
print " md5 = " + reference_md5
subprocess.check_call(["cp", output_file, output_file + ".ref.o"])
for iteration in range(0, num_iterations):
if verbose:
print "Iteration {}:".format(iteration)
subprocess.check_call(new_args)
second_md5 = subprocess.check_output(["md5", "-q", output_file])
second_time = os.path.getmtime(output_file)
if verbose:
print " time = {}".format(second_time)
print " md5 = " + second_md5
# This is the most important check: is the output file exactly the
# same.
if reference_md5 != second_md5:
sys.exit("non-determinism when generating: " + output_file)
# This is the bonus check: does the compiler not re-write the output
# file. (For compilations < 1sec this check may succeed even if the
# file was overwritten).
if compare_time and reference_time != second_time:
sys.exit("file re-written: " + output_file)
main()