# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
# Configuration file for the 'lit' test runner.

import os
import re
import subprocess
import lit.formats

# Tell pylint that we know config and lit_config exist somewhere.
if 'PYLINT_IMPORT' in os.environ:
    config = object()
    lit_config = object()

def prepend_dynamic_library_path(path):
    if config.operating_system == 'Windows':
        name = 'PATH'
        sep = ';'
    elif config.operating_system == 'Darwin':
        name = 'DYLD_LIBRARY_PATH'
        sep = ':'
    else:
        name = 'LD_LIBRARY_PATH'
        sep = ':'
    if name in config.environment:
        config.environment[name] = path + sep + config.environment[name]
    else:
        config.environment[name] = path

# name: The name of this test suite.
config.name = 'libomp'

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.c', '.cpp']

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)

# test_exec_root: The root object directory where output is placed
config.test_exec_root = config.libomp_obj_root

# test format
config.test_format = lit.formats.ShTest()

# compiler flags
flags = " -I " + config.test_source_root + \
    " -L " + config.library_dir + \
    " " + config.test_extra_flags
if config.has_omit_frame_pointer_flag:
    flags += " -fno-omit-frame-pointer"

config.test_flags = " -I " + config.omp_header_directory + flags
config.test_flags_use_compiler_omp_h = flags


# extra libraries
libs = ""
if config.has_libm:
    libs += " -lm"
if config.has_libatomic:
    libs += " -latomic"

# Allow REQUIRES / UNSUPPORTED / XFAIL to work
config.target_triple = [ ]
for feature in config.test_compiler_features:
    config.available_features.add(feature)

# Setup environment to find dynamic library at runtime
if config.using_hwloc:
    prepend_dynamic_library_path(config.hwloc_library_dir)
    config.available_features.add('hwloc')
# Note: please keep config.library_dir *after* any potentially system
# directories, as otherwise preinstalled openmp libraries will be used
# over just-built
prepend_dynamic_library_path(config.library_dir)

# Rpath modifications for Darwin
if config.operating_system == 'Darwin':
    config.test_flags += " -Wl,-rpath," + config.library_dir
    if config.using_hwloc:
        config.test_flags += " -Wl,-rpath," + config.hwloc_library_dir

# Find the SDK on Darwin
if config.operating_system == 'Darwin':
  cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  out, err = cmd.communicate()
  out = out.strip().decode()
  res = cmd.wait()
  if res == 0 and out:
    config.test_flags += " -isysroot " + out

# Disable OMPT tests if FileCheck was not found
if config.has_ompt and config.test_filecheck == "":
    lit_config.note("Not testing OMPT because FileCheck was not found")
    config.has_ompt = False

if config.has_ompt:
    config.available_features.add("ompt")
    # for callback.h
    config.test_flags += " -I " + config.test_source_root + "/ompt"

if 'Linux' in config.operating_system:
    config.available_features.add("linux")

if config.operating_system == 'NetBSD':
    config.available_features.add("netbsd")

if config.operating_system in ['Linux', 'Windows']:
    config.available_features.add('affinity')

import multiprocessing
try:
    if multiprocessing.cpu_count() > 1:
        config.available_features.add('multicpu')
except NotImplementedError:
    pass

# to run with icc INTEL_LICENSE_FILE must be set
if 'INTEL_LICENSE_FILE' in os.environ:
    config.environment['INTEL_LICENSE_FILE'] = os.environ['INTEL_LICENSE_FILE']

# substitutions
config.substitutions.append(("%libomp-compile-and-run", \
    "%libomp-compile && %libomp-run"))
config.substitutions.append(("%libomp-c99-compile-and-run", \
    "%libomp-c99-compile && %libomp-run"))
config.substitutions.append(("%libomp-cxx-compile-and-run", \
    "%libomp-cxx-compile && %libomp-run"))
config.substitutions.append(("%libomp-cxx-compile-c", \
    "%clangXX %openmp_flags %flags -std=c++14 -x c++ %s -o %t" + libs))
config.substitutions.append(("%libomp-cxx-compile", \
    "%clangXX %openmp_flags %flags -std=c++14 %s -o %t" + libs))
config.substitutions.append(("%libomp-compile", \
    "%clang %openmp_flags %flags %s -o %t" + libs))
config.substitutions.append(("%libomp-c99-compile", \
    "%clang %openmp_flags %flags -std=c99 %s -o %t" + libs))
config.substitutions.append(("%libomp-run", "%t"))
config.substitutions.append(("%clangXX", config.test_cxx_compiler))
config.substitutions.append(("%clang", config.test_c_compiler))
config.substitutions.append(("%openmp_flags", config.test_openmp_flags))
# %flags-use-compiler-omp-h allows us to use the test compiler's omp.h file which
# may have different definitions of structures than our omp.h file.
if config.is_standalone_build:
    config.substitutions.append(("%flags-use-compiler-omp-h",
        config.test_flags_use_compiler_omp_h))
else:
    # If testing the runtime within an LLVM tree, then always include omp.h
    # directory associated with the new clang compiler.
    config.substitutions.append(("%flags-use-compiler-omp-h",
        config.test_flags))
config.substitutions.append(("%flags", config.test_flags))
config.substitutions.append(("%python", '"%s"' % (sys.executable)))
config.substitutions.append(("%not", config.test_not))

if config.has_ompt:
    config.substitutions.append(("FileCheck", "tee %%t.out | %s" % config.test_filecheck))
    config.substitutions.append(("%sort-threads", "sort -n -s"))
    if config.operating_system == 'Windows':
        # No such environment variable on Windows.
        config.substitutions.append(("%preload-tool", "true ||"))
        config.substitutions.append(("%no-as-needed-flag", "-Wl,--no-as-needed"))
    elif config.operating_system == 'Darwin':
        config.substitutions.append(("%preload-tool", "env DYLD_INSERT_LIBRARIES=%T/tool.so"))
        # No such linker flag on Darwin.
        config.substitutions.append(("%no-as-needed-flag", ""))
    else:
        config.substitutions.append(("%preload-tool", "env LD_PRELOAD=%T/tool.so"))
        config.substitutions.append(("%no-as-needed-flag", "-Wl,--no-as-needed"))
else:
    config.substitutions.append(("FileCheck", config.test_filecheck))
