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