Skip to content

Commit

Permalink
Rewrite ObjcCommon in Starlark
Browse files Browse the repository at this point in the history
RELNOTES:none
PiperOrigin-RevId: 385983265
  • Loading branch information
oquenchil authored and copybara-github committed Jul 21, 2021
1 parent 00bd291 commit 4a0cc3b
Show file tree
Hide file tree
Showing 13 changed files with 409 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.rules.apple.XcodeConfigInfo;
import com.google.devtools.build.lib.rules.apple.XcodeVersionProperties;
import com.google.devtools.build.lib.rules.cpp.CcModule;
import com.google.devtools.build.lib.rules.cpp.CppSemantics;
import com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag;
import com.google.devtools.build.lib.starlarkbuildapi.SplitTransitionProviderApi;
import com.google.devtools.build.lib.starlarkbuildapi.apple.AppleCommonApi;
import java.util.Map;
Expand Down Expand Up @@ -193,12 +195,34 @@ public ObjcProvider newObjcProvider(Dict<String, Object> kwargs, StarlarkThread
ObjcProvider.Key<?> key = ObjcProvider.getStarlarkKeyForString(entry.getKey());
if (key != null) {
resultBuilder.addElementsFromStarlark(key, entry.getValue());
} else if (entry.getKey().equals("strict_include")) {
resultBuilder.addStrictIncludeFromStarlark(entry.getValue());
} else if (entry.getKey().equals("providers")) {
resultBuilder.addProvidersFromStarlark(entry.getValue());
} else {
throw Starlark.errorf(BAD_KEY_ERROR, entry.getKey());
switch (entry.getKey()) {
case "cc_library":
CcModule.checkPrivateStarlarkificationAllowlist(thread);
resultBuilder.uncheckedAddTransitive(
ObjcProvider.CC_LIBRARY,
ObjcProviderStarlarkConverters.convertToJava(
ObjcProvider.CC_LIBRARY, entry.getValue()));
break;
case "linkstamp":
CcModule.checkPrivateStarlarkificationAllowlist(thread);
resultBuilder.uncheckedAddTransitive(
ObjcProvider.LINKSTAMP,
ObjcProviderStarlarkConverters.convertToJava(
ObjcProvider.LINKSTAMP, entry.getValue()));
break;
case "flag":
resultBuilder.add(ObjcProvider.FLAG, Flag.USES_CPP);
break;
case "strict_include":
resultBuilder.addStrictIncludeFromStarlark(entry.getValue());
break;
case "providers":
resultBuilder.addProvidersFromStarlark(entry.getValue());
break;
default:
throw Starlark.errorf(BAD_KEY_ERROR, entry.getKey());
}
}
}
return resultBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.google.devtools.build.lib.rules.cpp.CppHelper;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.StarlarkList;
Expand Down Expand Up @@ -351,6 +352,11 @@ public Depset hdrsForStarlark() {
return Depset.of(Artifact.TYPE, hdrs());
}

@StarlarkMethod(name = "textual_hdrs", documented = false, structField = true)
public Depset textualHdrsForStarlark() {
return Depset.of(Artifact.TYPE, textualHdrs());
}

/**
* Returns the headers that cannot be compiled individually.
*/
Expand All @@ -376,6 +382,17 @@ public Depset includesForStarlark() {
.collect(ImmutableList.toImmutableList())));
}

@StarlarkMethod(name = "sdk_includes", documented = false, structField = true)
public Depset sdkIncludesForStarlark() {
return Depset.of(
ElementType.STRING,
NestedSetBuilder.wrap(
Order.COMPILE_ORDER,
sdkIncludes().toList().stream()
.map(PathFragment::getSafePathString)
.collect(ImmutableList.toImmutableList())));
}

/**
* Returns the paths for SDK includes.
*/
Expand All @@ -390,27 +407,56 @@ public NestedSet<SdkFramework> sdkFrameworks() {
return this.sdkFrameworks;
}

