aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/cpp/lib_cc_configure.bzl
blob: 2287955ad5b2133b38f62dc3d3448b68dd06a4e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# pylint: disable=g-bad-file-header
# Copyright 2016 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Base library for configuring the C++ toolchain."""


def escape_string(arg):
  """Escape percent sign (%) in the string so it can appear in the Crosstool."""
  if arg != None:
    return str(arg).replace("%", "%%")
  else:
    return None


def auto_configure_fail(msg):
  """Output failure message when auto configuration fails."""
  red = "\033[0;31m"
  no_color = "\033[0m"
  fail("\n%sAuto-Configuration Error:%s %s\n" % (red, no_color, msg))


def auto_configure_warning(msg):
  """Output warning message during auto configuration."""
  yellow = "\033[1;33m"
  no_color = "\033[0m"
  print("\n%sAuto-Configuration Warning:%s %s\n" % (yellow, no_color, msg))


def get_env_var(repository_ctx, name, default = None, enable_warning = True):
  """Find an environment variable in system path. Doesn't %-escape the value!"""
  if name in repository_ctx.os.environ:
    return repository_ctx.os.environ[name]
  if default != None:
    if enable_warning:
      auto_configure_warning("'%s' environment variable is not set, using '%s' as default" % (name, default))
    return default
  auto_configure_fail("'%s' environment variable is not set" % name)


def which(repository_ctx, cmd, default = None):
  """A wrapper around repository_ctx.which() to provide a fallback value. Doesn't %-escape the value!"""
  result = repository_ctx.which(cmd)
  return default if result == None else str(result)


def which_cmd(repository_ctx, cmd, default = None):
  """Find cmd in PATH using repository_ctx.which() and fail if cannot find it. Doesn't %-escape the cmd!"""
  result = repository_ctx.which(cmd)
  if result != None:
    return str(result)
  path = get_env_var(repository_ctx, "PATH")
  if default != None:
    auto_configure_warning("Cannot find %s in PATH, using '%s' as default.\nPATH=%s" % (cmd, default, path))
    return default
  auto_configure_fail("Cannot find %s in PATH, please make sure %s is installed and add its directory in PATH.\nPATH=%s" % (cmd, cmd, path))
  return str(result)


def execute(repository_ctx, command, environment = None,
            expect_failure = False):
  """Execute a command, return stdout if succeed and throw an error if it fails. Doesn't %-escape the result!"""
  if environment:
    result = repository_ctx.execute(command, environment = environment)
  else:
    result = repository_ctx.execute(command)
  if expect_failure != (result.return_code != 0):
    if expect_failure:
      auto_configure_fail(
          "expected failure, command %s, stderr: (%s)" % (
              command, result.stderr))
    else:
      auto_configure_fail(
          "non-zero exit code: %d, command %s, stderr: (%s)" % (
              result.return_code, command, result.stderr))
  stripped_stdout = result.stdout.strip()
  if not stripped_stdout:
    auto_configure_fail(
        "empty output from command %s, stderr: (%s)" % (command, result.stderr))
  return stripped_stdout


def get_cpu_value(repository_ctx):
  """Compute the cpu_value based on the OS name. Doesn't %-escape the result!"""
  os_name = repository_ctx.os.name.lower()
  if os_name.startswith("mac os"):
    return "darwin"
  if os_name.find("freebsd") != -1:
    return "freebsd"
  if os_name.find("windows") != -1:
    return "x64_windows"
  # Use uname to figure out whether we are on x86_32 or x86_64
  result = repository_ctx.execute(["uname", "-m"])
  if result.stdout.strip() in ["power", "ppc64le", "ppc", "ppc64"]:
    return "ppc"
  if result.stdout.strip() in ["arm", "armv7l", "aarch64"]:
    return "arm"
  return "k8" if result.stdout.strip() in ["amd64", "x86_64", "x64"] else "piii"


def tpl(repository_ctx, template, substitutions={}, out=None):
  if not out:
    out = template
  repository_ctx.template(
      out,
      Label("@bazel_tools//tools/cpp:%s.tpl" % template),
      substitutions)


def is_cc_configure_debug(repository_ctx):
  """Returns True if CC_CONFIGURE_DEBUG is set to 1."""
  env = repository_ctx.os.environ
  return "CC_CONFIGURE_DEBUG" in env and env["CC_CONFIGURE_DEBUG"] == "1"