aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationIdentifier.java
blob: 00988106b552f530766dbcf816cd80ebf2c635f7 (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright 2014 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.

package com.google.devtools.build.lib.rules.cpp;

import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Options;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;

import java.util.Objects;

/**
 * Contains parameters which uniquely describe a crosstool configuration
 * and methods for comparing two crosstools against each other.
 *
 * <p>Two crosstools which contain equivalent values of these parameters are
 * considered equal.
 */
public final class CrosstoolConfigurationIdentifier implements CrosstoolConfigurationOptions {

  private static final String USE_HOST_CPU = "same_as_host";

  /** The CPU associated with this crosstool configuration. */
  private final String cpu;

  /** The compiler (e.g. gcc) associated with this crosstool configuration. */
  private final String compiler;

  /** The version of libc (e.g. glibc-2.11) associated with this crosstool configuration. */
  private final String libc;

  private CrosstoolConfigurationIdentifier(String cpu, String compiler, String libc) {
    this.cpu = cpu;
    this.compiler = compiler;
    this.libc = libc;
  }

  /**
   * Creates a new crosstool configuration from the given crosstool release and
   * configuration options.
   */
  public static CrosstoolConfigurationIdentifier fromReleaseAndCrosstoolConfiguration(
      CrosstoolConfig.CrosstoolRelease release, BuildOptions buildOptions) {
    Options options = buildOptions.get(BuildConfiguration.Options.class);
    String cpu = options.getCpu();
    if (cpu == null) {
      cpu = release.getDefaultTargetCpu();
      if (cpu.equals(USE_HOST_CPU)) {
        cpu = options.hostCpu;
      }
    }
    CppOptions cppOptions = buildOptions.get(CppOptions.class);
    return new CrosstoolConfigurationIdentifier(cpu, cppOptions.cppCompiler, cppOptions.glibc);
  }

  public static CrosstoolConfigurationIdentifier fromToolchain(CToolchain toolchain) {
    return new CrosstoolConfigurationIdentifier(
        toolchain.getTargetCpu(), toolchain.getCompiler(), toolchain.getTargetLibc());
  }

  @Override
  public boolean equals(Object other) {
    if (!(other instanceof CrosstoolConfigurationIdentifier)) {
      return false;
    }
    CrosstoolConfigurationIdentifier otherCrosstool = (CrosstoolConfigurationIdentifier) other;
    return Objects.equals(cpu, otherCrosstool.cpu)
        && Objects.equals(compiler, otherCrosstool.compiler)
        && Objects.equals(libc, otherCrosstool.libc);
  }

  @Override
  public int hashCode() {
    return Objects.hash(cpu, compiler, libc);
  }


  /**
   * Returns a series of command line flags which specify the configuration options.
   * Any of these options may be null, in which case its flag is omitted.
   *
   * <p>The appended string will be along the lines of
   * " --cpu='cpu' --compiler='compiler' --glibc='libc'".
   */
  public String describeFlags() {
    StringBuilder message = new StringBuilder();
    if (getCpu() != null) {
      message.append(" --cpu='").append(getCpu()).append("'");
    }
    if (getCompiler() != null) {
      message.append(" --compiler='").append(getCompiler()).append("'");
    }
    if (getLibc() != null) {
      message.append(" --glibc='").append(getLibc()).append("'");
    }
    return message.toString();
  }

  /** Returns true if the specified toolchain is a candidate for use with this crosstool. */
  public boolean isCandidateToolchain(CToolchain toolchain) {
    return (toolchain.getTargetCpu().equals(getCpu())
        && (getLibc() == null || toolchain.getTargetLibc().equals(getLibc()))
        && (getCompiler() == null || toolchain.getCompiler().equals(
            getCompiler())));
  }

  @Override
  public String toString() {
    return describeFlags();
  }

  @Override
  public String getCpu() {
    return cpu;
  }

  @Override
  public String getCompiler() {
    return compiler;
  }

  @Override
  public String getLibc() {
    return libc;
  }
}