blob: 0694cb7dd1d79207667ed24259826b31c349d37e [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// 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 (
Colin Cross0af4b842015-04-30 16:36:18 -070022 "fmt"
Colin Crossb98c8b02016-07-29 13:44:28 -070023 "path/filepath"
Colin Cross0af4b842015-04-30 16:36:18 -070024 "runtime"
25 "strconv"
Colin Cross3f40fa42015-01-30 17:27:36 -080026 "strings"
Colin Crossed4cf0b2015-03-26 14:43:45 -070027
28 "github.com/google/blueprint"
Colin Crossb98c8b02016-07-29 13:44:28 -070029
30 "android/soong/android"
31 "android/soong/cc/config"
Colin Cross3f40fa42015-01-30 17:27:36 -080032)
33
34const (
Dan Albertc3144b12015-04-28 18:17:56 -070035 objectExtension = ".o"
Colin Cross3f40fa42015-01-30 17:27:36 -080036 staticLibraryExtension = ".a"
37)
38
39var (
Colin Cross635c3b02016-05-18 15:37:25 -070040 pctx = android.NewPackageContext("android/soong/cc")
Colin Cross3f40fa42015-01-30 17:27:36 -080041
Colin Cross9d45bb72016-08-29 16:14:13 -070042 cc = pctx.AndroidGomaStaticRule("cc",
Colin Cross3f40fa42015-01-30 17:27:36 -080043 blueprint.RuleParams{
44 Depfile: "${out}.d",
45 Deps: blueprint.DepsGCC,
Alistair Strachan777475c2016-08-26 12:55:49 -070046 Command: "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -MD -MF ${out}.d -o $out $in",
Dan Willemsenc94a7682015-11-17 15:27:28 -080047 CommandDeps: []string{"$ccCmd"},
Colin Cross3f40fa42015-01-30 17:27:36 -080048 Description: "cc $out",
49 },
Dan Willemsen322a0a62015-11-17 15:19:46 -080050 "ccCmd", "cFlags")
Colin Cross3f40fa42015-01-30 17:27:36 -080051
Colin Cross9d45bb72016-08-29 16:14:13 -070052 ld = pctx.AndroidStaticRule("ld",
Colin Cross3f40fa42015-01-30 17:27:36 -080053 blueprint.RuleParams{
Dan Albertce2b8392016-07-21 13:16:49 -070054 Command: "$ldCmd ${crtBegin} @${out}.rsp " +
Colin Cross28344522015-04-22 13:07:53 -070055 "${libFlags} ${crtEnd} -o ${out} ${ldFlags}",
Dan Willemsenc94a7682015-11-17 15:27:28 -080056 CommandDeps: []string{"$ldCmd"},
Colin Cross7d21c442015-03-30 17:47:53 -070057 Description: "ld $out",
58 Rspfile: "${out}.rsp",
59 RspfileContent: "${in}",
Colin Cross3f40fa42015-01-30 17:27:36 -080060 },
Dan Albertce2b8392016-07-21 13:16:49 -070061 "ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags")
Colin Cross3f40fa42015-01-30 17:27:36 -080062
Colin Cross9d45bb72016-08-29 16:14:13 -070063 partialLd = pctx.AndroidStaticRule("partialLd",
Colin Cross3f40fa42015-01-30 17:27:36 -080064 blueprint.RuleParams{
Colin Cross41280a42015-11-23 14:01:42 -080065 Command: "$ldCmd -nostdlib -Wl,-r ${in} -o ${out} ${ldFlags}",
Dan Willemsenc94a7682015-11-17 15:27:28 -080066 CommandDeps: []string{"$ldCmd"},
Colin Cross3f40fa42015-01-30 17:27:36 -080067 Description: "partialLd $out",
68 },
Colin Cross41280a42015-11-23 14:01:42 -080069 "ldCmd", "ldFlags")
Colin Cross3f40fa42015-01-30 17:27:36 -080070
Colin Cross9d45bb72016-08-29 16:14:13 -070071 ar = pctx.AndroidStaticRule("ar",
Colin Cross3f40fa42015-01-30 17:27:36 -080072 blueprint.RuleParams{
Colin Cross7d21c442015-03-30 17:47:53 -070073 Command: "rm -f ${out} && $arCmd $arFlags $out @${out}.rsp",
Dan Willemsenc94a7682015-11-17 15:27:28 -080074 CommandDeps: []string{"$arCmd"},
Colin Cross7d21c442015-03-30 17:47:53 -070075 Description: "ar $out",
76 Rspfile: "${out}.rsp",
77 RspfileContent: "${in}",
Colin Cross3f40fa42015-01-30 17:27:36 -080078 },
79 "arCmd", "arFlags")
80
Colin Cross9d45bb72016-08-29 16:14:13 -070081 darwinAr = pctx.AndroidStaticRule("darwinAr",
Colin Cross0af4b842015-04-30 16:36:18 -070082 blueprint.RuleParams{
Colin Crossb98c8b02016-07-29 13:44:28 -070083 Command: "rm -f ${out} && ${config.MacArPath} $arFlags $out $in",
84 CommandDeps: []string{"${config.MacArPath}"},
Colin Cross0af4b842015-04-30 16:36:18 -070085 Description: "ar $out",
86 },
Colin Crossb8ecdfe2016-05-03 15:10:29 -070087 "arFlags")
Colin Cross0af4b842015-04-30 16:36:18 -070088
Colin Cross9d45bb72016-08-29 16:14:13 -070089 darwinAppendAr = pctx.AndroidStaticRule("darwinAppendAr",
Colin Cross0af4b842015-04-30 16:36:18 -070090 blueprint.RuleParams{
Colin Crossb98c8b02016-07-29 13:44:28 -070091 Command: "cp -f ${inAr} ${out}.tmp && ${config.MacArPath} $arFlags ${out}.tmp $in && mv ${out}.tmp ${out}",
92 CommandDeps: []string{"${config.MacArPath}", "${inAr}"},
Colin Cross0af4b842015-04-30 16:36:18 -070093 Description: "ar $out",
94 },
Colin Crossb8ecdfe2016-05-03 15:10:29 -070095 "arFlags", "inAr")
96
Colin Cross9d45bb72016-08-29 16:14:13 -070097 darwinStrip = pctx.AndroidStaticRule("darwinStrip",
Colin Crossb8ecdfe2016-05-03 15:10:29 -070098 blueprint.RuleParams{
Colin Crossa24166b2016-08-01 15:42:38 -070099 Command: "${config.MacStripPath} -u -r -o $out $in",
100 CommandDeps: []string{"${config.MacStripPath}"},
Colin Crossb8ecdfe2016-05-03 15:10:29 -0700101 Description: "strip $out",
102 })
Colin Cross0af4b842015-04-30 16:36:18 -0700103
Colin Cross9d45bb72016-08-29 16:14:13 -0700104 prefixSymbols = pctx.AndroidStaticRule("prefixSymbols",
Colin Crossbfae8852015-03-26 14:44:11 -0700105 blueprint.RuleParams{
106 Command: "$objcopyCmd --prefix-symbols=${prefix} ${in} ${out}",
Dan Willemsenc94a7682015-11-17 15:27:28 -0800107 CommandDeps: []string{"$objcopyCmd"},
Colin Crossbfae8852015-03-26 14:44:11 -0700108 Description: "prefixSymbols $out",
109 },
110 "objcopyCmd", "prefix")
111
Nan Zhang43a485c2017-03-27 14:27:58 -0700112 _ = pctx.SourcePathVariable("stripPath", "build/soong/scripts/strip.sh")
Colin Cross665dce92016-04-28 14:50:03 -0700113
Colin Cross9d45bb72016-08-29 16:14:13 -0700114 strip = pctx.AndroidStaticRule("strip",
Colin Cross665dce92016-04-28 14:50:03 -0700115 blueprint.RuleParams{
116 Depfile: "${out}.d",
117 Deps: blueprint.DepsGCC,
118 Command: "CROSS_COMPILE=$crossCompile $stripPath ${args} -i ${in} -o ${out} -d ${out}.d",
119 CommandDeps: []string{"$stripPath"},
120 Description: "strip $out",
121 },
122 "args", "crossCompile")
123
Colin Cross9d45bb72016-08-29 16:14:13 -0700124 emptyFile = pctx.AndroidStaticRule("emptyFile",
Dan Willemsen9f0b5502016-05-13 14:05:09 -0700125 blueprint.RuleParams{
126 Command: "rm -f $out && touch $out",
127 Description: "empty file $out",
128 })
129
Nan Zhang43a485c2017-03-27 14:27:58 -0700130 _ = pctx.SourcePathVariable("copyGccLibPath", "build/soong/scripts/copygcclib.sh")
Colin Cross3f40fa42015-01-30 17:27:36 -0800131
Colin Cross9d45bb72016-08-29 16:14:13 -0700132 copyGccLib = pctx.AndroidStaticRule("copyGccLib",
Colin Cross3f40fa42015-01-30 17:27:36 -0800133 blueprint.RuleParams{
134 Depfile: "${out}.d",
135 Deps: blueprint.DepsGCC,
136 Command: "$copyGccLibPath $out $ccCmd $cFlags -print-file-name=${libName}",
Dan Willemsenc94a7682015-11-17 15:27:28 -0800137 CommandDeps: []string{"$copyGccLibPath", "$ccCmd"},
Colin Cross3f40fa42015-01-30 17:27:36 -0800138 Description: "copy gcc $out",
139 },
140 "ccCmd", "cFlags", "libName")
Colin Cross26c34ed2016-09-30 17:10:16 -0700141
Nan Zhang43a485c2017-03-27 14:27:58 -0700142 _ = pctx.SourcePathVariable("tocPath", "build/soong/scripts/toc.sh")
Colin Cross26c34ed2016-09-30 17:10:16 -0700143
144 toc = pctx.AndroidStaticRule("toc",
145 blueprint.RuleParams{
146 Depfile: "${out}.d",
147 Deps: blueprint.DepsGCC,
148 Command: "CROSS_COMPILE=$crossCompile $tocPath -i ${in} -o ${out} -d ${out}.d",
149 CommandDeps: []string{"$tocPath"},
150 Restat: true,
151 },
152 "crossCompile")
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700153
154 clangTidy = pctx.AndroidStaticRule("clangTidy",
155 blueprint.RuleParams{
156 Command: "rm -f $out && ${config.ClangBin}/clang-tidy $tidyFlags $in -- $cFlags && touch $out",
157 CommandDeps: []string{"${config.ClangBin}/clang-tidy"},
158 Description: "tidy $out",
159 },
160 "cFlags", "tidyFlags")
Colin Cross91e90042016-12-02 17:13:24 -0800161
Nan Zhang43a485c2017-03-27 14:27:58 -0700162 _ = pctx.SourcePathVariable("yasmCmd", "prebuilts/misc/${config.HostPrebuiltTag}/yasm/yasm")
Colin Cross91e90042016-12-02 17:13:24 -0800163
164 yasm = pctx.AndroidStaticRule("yasm",
165 blueprint.RuleParams{
166 Command: "$yasmCmd $asFlags -o $out $in",
167 CommandDeps: []string{"$yasmCmd"},
168 Description: "yasm $out",
169 },
170 "asFlags")
Colin Cross3f40fa42015-01-30 17:27:36 -0800171)
172
Dan Willemsen322a0a62015-11-17 15:19:46 -0800173func init() {
174 // We run gcc/clang with PWD=/proc/self/cwd to remove $TOP from the
175 // debug output. That way two builds in two different directories will
176 // create the same output.
177 if runtime.GOOS != "darwin" {
178 pctx.StaticVariable("relPwd", "PWD=/proc/self/cwd")
179 } else {
180 // Darwin doesn't have /proc
181 pctx.StaticVariable("relPwd", "")
182 }
183}
184
Colin Cross3f40fa42015-01-30 17:27:36 -0800185type builderFlags struct {
186 globalFlags string
Vishwath Mohan83d9f712017-03-16 11:01:23 -0700187 arFlags string
Colin Cross3f40fa42015-01-30 17:27:36 -0800188 asFlags string
189 cFlags string
190 conlyFlags string
191 cppFlags string
192 ldFlags string
Colin Cross16b23492016-01-06 14:41:07 -0800193 libFlags string
Colin Cross581c1892015-04-07 16:50:10 -0700194 yaccFlags string
Colin Cross0c461f12016-10-20 16:11:43 -0700195 protoFlags string
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700196 tidyFlags string
Colin Cross91e90042016-12-02 17:13:24 -0800197 yasmFlags string
Dan Willemsene1240db2016-11-03 14:28:51 -0700198 aidlFlags string
Colin Crossb98c8b02016-07-29 13:44:28 -0700199 toolchain config.Toolchain
Colin Cross3f40fa42015-01-30 17:27:36 -0800200 clang bool
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700201 tidy bool
Dan Willemsen581341d2017-02-09 16:16:31 -0800202 coverage bool
Colin Cross665dce92016-04-28 14:50:03 -0700203
Colin Crossc3199482017-03-30 15:03:04 -0700204 systemIncludeFlags string
205
Colin Cross18c0c5a2016-12-01 14:45:23 -0800206 groupStaticLibs bool
207
Colin Cross665dce92016-04-28 14:50:03 -0700208 stripKeepSymbols bool
209 stripKeepMiniDebugInfo bool
210 stripAddGnuDebuglink bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800211}
212
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700213type Objects struct {
Dan Willemsen581341d2017-02-09 16:16:31 -0800214 objFiles android.Paths
215 tidyFiles android.Paths
216 coverageFiles android.Paths
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700217}
218
219func (a Objects) Copy() Objects {
220 return Objects{
Dan Willemsen581341d2017-02-09 16:16:31 -0800221 objFiles: append(android.Paths{}, a.objFiles...),
222 tidyFiles: append(android.Paths{}, a.tidyFiles...),
223 coverageFiles: append(android.Paths{}, a.coverageFiles...),
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700224 }
225}
226
227func (a Objects) Append(b Objects) Objects {
228 return Objects{
Dan Willemsen581341d2017-02-09 16:16:31 -0800229 objFiles: append(a.objFiles, b.objFiles...),
230 tidyFiles: append(a.tidyFiles, b.tidyFiles...),
231 coverageFiles: append(a.coverageFiles, b.coverageFiles...),
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700232 }
233}
234
Colin Cross3f40fa42015-01-30 17:27:36 -0800235// Generate rules for compiling multiple .c, .cpp, or .S files to individual .o files
Colin Cross635c3b02016-05-18 15:37:25 -0700236func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles android.Paths,
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700237 flags builderFlags, deps android.Paths) Objects {
Colin Cross581c1892015-04-07 16:50:10 -0700238
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700239 objFiles := make(android.Paths, len(srcFiles))
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700240 var tidyFiles android.Paths
241 if flags.tidy && flags.clang {
242 tidyFiles = make(android.Paths, 0, len(srcFiles))
243 }
Dan Willemsen581341d2017-02-09 16:16:31 -0800244 var coverageFiles android.Paths
245 if flags.coverage {
246 coverageFiles = make(android.Paths, 0, len(srcFiles))
247 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800248
Colin Crossc3199482017-03-30 15:03:04 -0700249 cflags := strings.Join([]string{
250 flags.globalFlags,
251 flags.systemIncludeFlags,
252 flags.cFlags,
253 flags.conlyFlags,
254 }, " ")
255
256 cppflags := strings.Join([]string{
257 flags.globalFlags,
258 flags.systemIncludeFlags,
259 flags.cFlags,
260 flags.cppFlags,
261 }, " ")
262
263 asflags := strings.Join([]string{
264 flags.globalFlags,
265 flags.systemIncludeFlags,
266 flags.asFlags,
267 }, " ")
Colin Cross3f40fa42015-01-30 17:27:36 -0800268
Dan Willemsenbe03f342016-03-03 17:21:04 -0800269 if flags.clang {
Colin Crossb98c8b02016-07-29 13:44:28 -0700270 cflags += " ${config.NoOverrideClangGlobalCflags}"
271 cppflags += " ${config.NoOverrideClangGlobalCflags}"
Dan Willemsenbe03f342016-03-03 17:21:04 -0800272 } else {
Colin Crossb98c8b02016-07-29 13:44:28 -0700273 cflags += " ${config.NoOverrideGlobalCflags}"
274 cppflags += " ${config.NoOverrideGlobalCflags}"
Dan Willemsenbe03f342016-03-03 17:21:04 -0800275 }
276
Colin Cross3f40fa42015-01-30 17:27:36 -0800277 for i, srcFile := range srcFiles {
Dan Willemsen21ec4902016-11-02 20:43:13 -0700278 objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
Colin Cross3f40fa42015-01-30 17:27:36 -0800279
280 objFiles[i] = objFile
281
Colin Cross91e90042016-12-02 17:13:24 -0800282 if srcFile.Ext() == ".asm" {
283 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
284 Rule: yasm,
285 Output: objFile,
286 Input: srcFile,
287 OrderOnly: deps,
288 Args: map[string]string{
289 "asFlags": flags.yasmFlags,
290 },
291 })
292 continue
293 }
294
Colin Cross3f40fa42015-01-30 17:27:36 -0800295 var moduleCflags string
296 var ccCmd string
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700297 tidy := flags.tidy && flags.clang
Dan Willemsen581341d2017-02-09 16:16:31 -0800298 coverage := flags.coverage
Colin Cross3f40fa42015-01-30 17:27:36 -0800299
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700300 switch srcFile.Ext() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800301 case ".S", ".s":
302 ccCmd = "gcc"
303 moduleCflags = asflags
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700304 tidy = false
Dan Willemsen581341d2017-02-09 16:16:31 -0800305 coverage = false
Colin Cross3f40fa42015-01-30 17:27:36 -0800306 case ".c":
307 ccCmd = "gcc"
308 moduleCflags = cflags
Colin Cross9978ffe2016-12-01 15:31:22 -0800309 case ".cpp", ".cc", ".mm":
Colin Cross3f40fa42015-01-30 17:27:36 -0800310 ccCmd = "g++"
311 moduleCflags = cppflags
312 default:
313 ctx.ModuleErrorf("File %s has unknown extension", srcFile)
314 continue
315 }
316
317 if flags.clang {
318 switch ccCmd {
319 case "gcc":
320 ccCmd = "clang"
321 case "g++":
322 ccCmd = "clang++"
323 default:
324 panic("unrecoginzied ccCmd")
325 }
326
Colin Crossb98c8b02016-07-29 13:44:28 -0700327 ccCmd = "${config.ClangBin}/" + ccCmd
Colin Cross3f40fa42015-01-30 17:27:36 -0800328 } else {
329 ccCmd = gccCmd(flags.toolchain, ccCmd)
330 }
331
Dan Willemsen581341d2017-02-09 16:16:31 -0800332 var implicitOutputs android.WritablePaths
333 if coverage {
334 gcnoFile := android.ObjPathWithExt(ctx, subdir, srcFile, "gcno")
335 implicitOutputs = append(implicitOutputs, gcnoFile)
336 coverageFiles = append(coverageFiles, gcnoFile)
337 }
338
Colin Cross635c3b02016-05-18 15:37:25 -0700339 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsen581341d2017-02-09 16:16:31 -0800340 Rule: cc,
341 Output: objFile,
342 ImplicitOutputs: implicitOutputs,
343 Input: srcFile,
344 OrderOnly: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800345 Args: map[string]string{
Colin Cross28344522015-04-22 13:07:53 -0700346 "cFlags": moduleCflags,
347 "ccCmd": ccCmd,
Colin Cross3f40fa42015-01-30 17:27:36 -0800348 },
349 })
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700350
351 if tidy {
Dan Willemsen21ec4902016-11-02 20:43:13 -0700352 tidyFile := android.ObjPathWithExt(ctx, subdir, srcFile, "tidy")
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700353 tidyFiles = append(tidyFiles, tidyFile)
354
355 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
356 Rule: clangTidy,
357 Output: tidyFile,
358 Input: srcFile,
359 // We must depend on objFile, since clang-tidy doesn't
360 // support exporting dependencies.
361 Implicit: objFile,
362 Args: map[string]string{
363 "cFlags": moduleCflags,
364 "tidyFlags": flags.tidyFlags,
365 },
366 })
367 }
368
Colin Cross3f40fa42015-01-30 17:27:36 -0800369 }
370
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700371 return Objects{
Dan Willemsen581341d2017-02-09 16:16:31 -0800372 objFiles: objFiles,
373 tidyFiles: tidyFiles,
374 coverageFiles: coverageFiles,
Dan Willemsen5cb580f2016-09-26 17:33:01 -0700375 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800376}
377
378// Generate a rule for compiling multiple .o files to a static library (.a)
Colin Cross635c3b02016-05-18 15:37:25 -0700379func TransformObjToStaticLib(ctx android.ModuleContext, objFiles android.Paths,
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700380 flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800381
Dan Willemsen581341d2017-02-09 16:16:31 -0800382 if ctx.Darwin() {
383 transformDarwinObjToStaticLib(ctx, objFiles, flags, outputFile, deps)
384 return
385 }
386
Colin Cross3f40fa42015-01-30 17:27:36 -0800387 arCmd := gccCmd(flags.toolchain, "ar")
388 arFlags := "crsPD"
Vishwath Mohan83d9f712017-03-16 11:01:23 -0700389 if flags.arFlags != "" {
390 arFlags += " " + flags.arFlags
391 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800392
Colin Cross635c3b02016-05-18 15:37:25 -0700393 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700394 Rule: ar,
395 Output: outputFile,
396 Inputs: objFiles,
397 Implicits: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800398 Args: map[string]string{
399 "arFlags": arFlags,
400 "arCmd": arCmd,
401 },
402 })
403}
404
Colin Cross0af4b842015-04-30 16:36:18 -0700405// Generate a rule for compiling multiple .o files to a static library (.a) on
406// darwin. The darwin ar tool doesn't support @file for list files, and has a
407// very small command line length limit, so we have to split the ar into multiple
408// steps, each appending to the previous one.
Dan Willemsen581341d2017-02-09 16:16:31 -0800409func transformDarwinObjToStaticLib(ctx android.ModuleContext, objFiles android.Paths,
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700410 flags builderFlags, outputPath android.ModuleOutPath, deps android.Paths) {
Colin Cross0af4b842015-04-30 16:36:18 -0700411
Colin Cross0af4b842015-04-30 16:36:18 -0700412 arFlags := "cqs"
413
Dan Willemsen9f0b5502016-05-13 14:05:09 -0700414 if len(objFiles) == 0 {
Colin Cross635c3b02016-05-18 15:37:25 -0700415 dummy := android.PathForModuleOut(ctx, "dummy"+objectExtension)
416 dummyAr := android.PathForModuleOut(ctx, "dummy"+staticLibraryExtension)
Dan Willemsen9f0b5502016-05-13 14:05:09 -0700417
Colin Cross635c3b02016-05-18 15:37:25 -0700418 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700419 Rule: emptyFile,
420 Output: dummy,
421 Implicits: deps,
Dan Willemsen9f0b5502016-05-13 14:05:09 -0700422 })
423
Colin Cross635c3b02016-05-18 15:37:25 -0700424 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsen9f0b5502016-05-13 14:05:09 -0700425 Rule: darwinAr,
426 Output: dummyAr,
427 Input: dummy,
428 Args: map[string]string{
429 "arFlags": arFlags,
430 },
431 })
432
Colin Cross635c3b02016-05-18 15:37:25 -0700433 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsen9f0b5502016-05-13 14:05:09 -0700434 Rule: darwinAppendAr,
435 Output: outputPath,
436 Input: dummy,
437 Args: map[string]string{
438 "arFlags": "d",
439 "inAr": dummyAr.String(),
440 },
441 })
442
443 return
444 }
445
Colin Cross0af4b842015-04-30 16:36:18 -0700446 // ARG_MAX on darwin is 262144, use half that to be safe
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700447 objFilesLists, err := splitListForSize(objFiles.Strings(), 131072)
Colin Cross0af4b842015-04-30 16:36:18 -0700448 if err != nil {
449 ctx.ModuleErrorf("%s", err.Error())
450 }
451
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700452 outputFile := outputPath.String()
453
Colin Cross0af4b842015-04-30 16:36:18 -0700454 var in, out string
455 for i, l := range objFilesLists {
456 in = out
457 out = outputFile
458 if i != len(objFilesLists)-1 {
459 out += "." + strconv.Itoa(i)
460 }
461
462 if in == "" {
463 ctx.Build(pctx, blueprint.BuildParams{
Dan Willemsena03cf6d2016-09-26 15:45:04 -0700464 Rule: darwinAr,
465 Outputs: []string{out},
466 Inputs: l,
467 Implicits: deps.Strings(),
Colin Cross0af4b842015-04-30 16:36:18 -0700468 Args: map[string]string{
469 "arFlags": arFlags,
Colin Cross0af4b842015-04-30 16:36:18 -0700470 },
471 })
472 } else {
473 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross635c3b02016-05-18 15:37:25 -0700474 Rule: darwinAppendAr,
475 Outputs: []string{out},
476 Inputs: l,
Colin Cross0af4b842015-04-30 16:36:18 -0700477 Args: map[string]string{
478 "arFlags": arFlags,
Colin Cross0af4b842015-04-30 16:36:18 -0700479 "inAr": in,
480 },
481 })
482 }
483 }
484}
485
Colin Cross3f40fa42015-01-30 17:27:36 -0800486// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
487// and shared libraires, to a shared library (.so) or dynamic executable
Colin Cross635c3b02016-05-18 15:37:25 -0700488func TransformObjToDynamicBinary(ctx android.ModuleContext,
489 objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps android.Paths,
490 crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800491
492 var ldCmd string
493 if flags.clang {
Colin Crossb98c8b02016-07-29 13:44:28 -0700494 ldCmd = "${config.ClangBin}/clang++"
Colin Cross3f40fa42015-01-30 17:27:36 -0800495 } else {
496 ldCmd = gccCmd(flags.toolchain, "g++")
497 }
498
Colin Cross3f40fa42015-01-30 17:27:36 -0800499 var libFlagsList []string
500
Colin Cross16b23492016-01-06 14:41:07 -0800501 if len(flags.libFlags) > 0 {
502 libFlagsList = append(libFlagsList, flags.libFlags)
503 }
504
Colin Cross3f40fa42015-01-30 17:27:36 -0800505 if len(wholeStaticLibs) > 0 {
Dan Willemsen490fd492015-11-24 17:53:15 -0800506 if ctx.Host() && ctx.Darwin() {
Colin Cross635c3b02016-05-18 15:37:25 -0700507 libFlagsList = append(libFlagsList, android.JoinWithPrefix(wholeStaticLibs.Strings(), "-force_load "))
Colin Cross0af4b842015-04-30 16:36:18 -0700508 } else {
509 libFlagsList = append(libFlagsList, "-Wl,--whole-archive ")
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700510 libFlagsList = append(libFlagsList, wholeStaticLibs.Strings()...)
Colin Cross0af4b842015-04-30 16:36:18 -0700511 libFlagsList = append(libFlagsList, "-Wl,--no-whole-archive ")
512 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800513 }
514
Colin Cross7a7cf972016-12-05 18:47:39 -0800515 if flags.groupStaticLibs && !ctx.Darwin() && len(staticLibs) > 0 {
Colin Cross18c0c5a2016-12-01 14:45:23 -0800516 libFlagsList = append(libFlagsList, "-Wl,--start-group")
517 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700518 libFlagsList = append(libFlagsList, staticLibs.Strings()...)
Colin Cross7a7cf972016-12-05 18:47:39 -0800519 if flags.groupStaticLibs && !ctx.Darwin() && len(staticLibs) > 0 {
Colin Cross18c0c5a2016-12-01 14:45:23 -0800520 libFlagsList = append(libFlagsList, "-Wl,--end-group")
521 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800522
Stephen Hines10347862016-07-18 15:54:54 -0700523 if groupLate && !ctx.Darwin() && len(lateStaticLibs) > 0 {
Dan Willemsenedc385f2015-07-08 13:02:23 -0700524 libFlagsList = append(libFlagsList, "-Wl,--start-group")
525 }
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700526 libFlagsList = append(libFlagsList, lateStaticLibs.Strings()...)
Stephen Hines10347862016-07-18 15:54:54 -0700527 if groupLate && !ctx.Darwin() && len(lateStaticLibs) > 0 {
Dan Willemsenedc385f2015-07-08 13:02:23 -0700528 libFlagsList = append(libFlagsList, "-Wl,--end-group")
529 }
530
Colin Cross3f40fa42015-01-30 17:27:36 -0800531 for _, lib := range sharedLibs {
Dan Albert9840e1b2016-07-21 08:47:33 -0700532 libFlagsList = append(libFlagsList, lib.String())
Colin Cross3f40fa42015-01-30 17:27:36 -0800533 }
534
Colin Cross3f40fa42015-01-30 17:27:36 -0800535 deps = append(deps, staticLibs...)
Colin Cross3075ad02015-03-17 10:47:08 -0700536 deps = append(deps, lateStaticLibs...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800537 deps = append(deps, wholeStaticLibs...)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700538 if crtBegin.Valid() {
539 deps = append(deps, crtBegin.Path(), crtEnd.Path())
Colin Cross3f40fa42015-01-30 17:27:36 -0800540 }
541
Colin Cross635c3b02016-05-18 15:37:25 -0700542 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross3f40fa42015-01-30 17:27:36 -0800543 Rule: ld,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700544 Output: outputFile,
Colin Cross3f40fa42015-01-30 17:27:36 -0800545 Inputs: objFiles,
546 Implicits: deps,
547 Args: map[string]string{
Dan Albertce2b8392016-07-21 13:16:49 -0700548 "ldCmd": ldCmd,
549 "crtBegin": crtBegin.String(),
550 "libFlags": strings.Join(libFlagsList, " "),
551 "ldFlags": flags.ldFlags,
552 "crtEnd": crtEnd.String(),
Colin Cross3f40fa42015-01-30 17:27:36 -0800553 },
554 })
555}
556
Colin Cross26c34ed2016-09-30 17:10:16 -0700557// Generate a rule for extract a table of contents from a shared library (.so)
558func TransformSharedObjectToToc(ctx android.ModuleContext, inputFile android.WritablePath,
559 outputFile android.WritablePath, flags builderFlags) {
560
561 crossCompile := gccCmd(flags.toolchain, "")
562
563 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
564 Rule: toc,
565 Output: outputFile,
566 Input: inputFile,
567 Args: map[string]string{
568 "crossCompile": crossCompile,
569 },
570 })
571}
572
Colin Cross3f40fa42015-01-30 17:27:36 -0800573// Generate a rule for compiling multiple .o files to a .o using ld partial linking
Colin Cross635c3b02016-05-18 15:37:25 -0700574func TransformObjsToObj(ctx android.ModuleContext, objFiles android.Paths,
575 flags builderFlags, outputFile android.WritablePath) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800576
Colin Cross41280a42015-11-23 14:01:42 -0800577 var ldCmd string
578 if flags.clang {
Colin Crossb98c8b02016-07-29 13:44:28 -0700579 ldCmd = "${config.ClangBin}/clang++"
Colin Cross41280a42015-11-23 14:01:42 -0800580 } else {
581 ldCmd = gccCmd(flags.toolchain, "g++")
582 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800583
Colin Cross635c3b02016-05-18 15:37:25 -0700584 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700585 Rule: partialLd,
586 Output: outputFile,
587 Inputs: objFiles,
Colin Cross3f40fa42015-01-30 17:27:36 -0800588 Args: map[string]string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700589 "ldCmd": ldCmd,
Colin Cross41280a42015-11-23 14:01:42 -0800590 "ldFlags": flags.ldFlags,
Colin Cross3f40fa42015-01-30 17:27:36 -0800591 },
592 })
593}
594
Colin Crossbfae8852015-03-26 14:44:11 -0700595// Generate a rule for runing objcopy --prefix-symbols on a binary
Colin Cross635c3b02016-05-18 15:37:25 -0700596func TransformBinaryPrefixSymbols(ctx android.ModuleContext, prefix string, inputFile android.Path,
597 flags builderFlags, outputFile android.WritablePath) {
Colin Crossbfae8852015-03-26 14:44:11 -0700598
599 objcopyCmd := gccCmd(flags.toolchain, "objcopy")
600
Colin Cross635c3b02016-05-18 15:37:25 -0700601 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700602 Rule: prefixSymbols,
603 Output: outputFile,
604 Input: inputFile,
Colin Crossbfae8852015-03-26 14:44:11 -0700605 Args: map[string]string{
606 "objcopyCmd": objcopyCmd,
607 "prefix": prefix,
608 },
609 })
610}
611
Colin Cross635c3b02016-05-18 15:37:25 -0700612func TransformStrip(ctx android.ModuleContext, inputFile android.Path,
613 outputFile android.WritablePath, flags builderFlags) {
Colin Cross665dce92016-04-28 14:50:03 -0700614
615 crossCompile := gccCmd(flags.toolchain, "")
616 args := ""
617 if flags.stripAddGnuDebuglink {
618 args += " --add-gnu-debuglink"
619 }
620 if flags.stripKeepMiniDebugInfo {
621 args += " --keep-mini-debug-info"
622 }
623 if flags.stripKeepSymbols {
624 args += " --keep-symbols"
625 }
626
Colin Cross635c3b02016-05-18 15:37:25 -0700627 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross665dce92016-04-28 14:50:03 -0700628 Rule: strip,
629 Output: outputFile,
630 Input: inputFile,
631 Args: map[string]string{
632 "crossCompile": crossCompile,
633 "args": args,
634 },
635 })
636}
637
Colin Cross635c3b02016-05-18 15:37:25 -0700638func TransformDarwinStrip(ctx android.ModuleContext, inputFile android.Path,
639 outputFile android.WritablePath) {
Colin Crossb8ecdfe2016-05-03 15:10:29 -0700640
Colin Cross635c3b02016-05-18 15:37:25 -0700641 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Crossb8ecdfe2016-05-03 15:10:29 -0700642 Rule: darwinStrip,
643 Output: outputFile,
644 Input: inputFile,
645 })
646}
647
Dan Willemsen581341d2017-02-09 16:16:31 -0800648func TransformCoverageFilesToLib(ctx android.ModuleContext,
649 inputs Objects, flags builderFlags, baseName string) android.OptionalPath {
650
651 if len(inputs.coverageFiles) > 0 {
652 outputFile := android.PathForModuleOut(ctx, baseName+".gcnodir")
653
654 TransformObjToStaticLib(ctx, inputs.coverageFiles, flags, outputFile, nil)
655
656 return android.OptionalPathForPath(outputFile)
657 }
658
659 return android.OptionalPath{}
660}
661
Colin Cross635c3b02016-05-18 15:37:25 -0700662func CopyGccLib(ctx android.ModuleContext, libName string,
663 flags builderFlags, outputFile android.WritablePath) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800664
Colin Cross635c3b02016-05-18 15:37:25 -0700665 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700666 Rule: copyGccLib,
667 Output: outputFile,
Colin Cross3f40fa42015-01-30 17:27:36 -0800668 Args: map[string]string{
669 "ccCmd": gccCmd(flags.toolchain, "gcc"),
670 "cFlags": flags.globalFlags,
671 "libName": libName,
672 },
673 })
674}
675
Colin Crossb98c8b02016-07-29 13:44:28 -0700676func gccCmd(toolchain config.Toolchain, cmd string) string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800677 return filepath.Join(toolchain.GccRoot(), "bin", toolchain.GccTriple()+"-"+cmd)
678}
Colin Cross0af4b842015-04-30 16:36:18 -0700679
680func splitListForSize(list []string, limit int) (lists [][]string, err error) {
681 var i int
682
683 start := 0
684 bytes := 0
685 for i = range list {
686 l := len(list[i])
687 if l > limit {
688 return nil, fmt.Errorf("list element greater than size limit (%d)", limit)
689 }
690 if bytes+l > limit {
691 lists = append(lists, list[start:i])
692 start = i
693 bytes = 0
694 }
695 bytes += l + 1 // count a space between each list element
696 }
697
698 lists = append(lists, list[start:])
699
700 totalLen := 0
701 for _, l := range lists {
702 totalLen += len(l)
703 }
704 if totalLen != len(list) {
705 panic(fmt.Errorf("Failed breaking up list, %d != %d", len(list), totalLen))
706 }
707 return lists, nil
708}