diff options
author | plf <plf@google.com> | 2018-07-16 01:11:04 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-07-16 01:12:34 -0700 |
commit | e14a7d4f156c28244a491c65083273f57734cdbe (patch) | |
tree | 63bae469d108c3d89d80c29013358dd0830f3f6e | |
parent | a567777889fd0abc6c31818054ed18eaa918e1fe (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
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'],", ");"); |