com.facebook.buck.go.GoCompile.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.go.GoCompile.java

Source

/*
 * Copyright 2016-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.facebook.buck.go;

import com.facebook.buck.io.MorePaths;
import com.facebook.buck.model.BuildTargets;
import com.facebook.buck.rules.AbstractBuildRuleWithResolver;
import com.facebook.buck.rules.AddToRuleKey;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildableContext;
import com.facebook.buck.rules.BuildableProperties;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SymlinkTree;
import com.facebook.buck.rules.Tool;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.fs.MakeCleanDirectoryStep;
import com.facebook.buck.step.fs.MkdirStep;
import com.facebook.buck.step.fs.SymlinkFileStep;
import com.facebook.buck.step.fs.TouchStep;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

import java.nio.file.Path;
import java.util.Optional;

public class GoCompile extends AbstractBuildRuleWithResolver {
    @AddToRuleKey
    private final Tool compiler;
    @AddToRuleKey
    private final Tool assembler;
    @AddToRuleKey
    private final Tool packer;
    @AddToRuleKey(stringify = true)
    private final Path packageName;
    @AddToRuleKey
    private final ImmutableSet<SourcePath> srcs;
    @AddToRuleKey
    private final ImmutableList<String> compilerFlags;
    @AddToRuleKey
    private final ImmutableList<String> assemblerFlags;
    @AddToRuleKey
    private final GoPlatform platform;
    // TODO(mikekap): Make these part of the rule key.
    private final ImmutableList<Path> assemblerIncludeDirs;
    private final ImmutableMap<Path, Path> importPathMap;

    private final SymlinkTree symlinkTree;
    private final Path output;

    public GoCompile(BuildRuleParams params, SourcePathResolver resolver, SymlinkTree symlinkTree, Path packageName,
            ImmutableMap<Path, Path> importPathMap, ImmutableSet<SourcePath> srcs,
            ImmutableList<String> compilerFlags, Tool compiler, ImmutableList<String> assemblerFlags,
            ImmutableList<Path> assemblerIncludeDirs, Tool assembler, Tool packer, GoPlatform platform) {
        super(params, resolver);
        this.importPathMap = importPathMap;
        this.srcs = srcs;
        this.symlinkTree = symlinkTree;
        this.packageName = packageName;
        this.compilerFlags = compilerFlags;
        this.compiler = compiler;
        this.assemblerFlags = assemblerFlags;
        this.assemblerIncludeDirs = assemblerIncludeDirs;
        this.assembler = assembler;
        this.packer = packer;
        this.platform = platform;
        this.output = BuildTargets.getGenPath(getProjectFilesystem(), getBuildTarget(),
                "%s/" + getBuildTarget().getShortName() + ".a");
    }

    @Override
    public ImmutableList<Step> getBuildSteps(BuildContext context, BuildableContext buildableContext) {

        buildableContext.recordArtifact(output);

        ImmutableList.Builder<Path> compileSrcListBuilder = ImmutableList.builder();
        ImmutableList.Builder<Path> headerSrcListBuilder = ImmutableList.builder();
        ImmutableList.Builder<Path> asmSrcListBuilder = ImmutableList.builder();
        for (SourcePath path : srcs) {
            Path srcPath = getResolver().getAbsolutePath(path);
            String extension = MorePaths.getFileExtension(srcPath).toLowerCase();
            if (extension.equals("s")) {
                asmSrcListBuilder.add(srcPath);
            } else if (extension.equals("go")) {
                compileSrcListBuilder.add(srcPath);
            } else {
                headerSrcListBuilder.add(srcPath);
            }
        }

        ImmutableList<Path> compileSrcs = compileSrcListBuilder.build();
        ImmutableList<Path> headerSrcs = headerSrcListBuilder.build();
        ImmutableList<Path> asmSrcs = asmSrcListBuilder.build();

        ImmutableList.Builder<Step> steps = ImmutableList.builder();
        steps.add(new MkdirStep(getProjectFilesystem(), output.getParent()));

        Optional<Path> asmHeaderPath;

        if (!asmSrcs.isEmpty()) {
            asmHeaderPath = Optional.of(BuildTargets.getScratchPath(getProjectFilesystem(), getBuildTarget(),
                    "%s/" + getBuildTarget().getShortName() + "__asm_hdr").resolve("go_asm.h"));

            steps.add(new MkdirStep(getProjectFilesystem(), asmHeaderPath.get().getParent()));
        } else {
            asmHeaderPath = Optional.empty();
        }

        boolean allowExternalReferences = !asmSrcs.isEmpty();

        if (compileSrcs.isEmpty()) {
            steps.add(new TouchStep(getProjectFilesystem(), output));
        } else {
            steps.add(new GoCompileStep(getProjectFilesystem().getRootPath(), compiler.getEnvironment(),
                    compiler.getCommandPrefix(getResolver()), compilerFlags, packageName, compileSrcs,
                    importPathMap, ImmutableList.of(symlinkTree.getRoot()), asmHeaderPath, allowExternalReferences,
                    platform, output));
        }

        if (!asmSrcs.isEmpty()) {
            Path asmIncludeDir = BuildTargets.getScratchPath(getProjectFilesystem(), getBuildTarget(),
                    "%s/" + getBuildTarget().getShortName() + "__asm_includes");
            steps.add(new MakeCleanDirectoryStep(getProjectFilesystem(), asmIncludeDir));

            if (!headerSrcs.isEmpty()) {
                // TODO(mikekap): Allow header-map style input.
                for (Path header : FluentIterable.from(headerSrcs).append(asmSrcs)) {
                    steps.add(new SymlinkFileStep(getProjectFilesystem(), header,
                            asmIncludeDir.resolve(header.getFileName()), /* useAbsolutePaths */ true));
                }
            }

            Path asmOutputDir = BuildTargets.getScratchPath(getProjectFilesystem(), getBuildTarget(),
                    "%s/" + getBuildTarget().getShortName() + "__asm_compile");
            steps.add(new MakeCleanDirectoryStep(getProjectFilesystem(), asmOutputDir));

            ImmutableList.Builder<Path> asmOutputs = ImmutableList.builder();
            for (Path asmSrc : asmSrcs) {
                Path outputPath = asmOutputDir
                        .resolve(asmSrc.getFileName().toString().replaceAll("\\.[sS]$", ".o"));
                steps.add(new GoAssembleStep(getProjectFilesystem().getRootPath(), assembler.getEnvironment(),
                        assembler.getCommandPrefix(getResolver()), assemblerFlags, asmSrc,
                        ImmutableList.<Path>builder().addAll(assemblerIncludeDirs)
                                .add(asmHeaderPath.get().getParent()).add(asmIncludeDir).build(),
                        platform, outputPath));
                asmOutputs.add(outputPath);
            }

            steps.add(new GoPackStep(getProjectFilesystem().getRootPath(), packer.getEnvironment(),
                    packer.getCommandPrefix(getResolver()), GoPackStep.Operation.APPEND, asmOutputs.build(),
                    output));
        }

        return steps.build();
    }

    @Override
    public Path getPathToOutput() {
        return output;
    }

    @Override
    public BuildableProperties getProperties() {
        return new BuildableProperties(BuildableProperties.Kind.LIBRARY);
    }
}