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 17import ( 18 "fmt" 19 "path/filepath" 20 "regexp" 21 "strings" 22 23 "android/soong/android" 24) 25 26// Efficiently converts a list of include directories to a single string 27// of cflags with -I prepended to each directory. 28func includeDirsToFlags(dirs android.Paths) string { 29 return android.JoinWithPrefix(dirs.Strings(), "-I") 30} 31 32func ldDirsToFlags(dirs []string) string { 33 return android.JoinWithPrefix(dirs, "-L") 34} 35 36func libNamesToFlags(names []string) string { 37 return android.JoinWithPrefix(names, "-l") 38} 39 40var indexList = android.IndexList 41var inList = android.InList 42var filterList = android.FilterList 43var removeListFromList = android.RemoveListFromList 44var removeFromList = android.RemoveFromList 45 46var libNameRegexp = regexp.MustCompile(`^lib(.*)$`) 47 48func moduleToLibName(module string) (string, error) { 49 matches := libNameRegexp.FindStringSubmatch(module) 50 if matches == nil { 51 return "", fmt.Errorf("Library module name %s does not start with lib", module) 52 } 53 return matches[1], nil 54} 55 56func flagsToBuilderFlags(in Flags) builderFlags { 57 return builderFlags{ 58 globalCommonFlags: strings.Join(in.Global.CommonFlags, " "), 59 globalAsFlags: strings.Join(in.Global.AsFlags, " "), 60 globalYasmFlags: strings.Join(in.Global.YasmFlags, " "), 61 globalCFlags: strings.Join(in.Global.CFlags, " "), 62 globalToolingCFlags: strings.Join(in.Global.ToolingCFlags, " "), 63 globalToolingCppFlags: strings.Join(in.Global.ToolingCppFlags, " "), 64 globalConlyFlags: strings.Join(in.Global.ConlyFlags, " "), 65 globalCppFlags: strings.Join(in.Global.CppFlags, " "), 66 globalLdFlags: strings.Join(in.Global.LdFlags, " "), 67 68 localCommonFlags: strings.Join(in.Local.CommonFlags, " "), 69 localAsFlags: strings.Join(in.Local.AsFlags, " "), 70 localYasmFlags: strings.Join(in.Local.YasmFlags, " "), 71 localCFlags: strings.Join(in.Local.CFlags, " "), 72 localToolingCFlags: strings.Join(in.Local.ToolingCFlags, " "), 73 localToolingCppFlags: strings.Join(in.Local.ToolingCppFlags, " "), 74 localConlyFlags: strings.Join(in.Local.ConlyFlags, " "), 75 localCppFlags: strings.Join(in.Local.CppFlags, " "), 76 localLdFlags: strings.Join(in.Local.LdFlags, " "), 77 78 aidlFlags: strings.Join(in.aidlFlags, " "), 79 rsFlags: strings.Join(in.rsFlags, " "), 80 libFlags: strings.Join(in.libFlags, " "), 81 extraLibFlags: strings.Join(in.extraLibFlags, " "), 82 tidyFlags: strings.Join(in.TidyFlags, " "), 83 sAbiFlags: strings.Join(in.SAbiFlags, " "), 84 toolchain: in.Toolchain, 85 gcovCoverage: in.GcovCoverage, 86 tidy: in.Tidy, 87 sAbiDump: in.SAbiDump, 88 emitXrefs: in.EmitXrefs, 89 90 systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "), 91 92 assemblerWithCpp: in.AssemblerWithCpp, 93 groupStaticLibs: in.GroupStaticLibs, 94 95 proto: in.proto, 96 protoC: in.protoC, 97 protoOptionsFile: in.protoOptionsFile, 98 99 yacc: in.Yacc, 100 lex: in.Lex, 101 } 102} 103 104func flagsToStripFlags(in Flags) StripFlags { 105 return StripFlags{Toolchain: in.Toolchain} 106} 107 108func addPrefix(list []string, prefix string) []string { 109 for i := range list { 110 list[i] = prefix + list[i] 111 } 112 return list 113} 114 115func addSuffix(list []string, suffix string) []string { 116 for i := range list { 117 list[i] = list[i] + suffix 118 } 119 return list 120} 121 122// linkDirOnDevice/linkName -> target 123func makeSymlinkCmd(linkDirOnDevice string, linkName string, target string) string { 124 dir := filepath.Join("$(PRODUCT_OUT)", linkDirOnDevice) 125 return "mkdir -p " + dir + " && " + 126 "ln -sf " + target + " " + filepath.Join(dir, linkName) 127} 128 129func copyFileRule(ctx android.SingletonContext, path android.Path, out string) android.OutputPath { 130 outPath := android.PathForOutput(ctx, out) 131 ctx.Build(pctx, android.BuildParams{ 132 Rule: android.Cp, 133 Input: path, 134 Output: outPath, 135 Description: "copy " + path.String() + " -> " + out, 136 Args: map[string]string{ 137 "cpFlags": "-f -L", 138 }, 139 }) 140 return outPath 141} 142 143func combineNoticesRule(ctx android.SingletonContext, paths android.Paths, out string) android.OutputPath { 144 outPath := android.PathForOutput(ctx, out) 145 ctx.Build(pctx, android.BuildParams{ 146 Rule: android.Cat, 147 Inputs: paths, 148 Output: outPath, 149 Description: "combine notices for " + out, 150 }) 151 return outPath 152} 153 154func writeStringToFileRule(ctx android.SingletonContext, content, out string) android.OutputPath { 155 outPath := android.PathForOutput(ctx, out) 156 android.WriteFileRule(ctx, outPath, content) 157 return outPath 158} 159 160// Dump a map to a list file as: 161// 162// {key1} {value1} 163// {key2} {value2} 164// ... 165func installMapListFileRule(ctx android.SingletonContext, m map[string]string, path string) android.OutputPath { 166 var txtBuilder strings.Builder 167 for idx, k := range android.SortedStringKeys(m) { 168 if idx > 0 { 169 txtBuilder.WriteString("\n") 170 } 171 txtBuilder.WriteString(k) 172 txtBuilder.WriteString(" ") 173 txtBuilder.WriteString(m[k]) 174 } 175 return writeStringToFileRule(ctx, txtBuilder.String(), path) 176} 177