Home | History | Annotate | Download | only in cc
      1 // Copyright 2016 Google Inc. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package cc
     16 
     17 import (
     18 	"strings"
     19 
     20 	"github.com/google/blueprint"
     21 	"github.com/google/blueprint/pathtools"
     22 	"github.com/google/blueprint/proptools"
     23 
     24 	"android/soong/android"
     25 )
     26 
     27 func init() {
     28 	pctx.HostBinToolVariable("protocCmd", "aprotoc")
     29 }
     30 
     31 var (
     32 	proto = pctx.AndroidStaticRule("protoc",
     33 		blueprint.RuleParams{
     34 			Command:     "$protocCmd --cpp_out=$protoOutParams:$outDir -I $protoBase $protoFlags $in",
     35 			CommandDeps: []string{"$protocCmd"},
     36 		}, "protoFlags", "protoOutParams", "protoBase", "outDir")
     37 )
     38 
     39 // genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns
     40 // the paths to the generated files.
     41 func genProto(ctx android.ModuleContext, protoFile android.Path,
     42 	protoFlags, protoOutParams string, root bool) (ccFile, headerFile android.WritablePath) {
     43 
     44 	var protoBase string
     45 	if root {
     46 		protoBase = "."
     47 		ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.cc")
     48 		headerFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.h")
     49 	} else {
     50 		rel := protoFile.Rel()
     51 		protoBase = strings.TrimSuffix(protoFile.String(), rel)
     52 		ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.cc"))
     53 		headerFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.h"))
     54 	}
     55 
     56 	ctx.Build(pctx, android.BuildParams{
     57 		Rule:        proto,
     58 		Description: "protoc " + protoFile.Rel(),
     59 		Outputs:     android.WritablePaths{ccFile, headerFile},
     60 		Input:       protoFile,
     61 		Args: map[string]string{
     62 			"outDir":         android.ProtoDir(ctx).String(),
     63 			"protoFlags":     protoFlags,
     64 			"protoOutParams": protoOutParams,
     65 			"protoBase":      protoBase,
     66 		},
     67 	})
     68 
     69 	return ccFile, headerFile
     70 }
     71 
     72 func protoDeps(ctx BaseModuleContext, deps Deps, p *android.ProtoProperties, static bool) Deps {
     73 	var lib string
     74 
     75 	switch String(p.Proto.Type) {
     76 	case "full":
     77 		if ctx.useSdk() {
     78 			lib = "libprotobuf-cpp-full-ndk"
     79 			static = true
     80 		} else {
     81 			lib = "libprotobuf-cpp-full"
     82 		}
     83 	case "lite", "":
     84 		if ctx.useSdk() {
     85 			lib = "libprotobuf-cpp-lite-ndk"
     86 			static = true
     87 		} else {
     88 			lib = "libprotobuf-cpp-lite"
     89 		}
     90 	default:
     91 		ctx.PropertyErrorf("proto.type", "unknown proto type %q",
     92 			String(p.Proto.Type))
     93 	}
     94 
     95 	if static {
     96 		deps.StaticLibs = append(deps.StaticLibs, lib)
     97 		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, lib)
     98 	} else {
     99 		deps.SharedLibs = append(deps.SharedLibs, lib)
    100 		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, lib)
    101 	}
    102 
    103 	return deps
    104 }
    105 
    106 func protoFlags(ctx ModuleContext, flags Flags, p *android.ProtoProperties) Flags {
    107 	flags.CFlags = append(flags.CFlags, "-DGOOGLE_PROTOBUF_NO_RTTI")
    108 
    109 	flags.ProtoRoot = android.ProtoCanonicalPathFromRoot(ctx, p)
    110 	if flags.ProtoRoot {
    111 		flags.GlobalFlags = append(flags.GlobalFlags, "-I"+android.ProtoSubDir(ctx).String())
    112 	}
    113 	flags.GlobalFlags = append(flags.GlobalFlags, "-I"+android.ProtoDir(ctx).String())
    114 
    115 	flags.protoFlags = android.ProtoFlags(ctx, p)
    116 
    117 	if proptools.String(p.Proto.Type) == "lite" {
    118 		flags.protoOutParams = append(flags.protoOutParams, "lite")
    119 	}
    120 
    121 	return flags
    122 }
    123