Home | History | Annotate | Download | only in cc
      1 // Copyright 2015 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 // This file generates the final rules for compiling all C/C++.  All properties related to
     18 // compiling should have been translated into builderFlags or another argument to the Transform*
     19 // functions.
     20 
     21 import (
     22 	"github.com/google/blueprint"
     23 
     24 	"android/soong/android"
     25 )
     26 
     27 func init() {
     28 	pctx.SourcePathVariable("lexCmd", "prebuilts/misc/${config.HostPrebuiltTag}/flex/flex-2.5.39")
     29 	pctx.SourcePathVariable("yaccCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/bison")
     30 	pctx.SourcePathVariable("yaccDataDir", "prebuilts/build-tools/common/bison")
     31 
     32 	pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
     33 }
     34 
     35 var (
     36 	yacc = pctx.AndroidStaticRule("yacc",
     37 		blueprint.RuleParams{
     38 			Command:     "BISON_PKGDATADIR=$yaccDataDir $yaccCmd -d $yaccFlags --defines=$hFile -o $out $in",
     39 			CommandDeps: []string{"$yaccCmd"},
     40 		},
     41 		"yaccFlags", "hFile")
     42 
     43 	lex = pctx.AndroidStaticRule("lex",
     44 		blueprint.RuleParams{
     45 			Command:     "$lexCmd -o$out $in",
     46 			CommandDeps: []string{"$lexCmd"},
     47 		})
     48 
     49 	aidl = pctx.AndroidStaticRule("aidl",
     50 		blueprint.RuleParams{
     51 			Command:     "$aidlCmd -d${out}.d -ninja $aidlFlags $in $outDir $out",
     52 			CommandDeps: []string{"$aidlCmd"},
     53 			Depfile:     "${out}.d",
     54 			Deps:        blueprint.DepsGCC,
     55 		},
     56 		"aidlFlags", "outDir")
     57 
     58 	windmc = pctx.AndroidStaticRule("windmc",
     59 		blueprint.RuleParams{
     60 			Command:     "$windmcCmd -r$$(dirname $out) -h$$(dirname $out) $in",
     61 			CommandDeps: []string{"$windmcCmd"},
     62 		},
     63 		"windmcCmd")
     64 )
     65 
     66 func genYacc(ctx android.ModuleContext, yaccFile android.Path, outFile android.ModuleGenPath, yaccFlags string) (headerFile android.ModuleGenPath) {
     67 	headerFile = android.GenPathWithExt(ctx, "yacc", yaccFile, "h")
     68 
     69 	ctx.Build(pctx, android.BuildParams{
     70 		Rule:           yacc,
     71 		Description:    "yacc " + yaccFile.Rel(),
     72 		Output:         outFile,
     73 		ImplicitOutput: headerFile,
     74 		Input:          yaccFile,
     75 		Args: map[string]string{
     76 			"yaccFlags": yaccFlags,
     77 			"hFile":     headerFile.String(),
     78 		},
     79 	})
     80 
     81 	return headerFile
     82 }
     83 
     84 func genAidl(ctx android.ModuleContext, aidlFile android.Path, outFile android.ModuleGenPath, aidlFlags string) android.Paths {
     85 
     86 	ctx.Build(pctx, android.BuildParams{
     87 		Rule:        aidl,
     88 		Description: "aidl " + aidlFile.Rel(),
     89 		Output:      outFile,
     90 		Input:       aidlFile,
     91 		Args: map[string]string{
     92 			"aidlFlags": aidlFlags,
     93 			"outDir":    android.PathForModuleGen(ctx, "aidl").String(),
     94 		},
     95 	})
     96 
     97 	// TODO: This should return the generated headers, not the source file.
     98 	return android.Paths{outFile}
     99 }
    100 
    101 func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.ModuleGenPath) {
    102 	ctx.Build(pctx, android.BuildParams{
    103 		Rule:        lex,
    104 		Description: "lex " + lexFile.Rel(),
    105 		Output:      outFile,
    106 		Input:       lexFile,
    107 	})
    108 }
    109 
    110 func genWinMsg(ctx android.ModuleContext, srcFile android.Path, flags builderFlags) (android.Path, android.Path) {
    111 	headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h")
    112 	rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc")
    113 
    114 	windmcCmd := gccCmd(flags.toolchain, "windmc")
    115 
    116 	ctx.Build(pctx, android.BuildParams{
    117 		Rule:           windmc,
    118 		Description:    "windmc " + srcFile.Rel(),
    119 		Output:         rcFile,
    120 		ImplicitOutput: headerFile,
    121 		Input:          srcFile,
    122 		Args: map[string]string{
    123 			"windmcCmd": windmcCmd,
    124 		},
    125 	})
    126 
    127 	return rcFile, headerFile
    128 }
    129 
    130 func genSources(ctx android.ModuleContext, srcFiles android.Paths,
    131 	buildFlags builderFlags) (android.Paths, android.Paths) {
    132 
    133 	var deps android.Paths
    134 
    135 	var rsFiles android.Paths
    136 
    137 	for i, srcFile := range srcFiles {
    138 		switch srcFile.Ext() {
    139 		case ".y":
    140 			cFile := android.GenPathWithExt(ctx, "yacc", srcFile, "c")
    141 			srcFiles[i] = cFile
    142 			deps = append(deps, genYacc(ctx, srcFile, cFile, buildFlags.yaccFlags))
    143 		case ".yy":
    144 			cppFile := android.GenPathWithExt(ctx, "yacc", srcFile, "cpp")
    145 			srcFiles[i] = cppFile
    146 			deps = append(deps, genYacc(ctx, srcFile, cppFile, buildFlags.yaccFlags))
    147 		case ".l":
    148 			cFile := android.GenPathWithExt(ctx, "lex", srcFile, "c")
    149 			srcFiles[i] = cFile
    150 			genLex(ctx, srcFile, cFile)
    151 		case ".ll":
    152 			cppFile := android.GenPathWithExt(ctx, "lex", srcFile, "cpp")
    153 			srcFiles[i] = cppFile
    154 			genLex(ctx, srcFile, cppFile)
    155 		case ".proto":
    156 			ccFile, headerFile := genProto(ctx, srcFile, buildFlags.protoFlags,
    157 				buildFlags.protoOutParams, buildFlags.protoRoot)
    158 			srcFiles[i] = ccFile
    159 			deps = append(deps, headerFile)
    160 		case ".aidl":
    161 			cppFile := android.GenPathWithExt(ctx, "aidl", srcFile, "cpp")
    162 			srcFiles[i] = cppFile
    163 			deps = append(deps, genAidl(ctx, srcFile, cppFile, buildFlags.aidlFlags)...)
    164 		case ".rs", ".fs":
    165 			cppFile := rsGeneratedCppFile(ctx, srcFile)
    166 			rsFiles = append(rsFiles, srcFiles[i])
    167 			srcFiles[i] = cppFile
    168 		case ".mc":
    169 			rcFile, headerFile := genWinMsg(ctx, srcFile, buildFlags)
    170 			srcFiles[i] = rcFile
    171 			deps = append(deps, headerFile)
    172 		}
    173 	}
    174 
    175 	if len(rsFiles) > 0 {
    176 		deps = append(deps, rsGenerateCpp(ctx, rsFiles, buildFlags.rsFlags)...)
    177 	}
    178 
    179 	return srcFiles, deps
    180 }
    181