Search in sources :

Example 41 with BuildRule

use of com.facebook.buck.rules.BuildRule in project buck by facebook.

the class OcamlBuildRulesGenerator method generateSingleMLNativeCompilation.

/**
   * Compiles a single .ml file to a .cmx
   */
private void generateSingleMLNativeCompilation(Map<Path, ImmutableSortedSet<BuildRule>> sourceToRule, ImmutableList.Builder<SourcePath> cmxFiles, Path mlSource, ImmutableMap<Path, ImmutableList<Path>> sources, ImmutableList<Path> cycleDetector) {
    ImmutableList<Path> newCycleDetector = ImmutableList.<Path>builder().addAll(cycleDetector).add(mlSource).build();
    if (cycleDetector.contains(mlSource)) {
        throw new HumanReadableException("Dependency cycle detected: %s", Joiner.on(" -> ").join(newCycleDetector));
    }
    if (sourceToRule.containsKey(mlSource)) {
        return;
    }
    ImmutableSortedSet.Builder<BuildRule> depsBuilder = ImmutableSortedSet.naturalOrder();
    if (sources.containsKey(mlSource)) {
        for (Path dep : checkNotNull(sources.get(mlSource))) {
            generateSingleMLNativeCompilation(sourceToRule, cmxFiles, dep, sources, newCycleDetector);
            depsBuilder.addAll(checkNotNull(sourceToRule.get(dep)));
        }
    }
    ImmutableSortedSet<BuildRule> deps = depsBuilder.build();
    String name = mlSource.toFile().getName();
    BuildTarget buildTarget = createMLNativeCompileBuildTarget(params.getBuildTarget(), name);
    BuildRuleParams compileParams = params.withBuildTarget(buildTarget).copyReplacingDeclaredAndExtraDeps(Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>naturalOrder().addAll(params.getDeclaredDeps().get()).add(this.cleanRule).addAll(deps).addAll(ocamlContext.getNativeCompileDeps()).addAll(cCompiler.getDeps(ruleFinder)).build()), params.getExtraDeps());
    String outputFileName = getMLNativeOutputName(name);
    Path outputPath = ocamlContext.getCompileNativeOutputDir().resolve(outputFileName);
    final ImmutableList<Arg> compileFlags = getCompileFlags(/* isBytecode */
    false, /* excludeDeps */
    false);
    OcamlMLCompile compile = new OcamlMLCompile(compileParams, new OcamlMLCompileStep.Args(params.getProjectFilesystem()::resolve, cCompiler.getEnvironment(pathResolver), cCompiler.getCommandPrefix(pathResolver), ocamlContext.getOcamlCompiler().get(), ocamlContext.getOcamlInteropIncludesDir(), outputPath, mlSource, compileFlags));
    resolver.addToIndex(compile);
    sourceToRule.put(mlSource, ImmutableSortedSet.<BuildRule>naturalOrder().add(compile).addAll(deps).build());
    if (!outputFileName.endsWith(OcamlCompilables.OCAML_CMI)) {
        cmxFiles.add(compile.getSourcePathToOutput());
    }
}
Also used : SourcePath(com.facebook.buck.rules.SourcePath) Path(java.nio.file.Path) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams) HumanReadableException(com.facebook.buck.util.HumanReadableException) BuildTarget(com.facebook.buck.model.BuildTarget) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) StringArg(com.facebook.buck.rules.args.StringArg) Arg(com.facebook.buck.rules.args.Arg) BuildRule(com.facebook.buck.rules.BuildRule)

Example 42 with BuildRule

use of com.facebook.buck.rules.BuildRule in project buck by facebook.

the class OcamlBuildRulesGenerator method generateBytecodeLinking.

/**
   * Links the .cmo files generated by the bytecode compilation
   */