@StarlarkMethod(name = "sdk_framework", documented = false, structField = true)
public Depset sdkFramework() {
@StarlarkMethod(name = "sdk_frameworks", documented = false, structField = true)
public Depset sdkFrameworksForStarlark() {
return (Depset)
ObjcProviderStarlarkConverters.convertToStarlark(
ObjcProvider.SDK_FRAMEWORK, sdkFrameworks());
}

@StarlarkMethod(name = "weak_sdk_frameworks", documented = false, structField = true)
public Depset weakSdkFrameworksForStarlark() {
return (Depset)
ObjcProviderStarlarkConverters.convertToStarlark(
ObjcProvider.SDK_FRAMEWORK, weakSdkFrameworks());
}

/**
* Returns the SDK frameworks to be linked weakly.
*/
public NestedSet<SdkFramework> weakSdkFrameworks() {
return this.weakSdkFrameworks;
}

@StarlarkMethod(name = "sdk_dylibs", documented = false, structField = true)
public Depset sdkDylibsForStarlark() {
return Depset.of(ElementType.STRING, sdkDylibs);
}

/**
* Returns the SDK Dylibs to link against.
*/
public NestedSet<String> sdkDylibs() {
return this.sdkDylibs;
}

@StarlarkMethod(
name = "header_search_paths",
documented = false,
parameters = {
@Param(name = "genfiles_dir", positional = false, named = true),
})
public Depset headerSearchPathsForStarlark(String genfilesDir) {
return Depset.of(
ElementType.STRING,
NestedSetBuilder.stableOrder()
.addAll(
headerSearchPaths(PathFragment.create(genfilesDir)).toList().stream()
.map(PathFragment::toString)
.collect(ImmutableList.toImmutableList()))
.build());
}

/**
* Returns the exec paths of all header search paths that should be added to this target and
* dependers on this target, obtained from the {@code includes} attribute.
Expand Down Expand Up @@ -454,6 +500,11 @@ public ImmutableList<Artifact> linkInputs() {
return this.linkInputs;
}

@StarlarkMethod(name = "defines", documented = false, structField = true)
public Sequence<String> getDefinesForStarlark() {
return StarlarkList.immutableCopyOf(defines());
}

/** Returns the defines. */
public ImmutableList<String> defines() {
return this.defines;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.eval.StarlarkValue;
Expand Down Expand Up @@ -512,23 +511,6 @@ public Optional<Artifact> getCompiledArchive() {
return Optional.absent();
}

/**
* Returns the compiled {@code .a} file, or null if this object contains no {@link
* CompilationArtifacts} or the compilation information has no sources.
*/
@StarlarkMethod(
name = "compiled_archive",
documented = false,
structField = true,
allowReturnNones = true)
@Nullable
public Artifact getCompiledArchiveForStarlark() {
if (compilationArtifacts.isPresent() && compilationArtifacts.get().getArchive().isPresent()) {
return compilationArtifacts.get().getArchive().get();
}
return null;
}

/**
* Returns effective compilation options that do not arise from the crosstool.
*/
Expand Down Expand Up @@ -569,27 +551,6 @@ static Optional<PathFragment> nearestContainerMatching(
return Optional.absent();
}

/**
* Similar to {@link #nearestContainerMatching(FileType, Artifact)}, but returns the container
* closest to the root that matches the given type.
*/
static Optional<PathFragment> farthestContainerMatching(FileType type, Artifact artifact) {
PathFragment container = artifact.getExecPath();
Optional<PathFragment> lastMatch = Optional.absent();
do {
if (type.matches(container)) {
lastMatch = Optional.of(container);
}
container = container.getParentDirectory();
} while (container != null);
return lastMatch;
}

static Iterable<String> notInContainerErrors(
Iterable<Artifact> artifacts, FileType containerType) {
return notInContainerErrors(artifacts, ImmutableList.of(containerType));
}

static Iterable<String> notInContainerErrors(
Iterable<Artifact> artifacts, Iterable<FileType> containerTypes) {
Set<String> errors = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,11 @@ public Depset weakSdkFramework() {
@VisibleForTesting
static final ImmutableList<Key<?>> KEYS_NOT_IN_STARLARK =
ImmutableList.<Key<?>>of(
// LibraryToLink not exposed to Starlark.
CC_LIBRARY,
// Flag enum is not exposed to Starlark.
FLAG,
// Linkstamp is not exposed to Starlark. See commentary at its definition.
// cc_library is handled specially.
CC_LIBRARY,
// linkstamp is handled specially.
LINKSTAMP,
// Strict include is handled specially.
STRICT_INCLUDE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.cpp.CcLinkingContext.Linkstamp;
import com.google.devtools.build.lib.rules.cpp.LibraryToLink;
import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
import com.google.devtools.build.lib.vfs.PathFragment;
import net.starlark.java.eval.EvalException;
Expand Down Expand Up @@ -49,6 +51,11 @@ public static Object convertToStarlark(Key<?> javaKey, NestedSet<?> javaValue) {
/** Returns a value for a java ObjcProvider given a key and a corresponding Starlark value. */
public static NestedSet<?> convertToJava(Key<?> javaKey, Object starlarkValue)
throws EvalException {
if (javaKey.getType().equals(LibraryToLink.class)) {
return Depset.noneableCast(starlarkValue, LibraryToLink.class, "cc_library");
} else if (javaKey.getType().equals(Linkstamp.class)) {
return Depset.noneableCast(starlarkValue, Linkstamp.class, "linkstamp");
}
return CONVERTERS.get(javaKey.getType()).valueForJava(javaKey, starlarkValue);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,7 @@ public Metadata getMetadata() {
}
}

/**
* Iff a file matches this type, it is considered to use C++.
*/
/** Iff a file matches this type, it is considered to use C++. */
static final FileType CPP_SOURCES = FileType.of(".cc", ".cpp", ".mm", ".cxx", ".C");

static final FileType NON_CPP_SOURCES = FileType.of(".m", ".c");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

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

import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.docgen.annot.DocCategory;
Expand All @@ -25,9 +27,11 @@
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.cpp.CcCompilationContext;
import com.google.devtools.build.lib.rules.cpp.CppSemantics;
import com.google.devtools.build.lib.shell.ShellUtils;
import com.google.devtools.build.lib.shell.ShellUtils.TokenizationException;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -76,10 +80,11 @@ public CompilationAttributes createCompilationAttributes(StarlarkRuleContext sta
builder, starlarkRuleContext.getRuleContext());
CompilationAttributes.Builder.addSdkAttributesFromRuleContext(
builder, starlarkRuleContext.getRuleContext());
List<String> copts =
Sequence<String> copts =
expandToolchainAndRuleContextVariables(
starlarkRuleContext,
starlarkRuleContext.getRuleContext().attributes().get("copts", Type.STRING_LIST));
StarlarkList.immutableCopyOf(
starlarkRuleContext.getRuleContext().attributes().get("copts", Type.STRING_LIST)));
CompilationAttributes.Builder.addCompileOptionsFromRuleContext(
builder, starlarkRuleContext.getRuleContext(), copts);
CompilationAttributes.Builder.addModuleOptionsFromRuleContext(
Expand All @@ -88,8 +93,15 @@ public CompilationAttributes createCompilationAttributes(StarlarkRuleContext sta
return builder.build();
}

private List<String> expandToolchainAndRuleContextVariables(
StarlarkRuleContext starlarkRuleContext, Iterable<String> flags) throws EvalException {
@StarlarkMethod(
name = "expand_toolchain_and_ctx_variables",
documented = false,
parameters = {
@Param(name = "ctx", positional = false, named = true),
@Param(name = "flags", positional = false, defaultValue = "[]", named = true),
})
public Sequence<String> expandToolchainAndRuleContextVariables(
StarlarkRuleContext starlarkRuleContext, Sequence<?> flags) throws EvalException {
ImmutableMap<String, String> toolchainMap =
starlarkRuleContext
.getRuleContext()
Expand All @@ -98,15 +110,15 @@ private List<String> expandToolchainAndRuleContextVariables(
ImmutableMap<String, String> starlarkRuleContextMap =
ImmutableMap.<String, String>builder().putAll(starlarkRuleContext.var()).build();
List<String> expandedFlags = new ArrayList<>();
for (String flag : flags) {
for (String flag : Sequence.cast(flags, String.class, "flags")) {
String expandedFlag = expandFlag(flag, toolchainMap, starlarkRuleContextMap);
try {
ShellUtils.tokenize(expandedFlags, expandedFlag);
} catch (TokenizationException e) {
throw new EvalException(e);
}
}
return expandedFlags;
return StarlarkList.immutableCopyOf(expandedFlags);
}

private String expandFlag(
Expand Down Expand Up @@ -280,4 +292,55 @@ public InstrumentedFilesInfo createInstrumentedFilesInfo(
starlarkRuleContext.getRuleContext(),
Sequence.cast(objectFiles, Artifact.class, "object_files").getImmutableList());
}

@StarlarkMethod(
name = "create_compilation_context",
documented = false,
parameters = {
@Param(name = "public_hdrs", positional = false, defaultValue = "[]", named = true),
@Param(name = "public_textual_hdrs", positional = false, defaultValue = "[]", named = true),
@Param(name = "private_hdrs", positional = false, defaultValue = "[]", named = true),
@Param(name = "providers", positional = false, defaultValue = "[]", named = true),
@Param(
name = "direct_cc_compilation_contexts",
positional = false,
defaultValue = "[]",
named = true),
@Param(
name = "cc_compilation_contexts",
positional = false,
defaultValue = "[]",
named = true),
@Param(name = "defines", positional = false, defaultValue = "[]", named = true),
@Param(name = "includes", positional = false, defaultValue = "[]", named = true),
})
public ObjcCompilationContext createCompilationContext(
Sequence<?> publicHdrs,
Sequence<?> publicTextualHdrs,
Sequence<?> privateHdrs,
Sequence<?> providers,
Sequence<?> directCcCompilationContexts,
Sequence<?> ccCompilationContexts,
Sequence<?> defines,
Sequence<?> includes)
throws InterruptedException, EvalException {
return ObjcCompilationContext.builder()
.addPublicHeaders(Sequence.cast(publicHdrs, Artifact.class, "public_hdrs"))
.addPublicTextualHeaders(
Sequence.cast(publicTextualHdrs, Artifact.class, "public_textual_hdrs"))
.addPrivateHeaders(Sequence.cast(privateHdrs, Artifact.class, "private_hdrs"))
.addObjcProviders(Sequence.cast(providers, ObjcProvider.class, "providers"))
.addDirectCcCompilationContexts(
Sequence.cast(
directCcCompilationContexts, CcCompilationContext.class, "cc_compilation_contexts"))
.addCcCompilationContexts(
Sequence.cast(
ccCompilationContexts, CcCompilationContext.class, "cc_compilation_contexts"))
.addDefines(Sequence.cast(defines, String.class, "defines"))
.addIncludes(
Sequence.cast(includes, String.class, "includes").stream()
.map(PathFragment::create)
.collect(toImmutableList()))
.build();
}
}
Loading

0 comments on commit 4a0cc3b

Please sign in to comment.