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
15package 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
21import (
22	"github.com/google/blueprint"
23
24	"android/soong/common"
25)
26
27func init() {
28	pctx.SourcePathVariable("lexCmd", "prebuilts/misc/${HostPrebuiltTag}/flex/flex-2.5.39")
29	pctx.SourcePathVariable("yaccCmd", "prebuilts/misc/${HostPrebuiltTag}/bison/bison")
30	pctx.SourcePathVariable("yaccDataDir", "external/bison/data")
31}
32
33var (
34	yacc = pctx.StaticRule("yacc",
35		blueprint.RuleParams{
36			Command:     "BISON_PKGDATADIR=$yaccDataDir $yaccCmd -d $yaccFlags --defines=$hFile -o $cFile $in",
37			CommandDeps: []string{"$yaccCmd"},
38			Description: "yacc $out",
39		},
40		"yaccFlags", "cFile", "hFile")
41
42	lex = pctx.StaticRule("lex",
43		blueprint.RuleParams{
44			Command:     "$lexCmd -o$out $in",
45			CommandDeps: []string{"$lexCmd"},
46			Description: "lex $out",
47		})
48)
49
50func genYacc(ctx common.AndroidModuleContext, yaccFile common.Path, outFile common.ModuleGenPath, yaccFlags string) (headerFile common.ModuleGenPath) {
51	headerFile = common.GenPathWithExt(ctx, yaccFile, "h")
52
53	ctx.ModuleBuild(pctx, common.ModuleBuildParams{
54		Rule:    yacc,
55		Outputs: common.WritablePaths{outFile, headerFile},
56		Input:   yaccFile,
57		Args: map[string]string{
58			"yaccFlags": yaccFlags,
59			"cFile":     outFile.String(),
60			"hFile":     headerFile.String(),
61		},
62	})
63
64	return headerFile
65}
66
67func genLex(ctx common.AndroidModuleContext, lexFile common.Path, outFile common.ModuleGenPath) {
68	ctx.ModuleBuild(pctx, common.ModuleBuildParams{
69		Rule:   lex,
70		Output: outFile,
71		Input:  lexFile,
72	})
73}
74
75func genSources(ctx common.AndroidModuleContext, srcFiles common.Paths,
76	buildFlags builderFlags) (common.Paths, common.Paths) {
77
78	var deps common.Paths
79
80	for i, srcFile := range srcFiles {
81		switch srcFile.Ext() {
82		case ".y":
83			cFile := common.GenPathWithExt(ctx, srcFile, "c")
84			srcFiles[i] = cFile
85			deps = append(deps, genYacc(ctx, srcFile, cFile, buildFlags.yaccFlags))
86		case ".yy":
87			cppFile := common.GenPathWithExt(ctx, srcFile, "cpp")
88			srcFiles[i] = cppFile
89			deps = append(deps, genYacc(ctx, srcFile, cppFile, buildFlags.yaccFlags))
90		case ".l":
91			cFile := common.GenPathWithExt(ctx, srcFile, "c")
92			srcFiles[i] = cFile
93			genLex(ctx, srcFile, cFile)
94		case ".ll":
95			cppFile := common.GenPathWithExt(ctx, srcFile, "cpp")
96			srcFiles[i] = cppFile
97			genLex(ctx, srcFile, cppFile)
98		}
99	}
100
101	return srcFiles, deps
102}
103