private BuildRule generateBytecodeLinking(ImmutableList<SourcePath> allInputs) {
    BuildRuleParams linkParams = params.withBuildTarget(addBytecodeFlavor(params.getBuildTarget())).copyReplacingDeclaredAndExtraDeps(Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>naturalOrder().addAll(ruleFinder.filterBuildRuleInputs(allInputs)).addAll(ocamlContext.getBytecodeLinkDeps()).addAll(Stream.concat(ocamlContext.getBytecodeLinkableInput().getArgs().stream(), ocamlContext.getCLinkableInput().getArgs().stream()).flatMap(arg -> arg.getDeps(ruleFinder).stream()).filter(rule -> !(rule instanceof OcamlBuild)).iterator()).addAll(cxxCompiler.getDeps(ruleFinder)).build()), Suppliers.ofInstance(ImmutableSortedSet.of()));
    ImmutableList.Builder<Arg> flags = ImmutableList.builder();
    flags.addAll(ocamlContext.getFlags());
    flags.addAll(StringArg.from(ocamlContext.getCommonCLinkerFlags()));
    OcamlLink link = new OcamlLink(linkParams, allInputs, cxxCompiler.getEnvironment(pathResolver), cxxCompiler.getCommandPrefix(pathResolver), ocamlContext.getOcamlBytecodeCompiler().get(), flags.build(), ocamlContext.getOcamlInteropIncludesDir(), ocamlContext.getBytecodeOutput(), ocamlContext.getNativePluginOutput(), ocamlContext.getBytecodeLinkableInput().getArgs(), ocamlContext.getCLinkableInput().getArgs(), ocamlContext.isLibrary(), /* isBytecode */
    true, /* buildNativePlugin */
    false);
    resolver.addToIndex(link);
    return link;
}
Also used : Iterables(com.google.common.collect.Iterables) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePath(com.facebook.buck.rules.SourcePath) InternalFlavor(com.facebook.buck.model.InternalFlavor) BuildRule(com.facebook.buck.rules.BuildRule) Compiler(com.facebook.buck.cxx.Compiler) ImmutableList(com.google.common.collect.ImmutableList) Files(com.google.common.io.Files) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) StringArg(com.facebook.buck.rules.args.StringArg) Map(java.util.Map) Suppliers(com.google.common.base.Suppliers) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams) Path(java.nio.file.Path) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) ImmutableMap(com.google.common.collect.ImmutableMap) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) HumanReadableException(com.facebook.buck.util.HumanReadableException) BuildTarget(com.facebook.buck.model.BuildTarget) Maps(com.google.common.collect.Maps) Arg(com.facebook.buck.rules.args.Arg) Stream(java.util.stream.Stream) CxxPreprocessorInput(com.facebook.buck.cxx.CxxPreprocessorInput) Preconditions(com.google.common.base.Preconditions) Flavor(com.facebook.buck.model.Flavor) BuildRuleResolver(com.facebook.buck.rules.BuildRuleResolver) Joiner(com.google.common.base.Joiner) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams) ImmutableList(com.google.common.collect.ImmutableList) StringArg(com.facebook.buck.rules.args.StringArg) Arg(com.facebook.buck.rules.args.Arg)

Example 43 with BuildRule

use of com.facebook.buck.rules.BuildRule in project buck by facebook.

the class RuleKeyBuilder method setReflectively.

