1# -*- Python -*-
2
3import os
4import platform
5
6import lit.formats
7
8# Choose between lit's internal shell pipeline runner and a real shell.  If
9# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
10use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
11if use_lit_shell:
12    # 0 is external, "" is default, and everything else is internal.
13    execute_external = (use_lit_shell == "0")
14else:
15    # Otherwise we default to internal on Windows and external elsewhere, as
16    # bash on Windows is usually very slow.
17    execute_external = (not sys.platform in ['win32'])
18
19def get_required_attr(config, attr_name):
20  attr_value = getattr(config, attr_name, None)
21  if attr_value == None:
22    lit_config.fatal(
23      "No attribute %r in test configuration! You may need to run "
24      "tests from your build directory or add this attribute "
25      "to lit.site.cfg.py " % attr_name)
26  return attr_value
27
28# Setup config name.
29config.name = 'Builtins' + config.name_suffix
30
31# Platform-specific default Builtins_OPTIONS for lit tests.
32default_builtins_opts = ''
33
34# Setup source root.
35config.test_source_root = os.path.dirname(__file__)
36
37# Path to the static library
38is_msvc = get_required_attr(config, "is_msvc")
39if is_msvc:
40  base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.builtins%s.lib "
41                          % config.target_suffix)
42  config.substitutions.append( ("%librt ", base_lib) )
43elif config.host_os  == 'Darwin':
44  base_lib = os.path.join(config.compiler_rt_libdir, "libclang_rt.osx.a ")
45  config.substitutions.append( ("%librt ", base_lib + ' -lSystem ') )
46else:
47  base_lib = os.path.join(config.compiler_rt_libdir, "libclang_rt.builtins%s.a"
48                          % config.target_suffix)
49  if sys.platform in ['win32'] and execute_external:
50    # Don't pass dosish path separator to msys bash.exe.
51    base_lib = base_lib.replace('\\', '/')
52  config.substitutions.append( ("%librt ", base_lib + ' -lc -lm ') )
53
54builtins_source_dir = os.path.join(
55  get_required_attr(config, "compiler_rt_src_root"), "lib", "builtins")
56if sys.platform in ['win32'] and execute_external:
57  # Don't pass dosish path separator to msys bash.exe.
58  builtins_source_dir = builtins_source_dir.replace('\\', '/')
59builtins_lit_source_dir = get_required_attr(config, "builtins_lit_source_dir")
60
61extra_link_flags = ["-nodefaultlibs"]
62
63target_cflags = [get_required_attr(config, "target_cflags")]
64target_cflags += ['-fno-builtin', '-I', builtins_source_dir]
65target_cflags += extra_link_flags
66target_cxxflags = config.cxx_mode_flags + target_cflags
67clang_builtins_static_cflags = ([""] +
68                            config.debug_info_flags + target_cflags)
69clang_builtins_static_cxxflags = config.cxx_mode_flags + \
70                                 clang_builtins_static_cflags
71
72clang_builtins_cflags = clang_builtins_static_cflags
73clang_builtins_cxxflags = clang_builtins_static_cxxflags
74
75# FIXME: Right now we don't compile the C99 complex builtins when using
76# clang-cl. Fix that.
77if not is_msvc:
78  config.available_features.add('c99-complex')
79
80builtins_is_msvc = get_required_attr(config, "builtins_is_msvc")
81if not builtins_is_msvc:
82  config.available_features.add('int128')
83
84clang_wrapper = ""
85
86def build_invocation(compile_flags):
87  return " " + " ".join([clang_wrapper, config.clang] + compile_flags) + " "
88
89
90config.substitutions.append( ("%clang ", build_invocation(target_cflags)) )
91config.substitutions.append( ("%clangxx ", build_invocation(target_cxxflags)) )
92config.substitutions.append( ("%clang_builtins ", \
93                              build_invocation(clang_builtins_cflags)))
94config.substitutions.append( ("%clangxx_builtins ", \
95                              build_invocation(clang_builtins_cxxflags)))
96
97# Default test suffixes.
98config.suffixes = ['.c', '.cpp']
99
100if not config.emulator:
101  config.available_features.add('native-run')
102
103# Add features for available sources
104builtins_source_features = config.builtins_lit_source_features.split(';')
105# Sanity checks
106if not builtins_source_features:
107  lit_config.fatal('builtins_source_features cannot be empty')
108builtins_source_features_set = set()
109builtins_source_feature_duplicates = []
110for builtin_source_feature in builtins_source_features:
111  if len(builtin_source_feature) == 0:
112    lit_config.fatal('builtins_source_feature cannot contain empty features')
113  if builtin_source_feature not in builtins_source_features_set:
114    builtins_source_features_set.add(builtin_source_feature)
115  else:
116    builtins_source_feature_duplicates.append(builtin_source_feature)
117
118if len(builtins_source_feature_duplicates) > 0:
119  lit_config.fatal(
120    'builtins_source_features contains duplicates: {}'.format(
121      builtins_source_feature_duplicates)
122  )
123config.available_features.update(builtins_source_features)
124