blob: 300c1fff758dcf5cd15bf51370e2fb9f249fecc1 [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.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.ConfigurationMakeVariableContext;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
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(BuildConfiguration config, String sysroot, boolean shouldContain)
throws Exception {
RuleContext ruleContext =
getRuleContext(
getConfiguredTarget(Label.parseAbsolute("//dummy:library", ImmutableMap.of()), 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(BuildConfiguration configuration) throws Exception {
CppConfiguration cppConfiguration = configuration.getFragment(CppConfiguration.class);
return Preconditions.checkNotNull(
(CcToolchainProvider)
getConfiguredTarget(
cppConfiguration.getRuleProvidingCcToolchainProvider(), configuration)
.get(ToolchainInfo.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");
BuildConfiguration target = getTargetConfiguration();
CcToolchainProvider targetCcProvider = getCcToolchainProvider(target);
BuildConfiguration 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");
BuildConfiguration target = getTargetConfiguration();
CcToolchainProvider targetCcProvider = getCcToolchainProvider(target);
BuildConfiguration 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");
BuildConfiguration 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 {
// BuildConfiguration shouldn't provide a sysroot option by default.
useConfiguration("--cpu=k8");
BuildConfiguration config = getTargetConfiguration();
testCCFlagsContainsSysroot(config, "/usr/grte/v1", true);
scratch.file("a/grte/top/BUILD", "filegroup(name='everything')");
// BuildConfiguration should work with label grte_top options.
useConfiguration("--cpu=k8", "--grte_top=//a/grte/top:everything");
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");
RuleContext ruleContext =
getRuleContext(
getConfiguredTarget(
Label.parseAbsolute("//dummy:library", ImmutableMap.of()), 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 BuildConfiguration shouldn't provide a sysroot option by default.
for (String cpu : new String[] {"piii", "k8"}) {
useConfiguration("--cpu=" + cpu);
BuildConfiguration config = getHostConfiguration();
testCCFlagsContainsSysroot(config, "/usr/grte/v1", true);
}
// The host BuildConfiguration 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");
BuildConfiguration 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");
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());
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");
CcToolchainProvider ccProvider = getCcToolchainProvider(getTargetConfiguration());
assertThat(ccProvider.getSysroot()).isEqualTo("b/grte/top");
useConfiguration("--grte_top=//c/grte/top:everything", "--define=override_grte_top=1");
ccProvider = getCcToolchainProvider(getTargetConfiguration());
assertThat(ccProvider.getSysroot()).isEqualTo("a/grte/top");
}
}