/** Recursively serializes the value. Serialization of the key is handled outside. */
protected RuleKeyBuilder<RULE_KEY> setReflectively(@Nullable Object val) {
    if (val instanceof RuleKeyAppendable) {
        return setAppendableRuleKey((RuleKeyAppendable) val);
    }
    if (val instanceof BuildRule) {
        return setBuildRule((BuildRule) val);
    }
    if (val instanceof Supplier) {
        try (Scope containerScope = scopedHasher.wrapperScope(Wrapper.SUPPLIER)) {
            Object newVal = ((Supplier<?>) val).get();
            return setReflectively(newVal);
        }
    }
    if (val instanceof Optional) {
        Object o = ((Optional<?>) val).orElse(null);
        try (Scope wraperScope = scopedHasher.wrapperScope(Wrapper.OPTIONAL)) {
            return setReflectively(o);
        }
    }
    if (val instanceof Either) {
        Either<?, ?> either = (Either<?, ?>) val;
        if (either.isLeft()) {
            try (Scope wraperScope = scopedHasher.wrapperScope(Wrapper.EITHER_LEFT)) {
                return setReflectively(either.getLeft());
            }
        } else {
            try (Scope wraperScope = scopedHasher.wrapperScope(Wrapper.EITHER_RIGHT)) {
                return setReflectively(either.getRight());
            }
        }
    }
    // Note {@link java.nio.file.Path} implements "Iterable", so we explicitly exclude it here.
    if (val instanceof Iterable && !(val instanceof Path)) {
        try (ContainerScope containerScope = scopedHasher.containerScope(Container.LIST)) {
            for (Object element : (Iterable<?>) val) {
                try (Scope elementScope = containerScope.elementScope()) {
                    setReflectively(element);
                }
            }
            return this;
        }
    }
    if (val instanceof Iterator) {
        Iterator<?> iterator = (Iterator<?>) val;
        try (ContainerScope containerScope = scopedHasher.containerScope(Container.LIST)) {
            while (iterator.hasNext()) {
                try (Scope elementScope = containerScope.elementScope()) {
                    setReflectively(iterator.next());
                }
            }
        }
        return this;
    }
    if (val instanceof Map) {
        if (!(val instanceof SortedMap || val instanceof ImmutableMap)) {
            logger.warn("Adding an unsorted map to the rule key. " + "Expect unstable ordering and caches misses: %s", val);
        }
        try (ContainerScope containerScope = scopedHasher.containerScope(Container.MAP)) {
            for (Map.Entry<?, ?> entry : ((Map<?, ?>) val).entrySet()) {
                try (Scope elementScope = containerScope.elementScope()) {
                    setReflectively(entry.getKey());
                }
                try (Scope elementScope = containerScope.elementScope()) {
                    setReflectively(entry.getValue());
                }
            }
        }
        return this;
    }
    if (val instanceof Path) {
        throw new HumanReadableException("It's not possible to reliably disambiguate Paths. They are disallowed from rule keys");
    }
    if (val instanceof SourcePath) {
        try {
            return setSourcePath((SourcePath) val);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    if (val instanceof NonHashableSourcePathContainer) {
        SourcePath sourcePath = ((NonHashableSourcePathContainer) val).getSourcePath();
        return setNonHashingSourcePath(sourcePath);
    }
    if (val instanceof SourceWithFlags) {
        SourceWithFlags source = (SourceWithFlags) val;
        try {
            setSourcePath(source.getSourcePath());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        setReflectively(source.getFlags());
        return this;
    }
    return setSingleValue(val);
}
Also used : SourcePath(com.facebook.buck.rules.SourcePath) ArchiveMemberSourcePath(com.facebook.buck.rules.ArchiveMemberSourcePath) ArchiveMemberPath(com.facebook.buck.io.ArchiveMemberPath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) Path(java.nio.file.Path) PathSourcePath(com.facebook.buck.rules.PathSourcePath) Optional(java.util.Optional) ContainerScope(com.facebook.buck.rules.keys.RuleKeyScopedHasher.ContainerScope) NonHashableSourcePathContainer(com.facebook.buck.rules.NonHashableSourcePathContainer) IOException(java.io.IOException) SourceWithFlags(com.facebook.buck.rules.SourceWithFlags) ImmutableMap(com.google.common.collect.ImmutableMap) SourcePath(com.facebook.buck.rules.SourcePath) ArchiveMemberSourcePath(com.facebook.buck.rules.ArchiveMemberSourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) Scope(com.facebook.buck.rules.keys.RuleKeyScopedHasher.Scope) ContainerScope(com.facebook.buck.rules.keys.RuleKeyScopedHasher.ContainerScope) HumanReadableException(com.facebook.buck.util.HumanReadableException) SortedMap(java.util.SortedMap) Iterator(java.util.Iterator) Either(com.facebook.buck.model.Either) BuildRule(com.facebook.buck.rules.BuildRule) Supplier(com.google.common.base.Supplier) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) RuleKeyAppendable(com.facebook.buck.rules.RuleKeyAppendable)

Example 44 with BuildRule

use of com.facebook.buck.rules.BuildRule in project buck by facebook.

the class MacroArg method getInputs.

@Override
public ImmutableCollection<SourcePath> getInputs() {
    ImmutableCollection<BuildRule> rules;
    try {
        rules = expander.extractBuildTimeDeps(target, cellNames, resolver, unexpanded);
    } catch (MacroException e) {
        throw new HumanReadableException(e, "%s: %s", target, e.getMessage());
    }
    ImmutableList.Builder<SourcePath> paths = ImmutableList.builder();
    for (BuildRule rule : rules) {
        paths.add(Preconditions.checkNotNull(rule.getSourcePathToOutput()));
    }
    return paths.build();
}
Also used : SourcePath(com.facebook.buck.rules.SourcePath) HumanReadableException(com.facebook.buck.util.HumanReadableException) ImmutableList(com.google.common.collect.ImmutableList) BuildRule(com.facebook.buck.rules.BuildRule) MacroException(com.facebook.buck.model.MacroException)

Example 45 with BuildRule

use of com.facebook.buck.rules.BuildRule in project buck by facebook.

the class NdkLibraryDescription method generateMakefile.

/**
   * @return a {@link BuildRule} which generates a Android.mk which pulls in the local Android.mk
   *     file and also appends relevant preprocessor and linker flags to use C/C++ library deps.
   */
private Pair<String, Iterable<BuildRule>> generateMakefile(BuildRuleParams params, BuildRuleResolver resolver) throws NoSuchBuildTargetException {
    SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
    SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
    ImmutableList.Builder<String> outputLinesBuilder = ImmutableList.builder();
    ImmutableSortedSet.Builder<BuildRule> deps = ImmutableSortedSet.naturalOrder();
    for (Map.Entry<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> entry : cxxPlatforms.entrySet()) {
        CxxPlatform cxxPlatform = entry.getValue().getCxxPlatform();
        // Collect the preprocessor input for all C/C++ library deps.  We search *through* other
        // NDK library rules.
        CxxPreprocessorInput cxxPreprocessorInput = CxxPreprocessorInput.concat(CxxPreprocessables.getTransitiveCxxPreprocessorInput(cxxPlatform, params.getDeps(), NdkLibrary.class::isInstance));
        // We add any dependencies from the C/C++ preprocessor input to this rule, even though
        // it technically should be added to the top-level rule.
        deps.addAll(cxxPreprocessorInput.getDeps(resolver, ruleFinder));
        // Add in the transitive preprocessor flags contributed by C/C++ library rules into the
        // NDK build.
        ImmutableList.Builder<String> ppFlags = ImmutableList.builder();
        ppFlags.addAll(cxxPreprocessorInput.getPreprocessorFlags().get(CxxSource.Type.C));
        Preprocessor preprocessor = CxxSourceTypes.getPreprocessor(cxxPlatform, CxxSource.Type.C).resolve(resolver);
        ppFlags.addAll(CxxHeaders.getArgs(cxxPreprocessorInput.getIncludes(), pathResolver, Optional.empty(), preprocessor));
        String localCflags = Joiner.on(' ').join(escapeForMakefile(params.getProjectFilesystem(), ppFlags.build()));
        // Collect the native linkable input for all C/C++ library deps.  We search *through* other
        // NDK library rules.
        NativeLinkableInput nativeLinkableInput = NativeLinkables.getTransitiveNativeLinkableInput(cxxPlatform, params.getDeps(), Linker.LinkableDepType.SHARED, NdkLibrary.class::isInstance);
        // We add any dependencies from the native linkable input to this rule, even though
        // it technically should be added to the top-level rule.
        deps.addAll(nativeLinkableInput.getArgs().stream().flatMap(arg -> arg.getDeps(ruleFinder).stream()).iterator());
        // Add in the transitive native linkable flags contributed by C/C++ library rules into the
        // NDK build.
        String localLdflags = Joiner.on(' ').join(escapeForMakefile(params.getProjectFilesystem(), com.facebook.buck.rules.args.Arg.stringify(nativeLinkableInput.getArgs(), pathResolver)));
        // Write the relevant lines to the generated makefile.
        if (!localCflags.isEmpty() || !localLdflags.isEmpty()) {
            NdkCxxPlatforms.TargetCpuType targetCpuType = entry.getKey();
            String targetArchAbi = getTargetArchAbi(targetCpuType);
            outputLinesBuilder.add(String.format("ifeq ($(TARGET_ARCH_ABI),%s)", targetArchAbi));
            if (!localCflags.isEmpty()) {
                outputLinesBuilder.add("BUCK_DEP_CFLAGS=" + localCflags);
            }
            if (!localLdflags.isEmpty()) {
                outputLinesBuilder.add("BUCK_DEP_LDFLAGS=" + localLdflags);
            }
            outputLinesBuilder.add("endif");
            outputLinesBuilder.add("");
        }
    }
    // GCC-only magic that rewrites non-deterministic parts of builds
    String ndksubst = NdkCxxPlatforms.ANDROID_NDK_ROOT;
    outputLinesBuilder.addAll(ImmutableList.copyOf(new String[] { // We're evaluated once per architecture, but want to add the cflags only once.
    "ifeq ($(BUCK_ALREADY_HOOKED_CFLAGS),)", "BUCK_ALREADY_HOOKED_CFLAGS := 1", // Only GCC supports -fdebug-prefix-map
    "ifeq ($(filter clang%,$(NDK_TOOLCHAIN_VERSION)),)", // Replace absolute paths with machine-relative ones.
    "NDK_APP_CFLAGS += -fdebug-prefix-map=$(NDK_ROOT)/=" + ndksubst + "/", "NDK_APP_CFLAGS += -fdebug-prefix-map=$(abspath $(BUCK_PROJECT_DIR))/=./", // repository root.
    "NDK_APP_CFLAGS += -fdebug-prefix-map=$(BUCK_PROJECT_DIR)/=./", "NDK_APP_CFLAGS += -fdebug-prefix-map=./=" + ".$(subst $(abspath $(BUCK_PROJECT_DIR)),,$(abspath $(CURDIR)))/", "NDK_APP_CFLAGS += -fno-record-gcc-switches", "ifeq ($(filter 4.6,$(TOOLCHAIN_VERSION)),)", // headers either.
    "NDK_APP_CPPFLAGS += -fno-canonical-system-headers", // detailed command line argument information anyway.
    "NDK_APP_CFLAGS += -gno-record-gcc-switches", // !GCC 4.6
    "endif", // !clang
    "endif", // absolute path, but only for modules under the project root.
    "BUCK_SAVED_IMPORTS := $(__ndk_import_dirs)", "__ndk_import_dirs :=", "$(foreach __dir,$(BUCK_SAVED_IMPORTS),\\", "$(call import-add-path-optional,\\", "$(if $(filter $(abspath $(BUCK_PROJECT_DIR))%,$(__dir)),\\", "$(BUCK_PROJECT_DIR)$(patsubst $(abspath $(BUCK_PROJECT_DIR))%,%,$(__dir)),\\", "$(__dir))))", // !already hooked
    "endif", // generic paths.
    "NDK_APP_CFLAGS += -fdebug-prefix-map=$(TOOLCHAIN_PREBUILT_ROOT)/=" + "@ANDROID_NDK_ROOT@/toolchains/$(TOOLCHAIN_NAME)/prebuilt/@BUILD_HOST@/" }));
    outputLinesBuilder.add("include Android.mk");
    String contents = Joiner.on(System.lineSeparator()).join(outputLinesBuilder.build());
    return new Pair<String, Iterable<BuildRule>>(contents, deps.build());
}
Also used : CxxPlatform(com.facebook.buck.cxx.CxxPlatform) ImmutableList(com.google.common.collect.ImmutableList) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) NativeLinkableInput(com.facebook.buck.cxx.NativeLinkableInput) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) BuildRule(com.facebook.buck.rules.BuildRule) CxxPreprocessorInput(com.facebook.buck.cxx.CxxPreprocessorInput) Preprocessor(com.facebook.buck.cxx.Preprocessor) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) Pair(com.facebook.buck.model.Pair)

