blob: 49a8e7dc70a10a2ce06915a0f8d8900a2b127440 [file] [log] [blame]
// Copyright 2020 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 static com.google.common.truth.Truth.assertThat;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.ConfigurationMakeVariableContext;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.util.Crosstool.CcToolchainConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for calculating the sysroot that require building configured targets. */
@RunWith(JUnit4.class)
public final class CppSysrootTest extends BuildViewTestCase {
@Before
public void writeDummyLibrary() throws Exception {
scratch.file("dummy/BUILD", "cc_library(name='library')");
}
void testCCFlagsContainsSysroot(
BuildConfigurationValue config, String sysroot, boolean shouldContain) throws Exception {
RuleContext ruleContext =
getRuleContext(getConfiguredTarget(Label.parseCanonical("//dummy:library"), config));
ConfigurationMakeVariableContext context =
new ConfigurationMakeVariableContext(
ruleContext,
ruleContext.getTarget().getPackage(),
config,
ImmutableList.of(new CcCommon.CcFlagsSupplier(ruleContext)));
if (shouldContain) {
assertThat(context.lookupVariable("CC_FLAGS")).contains("--sysroot=" + sysroot);
} else {
assertThat(context.lookupVariable("CC_FLAGS")).doesNotContain("--sysroot=" + sysroot);
}
}
CcToolchainProvider getCcToolchainProvider(BuildConfigurationValue configuration)
throws Exception {
CppConfiguration cppConfiguration = configuration.getFragment(CppConfiguration.class);
return Preconditions.checkNotNull(
getConfiguredTarget(cppConfiguration.getRuleProvidingCcToolchainProvider(), configuration)
.get(CcToolchainProvider.PROVIDER));
}
@Test
public void testHostGrteTop() throws Exception {
scratch.file("a/grte/top/BUILD", "filegroup(name='everything')", "cc_library(name='library')");
useConfiguration(
"--host_grte_top=//a/grte/top", "--noincompatible_enable_cc_toolchain_resolution");
BuildConfigurationValue target = getTargetConfiguration();
CcToolchainProvider targetCcProvider = getCcToolchainProvider(target);
BuildConfigurationValue host = getHostConfiguration();
CcToolchainProvider hostCcProvider = getCcToolchainProvider(host);
testCCFlagsContainsSysroot(host, "a/grte/top", true);
assertThat(hostCcProvider.getSysroot().equals(targetCcProvider.getSysroot())).isFalse();
}
@Test
public void testOverrideHostGrteTop() throws Exception {
scratch.file("a/grte/top/BUILD", "filegroup(name='everything')");
scratch.file("b/grte/top/BUILD", "filegroup(name='everything')");
useConfiguration(
"--grte_top=//a/grte/top",
"--host_grte_top=//b/grte/top",
"--noincompatible_enable_cc_toolchain_resolution");
BuildConfigurationValue target = getTargetConfiguration();
CcToolchainProvider targetCcProvider = getCcToolchainProvider(target);
BuildConfigurationValue host = getHostConfiguration();
CcToolchainProvider hostCcProvider = getCcToolchainProvider(host);
assertThat(targetCcProvider.getSysroot()).isEqualTo("a/grte/top");
assertThat(hostCcProvider.getSysroot()).isEqualTo("b/grte/top");
testCCFlagsContainsSysroot(target, "a/grte/top", true);
testCCFlagsContainsSysroot(target, "b/grte/top", false);
testCCFlagsContainsSysroot(host, "b/grte/top", true);
testCCFlagsContainsSysroot(host, "a/grte/top", false);
}
@Test
public void testGrteTopAlias() throws Exception {
scratch.file("a/grte/top/BUILD", "filegroup(name='everything')");
scratch.file("b/grte/top/BUILD", "alias(name='everything', actual='//a/grte/top:everything')");
useConfiguration("--grte_top=//b/grte/top", "--noincompatible_enable_cc_toolchain_resolution");
BuildConfigurationValue target = getTargetConfiguration();
CcToolchainProvider targetCcProvider = getCcToolchainProvider(target);
assertThat(targetCcProvider.getSysroot()).isEqualTo("a/grte/top");
testCCFlagsContainsSysroot(target, "a/grte/top", true);
testCCFlagsContainsSysroot(target, "b/grte/top", false);
}
@Test
public void testSysroot() throws Exception {
// BuildConfigurationValue shouldn't provide a sysroot option by default.
useConfiguration("--cpu=k8", "--noincompatible_enable_cc_toolchain_resolution");
BuildConfigurationValue config = getTargetConfiguration();
testCCFlagsContainsSysroot(config, "/usr/grte/v1", true);
scratch.file("a/grte/top/BUILD", "filegroup(name='everything')");
// BuildConfigurationValue should work with label grte_top options.
useConfiguration(
"--cpu=k8",
"--grte_top=//a/grte/top:everything",
"--noincompatible_enable_cc_toolchain_resolution");
config = getTargetConfiguration();
testCCFlagsContainsSysroot(config, "a/grte/top", true);
}
@Test
public void testSysrootInFeatureConfigBlocksLegacySysroot() throws Exception {
AnalysisMock.get()
.ccSupport()
.setupCcToolchainConfig(
mockToolsConfig,
CcToolchainConfig.builder().withActionConfigs("sysroot_in_action_config"));
scratch.overwriteFile("a/grte/top/BUILD", "filegroup(name='everything')");
useConfiguration(
"--grte_top=//a/grte/top:everything", "--noincompatible_enable_cc_toolchain_resolution");
RuleContext ruleContext =
getRuleContext(getConfiguredTarget(Label.parseCanonical("//dummy:library"), targetConfig));
ConfigurationMakeVariableContext context =
new ConfigurationMakeVariableContext(
ruleContext,
ruleContext.getTarget().getPackage(),
targetConfig,
ImmutableList.of(new CcCommon.CcFlagsSupplier(ruleContext)));
assertThat(context.lookupVariable("CC_FLAGS"))
.contains("fc-start --sysroot=a/grte/top-from-feature fc-end");
assertThat(context.lookupVariable("CC_FLAGS")).doesNotContain("--sysroot=a/grte/top fc");
}
@Test
public void testSysrootWithHostConfig() throws Exception {
// The host BuildConfigurationValue shouldn't provide a sysroot option by default.
for (String cpu : new String[] {"piii", "k8"}) {
useConfiguration("--cpu=" + cpu, "--noincompatible_enable_cc_toolchain_resolution");
BuildConfigurationValue config = getHostConfiguration();
testCCFlagsContainsSysroot(config, "/usr/grte/v1", true);
}
// The host BuildConfigurationValue should work with label grte_top options.
scratch.file("a/grte/top/BUILD", "filegroup(name='everything')");
for (String cpu : new String[] {"piii", "k8"}) {
useConfiguration(
"--cpu=" + cpu,
"--host_grte_top=//a/grte/top",
"--noincompatible_enable_cc_toolchain_resolution");
BuildConfigurationValue config = getHostConfiguration();
testCCFlagsContainsSysroot(config, "a/grte/top", true);
// "--grte_top" does *not* set the host grte_top,
// so we don't get "a/grte/top" here, but instead the default "/usr/grte/v1"
useConfiguration(
"--cpu=" + cpu,
"--grte_top=//a/grte/top",
"--noincompatible_enable_cc_toolchain_resolution");
config = getHostConfiguration();
testCCFlagsContainsSysroot(config, "/usr/grte/v1", true);
// If a host_crosstool_top is set, we shouldn't see the grte_top option in the host config.
// (Assuming there was not also a --host_grte_top specified)
useConfiguration(
"--cpu=" + cpu,
"--grte_top=//a/grte/top",
"--host_crosstool_top=" + analysisMock.ccSupport().getMockCrosstoolLabel(),
"--noincompatible_enable_cc_toolchain_resolution");
config = getHostConfiguration();
testCCFlagsContainsSysroot(config, "/usr/grte/v1", true);
}
}
@Test
public void testConfigurableSysroot() throws Exception {
scratch.file(
"test/config_setting/BUILD",
"config_setting(name='defines', values={'define': 'override_grte_top=1'})");
scratch.file("a/grte/top/BUILD", "filegroup(name='everything')");
scratch.file("b/grte/top/BUILD", "filegroup(name='everything')");
scratch.file(
"c/grte/top/BUILD",
"alias(",
" name = 'everything',",
" actual=select(",
" {'//test/config_setting:defines' : '//a/grte/top:everything',",
" '//conditions:default' : '//b/grte/top:everything'}",
" )",
")");
useConfiguration(
"--grte_top=//c/grte/top:everything", "--noincompatible_enable_cc_toolchain_resolution");
CcToolchainProvider ccProvider = getCcToolchainProvider(getTargetConfiguration());
assertThat(ccProvider.getSysroot()).isEqualTo("b/grte/top");
useConfiguration(
"--grte_top=//c/grte/top:everything",
"--define=override_grte_top=1",
"--noincompatible_enable_cc_toolchain_resolution");
ccProvider = getCcToolchainProvider(getTargetConfiguration());
assertThat(ccProvider.getSysroot()).isEqualTo("a/grte/top");
}
}