aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar plf <plf@google.com>2018-07-16 01:11:04 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-16 01:12:34 -0700
commite14a7d4f156c28244a491c65083273f57734cdbe (patch)
tree63bae469d108c3d89d80c29013358dd0830f3f6e
parenta567777889fd0abc6c31818054ed18eaa918e1fe (diff)
C++: New functionality exposed to Skylark for external libs.
- CcLinkingInfo has a getter for CcLinkParams. - Artifacts and linkopts of CcLinkParams are accessible. - CcCompilationInfo constructor now accepts defines and include dirs. - CcCompilation now has getters for headers, defines and include dirs. CcCompiilationInfo( headers=depset([Artifacts]), defines=depset([Strings]), include_dirs=depet([Strings]) CcCompilationInfo.headers CcCompilationInfo.defines CcCompilationInfo.include_dirs -- cc_common.merge([CcLinkingInfos]) returns CcLinkingInfo -- CcLinkingInfo.static_shared_params CcLinkingInfo.static_no_shared_params CcLinkingInfo.no_static_shared_params CcLinkingInfo.no_static_no_shared_params -- CcLinkParams.libraries CcLinkParams.linkopts CcLinkParams.dynamic_libraries_for_runtime RELNOTES:none PiperOrigin-RevId: 204700779
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/AbstractCcLinkParamsStore.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationContext.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationInfo.java67
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsStore.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java64
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcCompilationInfoApi.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkParamsApi.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java28
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java222
12 files changed, 453 insertions, 97 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/AbstractCcLinkParamsStore.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/AbstractCcLinkParamsStore.java
index 2849d55e0c..ec9ece078d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/AbstractCcLinkParamsStore.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/AbstractCcLinkParamsStore.java
@@ -47,10 +47,10 @@ import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.
* </pre>
*/
public abstract class AbstractCcLinkParamsStore {
- protected CcLinkParams staticSharedParams;
- protected CcLinkParams staticNoSharedParams;
- protected CcLinkParams noStaticSharedParams;
- protected CcLinkParams noStaticNoSharedParams;
+ protected CcLinkParams staticModeParamsForDynamicLibrary;
+ protected CcLinkParams staticModeParamsForExecutable;
+ protected CcLinkParams dynamicModeParamsForDynamicLibrary;
+ protected CcLinkParams dynamicModeParamsForExecutable;
private CcLinkParams compute(boolean linkingStatically, boolean linkShared) {
CcLinkParams.Builder builder = CcLinkParams.builder(linkingStatically, linkShared);
@@ -76,9 +76,9 @@ public abstract class AbstractCcLinkParamsStore {
private CcLinkParams lookup(boolean linkingStatically, boolean linkShared) {
if (linkingStatically) {
- return linkShared ? staticSharedParams : staticNoSharedParams;
+ return linkShared ? staticModeParamsForDynamicLibrary : staticModeParamsForExecutable;
} else {
- return linkShared ? noStaticSharedParams : noStaticNoSharedParams;
+ return linkShared ? dynamicModeParamsForDynamicLibrary : dynamicModeParamsForExecutable;
}
}
@@ -86,15 +86,15 @@ public abstract class AbstractCcLinkParamsStore {
Preconditions.checkNotNull(params);
if (linkingStatically) {
if (linkShared) {
- staticSharedParams = params;
+ staticModeParamsForDynamicLibrary = params;
} else {
- staticNoSharedParams = params;
+ staticModeParamsForExecutable = params;
}
} else {
if (linkShared) {
- noStaticSharedParams = params;
+ dynamicModeParamsForDynamicLibrary = params;
} else {
- noStaticNoSharedParams = params;
+ dynamicModeParamsForExecutable = params;
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationContext.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationContext.java
index 02c2c184d6..492131bfdd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationContext.java
@@ -483,19 +483,6 @@ public final class CcCompilationContext implements CcCompilationContextApi {
}
/**
- * Add multiple include directories to be added with "-I". These can be
- * either relative to the exec root (see {@link
- * com.google.devtools.build.lib.analysis.BlazeDirectories#getExecRoot}) or absolute. The
- * entries are normalized before they are stored.
- */
- public Builder addIncludeDirs(Iterable<PathFragment> includeDirs) {
- for (PathFragment includeDir : includeDirs) {
- addIncludeDir(includeDir);
- }
- return this;
- }
-
- /**
* Add a single include directory to be added with "-iquote". It can be
* either relative to the exec root (see {@link
* com.google.devtools.build.lib.analysis.BlazeDirectories#getExecRoot}) or absolute. Before it
@@ -507,13 +494,12 @@ public final class CcCompilationContext implements CcCompilationContextApi {
}
/**
- * Add a single include directory to be added with "-isystem". It can be
- * either relative to the exec root (see {@link
- * com.google.devtools.build.lib.analysis.BlazeDirectories#getExecRoot}) or absolute. Before it
- * is stored, the include directory is normalized.
+ * Add a single include directory to be added with "-isystem". It can be either relative to the
+ * exec root (see {@link com.google.devtools.build.lib.analysis.BlazeDirectories#getExecRoot})
+ * or absolute. Before it is stored, the include directory is normalized.
*/
- public Builder addSystemIncludeDir(PathFragment systemIncludeDir) {
- systemIncludeDirs.add(systemIncludeDir);
+ public Builder addSystemIncludeDirs(Iterable<PathFragment> systemIncludeDirs) {
+ Iterables.addAll(this.systemIncludeDirs, systemIncludeDirs);
return this;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java
index f82782f6d4..09ea9f6596 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java
@@ -939,9 +939,8 @@ public final class CcCompilationHelper {
ccCompilationContextBuilder.addQuoteIncludeDir(
ruleContext.getConfiguration().getBinFragment().getRelative(repositoryPath));
- for (PathFragment systemIncludeDir : systemIncludeDirs) {
- ccCompilationContextBuilder.addSystemIncludeDir(systemIncludeDir);
- }
+ ccCompilationContextBuilder.addSystemIncludeDirs(systemIncludeDirs);
+
for (PathFragment includeDir : includeDirs) {
ccCompilationContextBuilder.addIncludeDir(includeDir);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationInfo.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationInfo.java
index 0e540b6106..d6806ad487 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationInfo.java
@@ -21,6 +21,8 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.NativeInfo;
@@ -34,6 +36,8 @@ import com.google.devtools.build.lib.syntax.FunctionSignature;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.SkylarkType;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.Collection;
import javax.annotation.Nullable;
/** Wrapper for every C++ compilation provider. */
@@ -48,9 +52,14 @@ public final class CcCompilationInfo extends NativeInfo implements CcCompilation
/* numMandatoryNamedOnly= */ 0,
/* starArg= */ false,
/* kwArg= */ false,
- "headers"),
- /* defaultValues= */ ImmutableList.of(Runtime.NONE),
- /* types= */ ImmutableList.of(SkylarkType.of(SkylarkNestedSet.class)));
+ "headers",
+ "system_includes",
+ "defines"),
+ /* defaultValues= */ ImmutableList.of(Runtime.NONE, Runtime.NONE, Runtime.NONE),
+ /* types= */ ImmutableList.of(
+ SkylarkType.of(SkylarkNestedSet.class),
+ SkylarkType.of(SkylarkNestedSet.class),
+ SkylarkType.of(SkylarkNestedSet.class)));
@Nullable
private static Object nullIfNone(Object object) {
@@ -71,12 +80,27 @@ public final class CcCompilationInfo extends NativeInfo implements CcCompilation
Object[] args, Environment env, Location loc) throws EvalException {
CcCommon.checkLocationWhitelisted(loc);
CcCompilationInfo.Builder ccCompilationInfoBuilder = CcCompilationInfo.Builder.create();
- SkylarkNestedSet headers = (SkylarkNestedSet) nullIfNone(args[0]);
CcCompilationContext.Builder ccCompilationContext =
new CcCompilationContext.Builder(/* ruleContext= */ null);
+ int i = 0;
+ SkylarkNestedSet headers = (SkylarkNestedSet) nullIfNone(args[i++]);
if (headers != null) {
ccCompilationContext.addDeclaredIncludeSrcs(headers.getSet(Artifact.class));
}
+ SkylarkNestedSet systemIncludes = (SkylarkNestedSet) nullIfNone(args[i++]);
+ if (systemIncludes != null) {
+ ccCompilationContext.addSystemIncludeDirs(
+ systemIncludes
+ .getSet(String.class)
+ .toList()
+ .stream()
+ .map(x -> PathFragment.create(x))
+ .collect(ImmutableList.toImmutableList()));
+ }
+ SkylarkNestedSet defines = (SkylarkNestedSet) nullIfNone(args[i++]);
+ if (defines != null) {
+ ccCompilationContext.addDefines(defines.getSet(String.class));
+ }
ccCompilationInfoBuilder.setCcCompilationContext(ccCompilationContext.build());
return ccCompilationInfoBuilder.build();
}
@@ -91,6 +115,41 @@ public final class CcCompilationInfo extends NativeInfo implements CcCompilation
this.ccCompilationContext = ccCompilationContext;
}
+ public static CcCompilationInfo merge(Collection<CcCompilationInfo> ccCompilationInfos) {
+ CcCompilationContext.Builder builder =
+ new CcCompilationContext.Builder(/* ruleContext= */ null);
+ builder.mergeDependentCcCompilationContexts(
+ ccCompilationInfos
+ .stream()
+ .map(CcCompilationInfo::getCcCompilationContext)
+ .collect(ImmutableList.toImmutableList()));
+ return (new CcCompilationInfo.Builder()).setCcCompilationContext(builder.build()).build();
+ }
+
+ @Override
+ public SkylarkNestedSet getSkylarkDefines() {
+ return SkylarkNestedSet.of(
+ String.class, NestedSetBuilder.wrap(Order.STABLE_ORDER, ccCompilationContext.getDefines()));
+ }
+
+ @Override
+ public SkylarkNestedSet getSkylarkHeaders() {
+ return SkylarkNestedSet.of(Artifact.class, ccCompilationContext.getDeclaredIncludeSrcs());
+ }
+
+ @Override
+ public SkylarkNestedSet getSkylarkDeclaredIncludeDirs() {
+ return SkylarkNestedSet.of(
+ String.class,
+ NestedSetBuilder.wrap(
+ Order.STABLE_ORDER,
+ ccCompilationContext
+ .getSystemIncludeDirs()
+ .stream()
+ .map(PathFragment::getPathString)
+ .collect(ImmutableList.toImmutableList())));
+ }
+
public CcCompilationContext getCcCompilationContext() {
return ccCompilationContext;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java
index 44bc16eb8c..dc94c49408 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParams.java
@@ -30,6 +30,7 @@ import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkParamsApi;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import java.util.Collection;
import java.util.Objects;
import javax.annotation.Nullable;
@@ -106,6 +107,14 @@ public final class CcLinkParams implements CcLinkParamsApi {
return ImmutableList.copyOf(Iterables.concat(Iterables.transform(linkOpts, LinkOptions::get)));
}
+ @Override
+ public SkylarkNestedSet getSkylarkLinkopts() {
+ // TODO(plf): Shouldn't flatten nested set. Remove LinkOptions class and just have a nested set
+ // of strings.
+ return SkylarkNestedSet.of(
+ String.class, NestedSetBuilder.wrap(Order.COMPILE_ORDER, flattenedLinkopts()));
+ }
+
/**
* Returns the linkstamps
*/
@@ -120,11 +129,21 @@ public final class CcLinkParams implements CcLinkParamsApi {
return libraries;
}
+ @Override
+ public SkylarkNestedSet getSkylarkLibrariesToLink() {
+ return SkylarkNestedSet.of(LibraryToLink.class, libraries);
+ }
+
/** Returns the dynamicLibrariesForRuntime. */
public NestedSet<Artifact> getDynamicLibrariesForRuntime() {
return dynamicLibrariesForRuntime;
}
+ @Override
+ public SkylarkNestedSet getSkylarkDynamicLibrariesForRuntime() {
+ return SkylarkNestedSet.of(Artifact.class, dynamicLibrariesForRuntime);
+ }
+
/**
* The extra link time libraries; will be null if there are no such libraries.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsStore.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsStore.java
index ae2992c4ba..e4f6e183c8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsStore.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsStore.java
@@ -64,14 +64,14 @@ public final class CcLinkParamsStore extends AbstractCcLinkParamsStore {
@VisibleForSerialization
@AutoCodec.Instantiator
public CcLinkParamsStore(
- CcLinkParams staticSharedParams,
- CcLinkParams staticNoSharedParams,
- CcLinkParams noStaticSharedParams,
- CcLinkParams noStaticNoSharedParams) {
- super.staticSharedParams = staticSharedParams;
- super.staticNoSharedParams = staticNoSharedParams;
- super.noStaticSharedParams = noStaticSharedParams;
- super.noStaticNoSharedParams = noStaticNoSharedParams;
+ CcLinkParams staticModeParamsForDynamicLibrary,
+ CcLinkParams staticModeParamsForExecutable,
+ CcLinkParams dynamicModeParamsForDynamicLibrary,
+ CcLinkParams dynamicModeParamsForExecutable) {
+ super.staticModeParamsForDynamicLibrary = staticModeParamsForDynamicLibrary;
+ super.staticModeParamsForExecutable = staticModeParamsForExecutable;
+ super.dynamicModeParamsForDynamicLibrary = dynamicModeParamsForDynamicLibrary;
+ super.dynamicModeParamsForExecutable = dynamicModeParamsForExecutable;
}
public static com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore merge(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java
index 4f087f374a..dd792ccb75 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingInfo.java
@@ -29,6 +29,7 @@ import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.FunctionSignature;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkType;
+import java.util.Collection;
import javax.annotation.Nullable;
/** Wrapper for every C++ linking provider. */
@@ -46,10 +47,10 @@ public final class CcLinkingInfo extends NativeInfo implements CcLinkingInfoApi
/* numMandatoryNamedOnly= */ 0,
/* starArg= */ false,
/* kwArg= */ false,
- "static_shared_params",
- "static_no_shared_params",
- "no_static_shared_params",
- "no_static_no_shared_params",
+ "static_mode_params_for_dynamic_library",
+ "static_mode_params_for_executable",
+ "dynamic_mode_params_for_dynamic_library",
+ "dynamic_mode_params_for_executable",
"cc_runfiles"),
/* defaultValues= */ ImmutableList.of(
Runtime.NONE, Runtime.NONE, Runtime.NONE, Runtime.NONE, Runtime.NONE),
@@ -78,16 +79,16 @@ public final class CcLinkingInfo extends NativeInfo implements CcLinkingInfoApi
Object[] args, Environment env, Location loc) throws EvalException {
CcCommon.checkLocationWhitelisted(loc);
int i = 0;
- CcLinkParams staticSharedParams = (CcLinkParams) nullIfNone(args[i++]);
- CcLinkParams staticNoSharedParams = (CcLinkParams) nullIfNone(args[i++]);
- CcLinkParams noStaticSharedParams = (CcLinkParams) nullIfNone(args[i++]);
- CcLinkParams noStaticNoSharedParams = (CcLinkParams) nullIfNone(args[i++]);
+ CcLinkParams staticModeParamsForDynamicLibrary = (CcLinkParams) nullIfNone(args[i++]);
+ CcLinkParams staticModeParamsForExecutable = (CcLinkParams) nullIfNone(args[i++]);
+ CcLinkParams dynamicModeParamsForDynamicLibrary = (CcLinkParams) nullIfNone(args[i++]);
+ CcLinkParams dynamicModeParamsForExecutable = (CcLinkParams) nullIfNone(args[i++]);
CcRunfiles ccRunfiles = (CcRunfiles) nullIfNone(args[i++]);
CcLinkingInfo.Builder ccLinkingInfoBuilder = CcLinkingInfo.Builder.create();
- if (staticSharedParams != null) {
- if (staticNoSharedParams == null
- || noStaticSharedParams == null
- || noStaticNoSharedParams == null) {
+ if (staticModeParamsForDynamicLibrary != null) {
+ if (staticModeParamsForExecutable == null
+ || dynamicModeParamsForDynamicLibrary == null
+ || dynamicModeParamsForExecutable == null) {
throw new EvalException(
loc,
"Every CcLinkParams parameter must be passed to CcLinkingInfo "
@@ -95,10 +96,10 @@ public final class CcLinkingInfo extends NativeInfo implements CcLinkingInfoApi
}
ccLinkingInfoBuilder.setCcLinkParamsStore(
new CcLinkParamsStore(
- staticSharedParams,
- staticNoSharedParams,
- noStaticSharedParams,
- noStaticNoSharedParams));
+ staticModeParamsForDynamicLibrary,
+ staticModeParamsForExecutable,
+ dynamicModeParamsForDynamicLibrary,
+ dynamicModeParamsForExecutable));
}
// TODO(plf): The CcDynamicLibrariesForRuntime provider can be removed perhaps. Do not
// add to the API until we know for sure. The CcRunfiles provider is already in the API
@@ -133,6 +134,37 @@ public final class CcLinkingInfo extends NativeInfo implements CcLinkingInfoApi
}
@Override
+ public CcLinkParams getStaticModeParamsForDynamicLibrary() {
+ return ccLinkParamsStore.get(/* linkingStatically= */ true, /* linkShared= */ true);
+ }
+
+ @Override
+ public CcLinkParams getStaticModeParamsForExecutable() {
+ return ccLinkParamsStore.get(/* linkingStatically= */ true, /* linkShared= */ false);
+ }
+
+ @Override
+ public CcLinkParams getDynamicModeParamsForDynamicLibrary() {
+ return ccLinkParamsStore.get(/* linkingStatically= */ false, /* linkShared= */ true);
+ }
+
+ @Override
+ public CcLinkParams getDynamicModeParamsForExecutable() {
+ return ccLinkParamsStore.get(/* linkingStatically= */ false, /* linkShared= */ false);
+ }
+
+ public static CcLinkingInfo merge(Collection<CcLinkingInfo> ccLinkingInfos) {
+ CcLinkingInfo.Builder builder = new CcLinkingInfo.Builder();
+ builder.setCcLinkParamsStore(
+ CcLinkParamsStore.merge(
+ ccLinkingInfos
+ .stream()
+ .map(CcLinkingInfo::getCcLinkParamsStore)
+ .collect(ImmutableList.toImmutableList())));
+ return builder.build();
+ }
+
+ @Override
public CcRunfiles getCcRunfiles() {
return ccRunfiles;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index 55bcc8f5e7..d775a39793 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -35,6 +35,8 @@ import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcModuleApi;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcSkylarkInfoApi;
+import com.google.devtools.build.lib.skylarkinterface.Param;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.SkylarkDict;
@@ -294,4 +296,37 @@ public class CcModule
}
return new CcSkylarkInfo();
}
+
+ @SkylarkCallable(
+ name = "merge_cc_linking_infos",
+ documented = false,
+ parameters = {
+ @Param(
+ name = "cc_linking_infos",
+ doc = "cc_linking_infos to be merged.",
+ positional = false,
+ named = true,
+ defaultValue = "[]",
+ type = SkylarkList.class)
+ })
+ public CcLinkingInfo mergeCcLinkingInfos(SkylarkList<CcLinkingInfo> ccLinkingInfos) {
+ return CcLinkingInfo.merge(ccLinkingInfos);
+ }
+
+ @SkylarkCallable(
+ name = "merge_cc_compilation_infos",
+ documented = false,
+ parameters = {
+ @Param(
+ name = "cc_compilation_infos",
+ doc = "cc_compilation_infos to be merged.",
+ positional = false,
+ named = true,
+ defaultValue = "[]",
+ type = SkylarkList.class)
+ })
+ public CcCompilationInfo mergeCcCompilationInfos(
+ SkylarkList<CcCompilationInfo> ccCompilationInfos) {
+ return CcCompilationInfo.merge(ccCompilationInfos);
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcCompilationInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcCompilationInfoApi.java
index 127ebaade4..a95863989a 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcCompilationInfoApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcCompilationInfoApi.java
@@ -15,8 +15,10 @@
package com.google.devtools.build.lib.skylarkbuildapi.cpp;
import com.google.devtools.build.lib.skylarkbuildapi.StructApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
/** Interface for a wrapper of every C++ compilation provider. */
@SkylarkModule(
@@ -24,4 +26,25 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
documented = false,
category = SkylarkModuleCategory.PROVIDER,
doc = "Wrapper for every C++ compilation provider")
-public interface CcCompilationInfoApi extends StructApi {}
+public interface CcCompilationInfoApi extends StructApi {
+ @SkylarkCallable(
+ name = "defines",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ SkylarkNestedSet getSkylarkDefines();
+
+ @SkylarkCallable(
+ name = "headers",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ SkylarkNestedSet getSkylarkHeaders();
+
+ @SkylarkCallable(
+ name = "system_includes",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ SkylarkNestedSet getSkylarkDeclaredIncludeDirs();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkParamsApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkParamsApi.java
index 2759c14370..f732819929 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkParamsApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkParamsApi.java
@@ -14,8 +14,10 @@
package com.google.devtools.build.lib.skylarkbuildapi.cpp;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
/**
* Parameters that affect linking actions.
@@ -31,4 +33,25 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
documented = false,
category = SkylarkModuleCategory.BUILTIN,
doc = "Parameters that affect linking actions.")
-public interface CcLinkParamsApi {}
+public interface CcLinkParamsApi {
+ @SkylarkCallable(
+ name = "linkopts",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ SkylarkNestedSet getSkylarkLinkopts();
+
+ @SkylarkCallable(
+ name = "libraries_to_link",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ SkylarkNestedSet getSkylarkLibrariesToLink();
+
+ @SkylarkCallable(
+ name = "dynamic_libraries_for_runtime",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ SkylarkNestedSet getSkylarkDynamicLibrariesForRuntime();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java
index 12bc9368d0..590d00503e 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingInfoApi.java
@@ -36,4 +36,32 @@ public interface CcLinkingInfoApi extends StructApi {
allowReturnNones = true,
structField = true)
public CcRunfilesApi getCcRunfiles();
+
+ @SkylarkCallable(
+ name = "static_mode_params_for_dynamic_library",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ CcLinkParamsApi getStaticModeParamsForDynamicLibrary();
+
+ @SkylarkCallable(
+ name = "static_mode_params_for_executable",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ CcLinkParamsApi getStaticModeParamsForExecutable();
+
+ @SkylarkCallable(
+ name = "dynamic_mode_params_for_dynamic_library",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ CcLinkParamsApi getDynamicModeParamsForDynamicLibrary();
+
+ @SkylarkCallable(
+ name = "dynamic_mode_params_for_executable",
+ documented = false,
+ allowReturnNones = true,
+ structField = true)
+ CcLinkParamsApi getDynamicModeParamsForExecutable();
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
index 798892554c..86d914f073 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
@@ -30,7 +30,9 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfig
import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.testutil.TestConstants;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -903,27 +905,53 @@ public class SkylarkCcCommonTest extends BuildViewTestCase {
" srcs = ['lib.cc'],",
" deps = ['r']",
")",
+ "cc_library(",
+ " name = 'dep1',",
+ " srcs = ['dep1.cc'],",
+ " hdrs = ['dep1.h'],",
+ " includes = ['dep1/baz'],",
+ " defines = ['DEP1'],",
+ ")",
+ "cc_library(",
+ " name = 'dep2',",
+ " srcs = ['dep2.cc'],",
+ " hdrs = ['dep2.h'],",
+ " includes = ['dep2/qux'],",
+ " defines = ['DEP2'],",
+ ")",
"crule(name='r')");
scratch.file("tools/build_defs/cc/BUILD", "");
scratch.file(
"tools/build_defs/cc/rule.bzl",
"def _impl(ctx):",
- " cc_compilation_info = CcCompilationInfo(headers=depset([ctx.file._header]))",
- " return [",
- " cc_compilation_info, cc_common.create_cc_skylark_info(ctx=ctx),",
- " ]",
+ " cc_compilation_info = CcCompilationInfo(headers=depset([ctx.file._header]),",
+ " system_includes=depset([ctx.attr._include]), defines=depset([ctx.attr._define]))",
+ " cc_compilation_infos = [cc_compilation_info]",
+ " for dep in ctx.attr._deps:",
+ " cc_compilation_infos.append(dep[CcCompilationInfo])",
+ " merged_cc_compilation_info=cc_common.merge_cc_compilation_infos(",
+ " cc_compilation_infos=cc_compilation_infos)",
+ " return struct(",
+ " providers=[cc_compilation_info, cc_common.create_cc_skylark_info(ctx=ctx)],",
+ " merged_headers=merged_cc_compilation_info.headers,",
+ " merged_system_includes=merged_cc_compilation_info.system_includes,",
+ " merged_defines=merged_cc_compilation_info.defines",
+ " )",
"crule = rule(",
" _impl,",
" attrs = { ",
- " '_header': attr.label(allow_single_file=True, default=Label('//a:header.h'))",
+ " '_header': attr.label(allow_single_file=True, default=Label('//a:header.h')),",
+ " '_include': attr.string(default='foo/bar'),",
+ " '_define': attr.string(default='MYDEFINE'),",
+ " '_deps': attr.label_list(default=['//a:dep1', '//a:dep2'])",
" },",
" fragments = ['cpp'],",
");");
- ConfiguredTarget r = getConfiguredTarget("//a:lib");
+ ConfiguredTarget lib = getConfiguredTarget("//a:lib");
@SuppressWarnings("unchecked")
CcCompilationContext ccCompilationContext =
- r.get(CcCompilationInfo.PROVIDER).getCcCompilationContext();
+ lib.get(CcCompilationInfo.PROVIDER).getCcCompilationContext();
assertThat(
ccCompilationContext
.getDeclaredIncludeSrcs()
@@ -932,6 +960,25 @@ public class SkylarkCcCommonTest extends BuildViewTestCase {
.map(Artifact::getFilename)
.collect(ImmutableList.toImmutableList()))
.containsExactly("lib.h", "header.h");
+
+ ConfiguredTarget r = getConfiguredTarget("//a:r");
+
+ List<Artifact> mergedHeaders =
+ ((SkylarkNestedSet) r.get("merged_headers")).getSet(Artifact.class).toList();
+ assertThat(
+ mergedHeaders
+ .stream()
+ .map(Artifact::getFilename)
+ .collect(ImmutableList.toImmutableList()))
+ .containsAllOf("header.h", "dep1.h", "dep2.h");
+
+ List<String> mergedDefines =
+ ((SkylarkNestedSet) r.get("merged_defines")).getSet(String.class).toList();
+ assertThat(mergedDefines).containsAllOf("MYDEFINE", "DEP1", "DEP2");
+
+ List<String> mergedIncludes =
+ ((SkylarkNestedSet) r.get("merged_system_includes")).getSet(String.class).toList();
+ assertThat(mergedIncludes).containsAllOf("foo/bar", "a/dep1/baz", "a/dep2/qux");
}
@Test
@@ -1031,37 +1078,118 @@ public class SkylarkCcCommonTest extends BuildViewTestCase {
}
@Test
- public void testCcLinkingProviderParamsWithFlag() throws Exception {
+ public void testCcLinkingProvider() throws Exception {
+ AnalysisMock.get()
+ .ccSupport()
+ .setupCrosstool(
+ mockToolsConfig,
+ "supports_interface_shared_objects: false");
+ useConfiguration("--experimental_enable_cc_skylark_api");
setUpCcLinkingProviderParamsTest();
ConfiguredTarget r = getConfiguredTarget("//a:r");
- @SuppressWarnings("unchecked")
- CcLinkParamsStore ccLinkParamsStore =
- ((CcLinkingInfo) r.get("cc_linking_info")).getCcLinkParamsStore();
- assertThat(ccLinkParamsStore).isNotNull();
+
+ List<String> staticSharedLinkopts =
+ ((SkylarkNestedSet) r.get("sd_linkopts")).getSet(String.class).toList();
+ List<String> staticNoSharedLinkopts =
+ ((SkylarkNestedSet) r.get("se_linkopts")).getSet(String.class).toList();
+ List<String> noStaticSharedLinkopts =
+ ((SkylarkNestedSet) r.get("dd_linkopts")).getSet(String.class).toList();
+ List<String> noStaticNoSharedLinkopts =
+ ((SkylarkNestedSet) r.get("de_linkopts")).getSet(String.class).toList();
+ assertThat(staticSharedLinkopts)
+ .containsAllOf("-static_for_dynamic", "-DEP1_LINKOPT", "-DEP2_LINKOPT");
+ assertThat(staticNoSharedLinkopts)
+ .containsAllOf("-static_for_executable", "-DEP1_LINKOPT", "-DEP2_LINKOPT");
+ assertThat(noStaticSharedLinkopts)
+ .containsAllOf("-dynamic_for_dynamic", "-DEP1_LINKOPT", "-DEP2_LINKOPT");
+ assertThat(noStaticNoSharedLinkopts)
+ .containsAllOf("-dynamic_for_executable", "-DEP1_LINKOPT", "-DEP2_LINKOPT");
+
+ List<LibraryToLink> staticSharedLibs =
+ ((SkylarkNestedSet) r.get("sd_libs")).getSet(LibraryToLink.class).toList();
+ List<LibraryToLink> staticNoSharedLibs =
+ ((SkylarkNestedSet) r.get("se_libs")).getSet(LibraryToLink.class).toList();
+ List<LibraryToLink> noStaticSharedLibs =
+ ((SkylarkNestedSet) r.get("dd_libs")).getSet(LibraryToLink.class).toList();
+ List<LibraryToLink> noStaticNoSharedLibs =
+ ((SkylarkNestedSet) r.get("de_libs")).getSet(LibraryToLink.class).toList();
assertThat(
- ccLinkParamsStore
- .get(/* linkingStatically= */ true, /* linkShared= */ true)
- .flattenedLinkopts())
- .containsExactly("-static_shared");
+ staticSharedLibs
+ .stream()
+ .map(x -> x.getOriginalLibraryArtifact().getFilename())
+ .collect(ImmutableList.toImmutableList()))
+ .containsAllOf("lib.a", "libdep1.a", "libdep2.a");
assertThat(
- ccLinkParamsStore
- .get(/* linkingStatically= */ true, /* linkShared= */ false)
- .flattenedLinkopts())
- .containsExactly("-static_no_shared");
+ staticNoSharedLibs
+ .stream()
+ .map(x -> x.getOriginalLibraryArtifact().getFilename())
+ .collect(ImmutableList.toImmutableList()))
+ .containsAllOf("lib.a", "libdep1.a", "libdep2.a");
+
assertThat(
- ccLinkParamsStore
- .get(/* linkingStatically= */ false, /* linkShared= */ true)
- .flattenedLinkopts())
- .containsExactly("-no_static_shared");
+ noStaticSharedLibs
+ .stream()
+ .map(x -> x.getOriginalLibraryArtifact().getFilename())
+ .collect(ImmutableList.toImmutableList()))
+ .containsAllOf("lib.so", "libdep1.so", "libdep2.so");
+ assertThat(
+ noStaticNoSharedLibs
+ .stream()
+ .map(x -> x.getOriginalLibraryArtifact().getFilename())
+ .collect(ImmutableList.toImmutableList()))
+ .containsAllOf("lib.so", "libdep1.so", "libdep2.so");
+
+ List<Artifact> staticSharedRunLibs =
+ ((SkylarkNestedSet) r.get("sd_runlibs")).getSet(Artifact.class).toList();
+ List<Artifact> staticNoSharedRunLibs =
+ ((SkylarkNestedSet) r.get("se_runlibs")).getSet(Artifact.class).toList();
+ List<Artifact> noStaticSharedRunLibs =
+ ((SkylarkNestedSet) r.get("dd_runlibs")).getSet(Artifact.class).toList();
+ List<Artifact> noStaticNoSharedRunLibs =
+ ((SkylarkNestedSet) r.get("de_runlibs")).getSet(Artifact.class).toList();
+ assertThat(
+ staticSharedRunLibs
+ .stream()
+ .map(Artifact::getFilename)
+ .collect(ImmutableList.toImmutableList()))
+ .isEmpty();
+ assertThat(
+ staticNoSharedRunLibs
+ .stream()
+ .map(Artifact::getFilename)
+ .collect(ImmutableList.toImmutableList()))
+ .isEmpty();
+ assertThat(
+ noStaticSharedRunLibs
+ .stream()
+ .map(Artifact::getFilename)
+ .collect(ImmutableList.toImmutableList()))
+ .containsAllOf("lib.so", "liba_Slibdep1.so", "liba_Slibdep2.so");
assertThat(
- ccLinkParamsStore
- .get(/* linkingStatically= */ false, /* linkShared= */ false)
- .flattenedLinkopts())
- .containsExactly("-no_static_no_shared");
+ noStaticNoSharedRunLibs
+ .stream()
+ .map(Artifact::getFilename)
+ .collect(ImmutableList.toImmutableList()))
+ .containsAllOf("lib.so", "liba_Slibdep1.so", "liba_Slibdep2.so");
}
private void setUpCcLinkingProviderParamsTest() throws Exception {
- scratch.file("a/BUILD", "load('//tools/build_defs/cc:rule.bzl', 'crule')", "crule(name='r')");
+ scratch.file(
+ "a/BUILD",
+ "load('//tools/build_defs/cc:rule.bzl', 'crule')",
+ "crule(name='r')",
+ "cc_library(",
+ " name = 'dep1',",
+ " srcs = ['dep1.cc'],",
+ " hdrs = ['dep1.h'],",
+ " linkopts = ['-DEP1_LINKOPT'],",
+ ")",
+ "cc_library(",
+ " name = 'dep2',",
+ " srcs = ['dep2.cc'],",
+ " hdrs = ['dep2.h'],",
+ " linkopts = ['-DEP2_LINKOPT'],",
+ ")");
scratch.file("a/lib.a", "");
scratch.file("a/lib.so", "");
scratch.file("tools/build_defs/cc/BUILD", "");
@@ -1074,21 +1202,45 @@ public class SkylarkCcCommonTest extends BuildViewTestCase {
"def _impl(ctx):",
" liba = cc_common.create_library_to_link(ctx=ctx, library=ctx.file.liba,",
" artifact_category='static_library')",
- " ss = _create(ctx, [liba], [ctx.file.libso], ['-static_shared'])",
- " sns = _create(ctx, [liba], [ctx.file.libso], ['-static_no_shared'])",
- " nss = _create(ctx, [liba], [ctx.file.libso], ['-no_static_shared'])",
- " nsns = _create(ctx, [liba], [ctx.file.libso], ['-no_static_no_shared'])",
+ " libso = cc_common.create_library_to_link(ctx=ctx, library=ctx.file.libso,",
+ " artifact_category='dynamic_library')",
+ " sd = _create(ctx, [liba], [], ['-static_for_dynamic'])",
+ " se = _create(ctx, [liba], [], ['-static_for_executable'])",
+ " dd = _create(ctx, [libso], [ctx.file.libso], ['-dynamic_for_dynamic'])",
+ " de = _create(ctx, [libso], [ctx.file.libso], ['-dynamic_for_executable'])",
" cc_linking_info = CcLinkingInfo(",
- " static_shared_params=ss, static_no_shared_params=sns,",
- " no_static_shared_params=nss, no_static_no_shared_params=nsns)",
+ " static_mode_params_for_dynamic_library=sd, static_mode_params_for_executable=se,",
+ " dynamic_mode_params_for_dynamic_library=dd, dynamic_mode_params_for_executable=de)",
+ " cc_linking_infos = [cc_linking_info]",
+ " for dep in ctx.attr._deps:",
+ " cc_linking_infos.append(dep[CcLinkingInfo])",
+ " merged_cc_linking_info = cc_common.merge_cc_linking_infos(",
+ " cc_linking_infos=cc_linking_infos)",
+ " sd = merged_cc_linking_info.static_mode_params_for_dynamic_library",
+ " se = merged_cc_linking_info.static_mode_params_for_executable",
+ " dd = merged_cc_linking_info.dynamic_mode_params_for_dynamic_library",
+ " de = merged_cc_linking_info.dynamic_mode_params_for_executable",
" return struct(",
" cc_linking_info = cc_linking_info,",
+ " sd_linkopts = sd.linkopts,",
+ " se_linkopts = se.linkopts,",
+ " dd_linkopts = dd.linkopts,",
+ " de_linkopts = de.linkopts,",
+ " sd_libs = sd.libraries_to_link,",
+ " se_libs = se.libraries_to_link,",
+ " dd_libs = dd.libraries_to_link,",
+ " de_libs = de.libraries_to_link,",
+ " sd_runlibs = sd.dynamic_libraries_for_runtime,",
+ " se_runlibs = se.dynamic_libraries_for_runtime,",
+ " dd_runlibs = dd.dynamic_libraries_for_runtime,",
+ " de_runlibs = de.dynamic_libraries_for_runtime,",
" )",
"crule = rule(",
" _impl,",
" attrs = { ",
" 'liba': attr.label(default='//a:lib.a', allow_single_file=True),",
" 'libso': attr.label(default='//a:lib.so', allow_single_file=True),",
+ " '_deps': attr.label_list(default=['//a:dep1', '//a:dep2']),",
" },",
" fragments = ['cpp'],",
");");