Aggregations

BuildRule (com.facebook.buck.rules.BuildRule)361 BuildTarget (com.facebook.buck.model.BuildTarget)199 SourcePathRuleFinder (com.facebook.buck.rules.SourcePathRuleFinder)190 BuildRuleResolver (com.facebook.buck.rules.BuildRuleResolver)189 Test (org.junit.Test)175 SourcePathResolver (com.facebook.buck.rules.SourcePathResolver)165 DefaultTargetNodeToBuildRuleTransformer (com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer)162 SourcePath (com.facebook.buck.rules.SourcePath)118 Path (java.nio.file.Path)95 BuildRuleParams (com.facebook.buck.rules.BuildRuleParams)70 FakeProjectFilesystem (com.facebook.buck.testutil.FakeProjectFilesystem)70 FakeBuildRule (com.facebook.buck.rules.FakeBuildRule)66 TargetGraph (com.facebook.buck.rules.TargetGraph)63 ProjectFilesystem (com.facebook.buck.io.ProjectFilesystem)61 FakeSourcePath (com.facebook.buck.rules.FakeSourcePath)61 ImmutableList (com.google.common.collect.ImmutableList)58 PathSourcePath (com.facebook.buck.rules.PathSourcePath)51 ImmutableSet (com.google.common.collect.ImmutableSet)45 ImmutableMap (com.google.common.collect.ImmutableMap)44 RuleKey (com.facebook.buck.rules.RuleKey)43