android.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. // Copyright 2017 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. package main
  15. import (
  16. mkparser "android/soong/androidmk/parser"
  17. "fmt"
  18. "sort"
  19. "strings"
  20. bpparser "github.com/google/blueprint/parser"
  21. )
  22. const (
  23. clear_vars = "__android_mk_clear_vars"
  24. )
  25. type bpVariable struct {
  26. name string
  27. variableType bpparser.Type
  28. }
  29. type variableAssignmentContext struct {
  30. file *bpFile
  31. prefix string
  32. mkvalue *mkparser.MakeString
  33. append bool
  34. }
  35. var rewriteProperties = map[string](func(variableAssignmentContext) error){
  36. // custom functions
  37. "LOCAL_AIDL_INCLUDES": localAidlIncludes,
  38. "LOCAL_C_INCLUDES": localIncludeDirs,
  39. "LOCAL_EXPORT_C_INCLUDE_DIRS": exportIncludeDirs,
  40. "LOCAL_LDFLAGS": ldflags,
  41. "LOCAL_MODULE_CLASS": prebuiltClass,
  42. "LOCAL_MODULE_STEM": stem,
  43. "LOCAL_MODULE_HOST_OS": hostOs,
  44. "LOCAL_SRC_FILES": srcFiles,
  45. "LOCAL_SANITIZE": sanitize(""),
  46. "LOCAL_SANITIZE_DIAG": sanitize("diag."),
  47. "LOCAL_CFLAGS": cflags,
  48. "LOCAL_UNINSTALLABLE_MODULE": invert("installable"),
  49. // composite functions
  50. "LOCAL_MODULE_TAGS": includeVariableIf(bpVariable{"tags", bpparser.ListType}, not(valueDumpEquals("optional"))),
  51. // skip functions
  52. "LOCAL_ADDITIONAL_DEPENDENCIES": skip, // TODO: check for only .mk files?
  53. "LOCAL_CPP_EXTENSION": skip,
  54. "LOCAL_MODULE_SUFFIX": skip, // TODO
  55. "LOCAL_PATH": skip, // Nothing to do, except maybe avoid the "./" in paths?
  56. "LOCAL_PRELINK_MODULE": skip, // Already phased out
  57. }
  58. // adds a group of properties all having the same type
  59. func addStandardProperties(propertyType bpparser.Type, properties map[string]string) {
  60. for key, val := range properties {
  61. rewriteProperties[key] = includeVariable(bpVariable{val, propertyType})
  62. }
  63. }
  64. func init() {
  65. addStandardProperties(bpparser.StringType,
  66. map[string]string{
  67. "LOCAL_MODULE": "name",
  68. "LOCAL_CXX_STL": "stl",
  69. "LOCAL_STRIP_MODULE": "strip",
  70. "LOCAL_MULTILIB": "compile_multilib",
  71. "LOCAL_ARM_MODE_HACK": "instruction_set",
  72. "LOCAL_SDK_VERSION": "sdk_version",
  73. "LOCAL_NDK_STL_VARIANT": "stl",
  74. "LOCAL_JAR_MANIFEST": "manifest",
  75. "LOCAL_JARJAR_RULES": "jarjar_rules",
  76. "LOCAL_CERTIFICATE": "certificate",
  77. "LOCAL_PACKAGE_NAME": "name",
  78. "LOCAL_MODULE_RELATIVE_PATH": "relative_install_path",
  79. "LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type",
  80. "LOCAL_MODULE_OWNER": "owner",
  81. "LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api",
  82. "LOCAL_NOTICE_FILE": "notice",
  83. "LOCAL_JAVA_LANGUAGE_VERSION": "java_version",
  84. })
  85. addStandardProperties(bpparser.ListType,
  86. map[string]string{
  87. "LOCAL_SRC_FILES_EXCLUDE": "exclude_srcs",
  88. "LOCAL_HEADER_LIBRARIES": "header_libs",
  89. "LOCAL_SHARED_LIBRARIES": "shared_libs",
  90. "LOCAL_STATIC_LIBRARIES": "static_libs",
  91. "LOCAL_WHOLE_STATIC_LIBRARIES": "whole_static_libs",
  92. "LOCAL_SYSTEM_SHARED_LIBRARIES": "system_shared_libs",
  93. "LOCAL_ASFLAGS": "asflags",
  94. "LOCAL_CLANG_ASFLAGS": "clang_asflags",
  95. "LOCAL_CONLYFLAGS": "conlyflags",
  96. "LOCAL_CPPFLAGS": "cppflags",
  97. "LOCAL_REQUIRED_MODULES": "required",
  98. "LOCAL_LDLIBS": "host_ldlibs",
  99. "LOCAL_CLANG_CFLAGS": "clang_cflags",
  100. "LOCAL_YACCFLAGS": "yaccflags",
  101. "LOCAL_SANITIZE_RECOVER": "sanitize.recover",
  102. "LOCAL_LOGTAGS_FILES": "logtags",
  103. "LOCAL_EXPORT_HEADER_LIBRARY_HEADERS": "export_header_lib_headers",
  104. "LOCAL_EXPORT_SHARED_LIBRARY_HEADERS": "export_shared_lib_headers",
  105. "LOCAL_EXPORT_STATIC_LIBRARY_HEADERS": "export_static_lib_headers",
  106. "LOCAL_INIT_RC": "init_rc",
  107. "LOCAL_TIDY_FLAGS": "tidy_flags",
  108. // TODO: This is comma-separated, not space-separated
  109. "LOCAL_TIDY_CHECKS": "tidy_checks",
  110. "LOCAL_RENDERSCRIPT_INCLUDES": "renderscript.include_dirs",
  111. "LOCAL_RENDERSCRIPT_FLAGS": "renderscript.flags",
  112. "LOCAL_JAVA_RESOURCE_DIRS": "java_resource_dirs",
  113. "LOCAL_JAVACFLAGS": "javacflags",
  114. "LOCAL_DX_FLAGS": "dxflags",
  115. "LOCAL_JAVA_LIBRARIES": "libs",
  116. "LOCAL_STATIC_JAVA_LIBRARIES": "static_libs",
  117. "LOCAL_AAPT_FLAGS": "aaptflags",
  118. "LOCAL_PACKAGE_SPLITS": "package_splits",
  119. "LOCAL_COMPATIBILITY_SUITE": "test_suites",
  120. "LOCAL_ANNOTATION_PROCESSORS": "annotation_processors",
  121. "LOCAL_ANNOTATION_PROCESSOR_CLASSES": "annotation_processor_classes",
  122. })
  123. addStandardProperties(bpparser.BoolType,
  124. map[string]string{
  125. // Bool properties
  126. "LOCAL_IS_HOST_MODULE": "host",
  127. "LOCAL_CLANG": "clang",
  128. "LOCAL_FORCE_STATIC_EXECUTABLE": "static_executable",
  129. "LOCAL_NATIVE_COVERAGE": "native_coverage",
  130. "LOCAL_NO_CRT": "nocrt",
  131. "LOCAL_ALLOW_UNDEFINED_SYMBOLS": "allow_undefined_symbols",
  132. "LOCAL_RTTI_FLAG": "rtti",
  133. "LOCAL_NO_STANDARD_LIBRARIES": "no_standard_libs",
  134. "LOCAL_PACK_MODULE_RELOCATIONS": "pack_relocations",
  135. "LOCAL_TIDY": "tidy",
  136. "LOCAL_PROPRIETARY_MODULE": "proprietary",
  137. "LOCAL_VENDOR_MODULE": "vendor",
  138. "LOCAL_EXPORT_PACKAGE_RESOURCES": "export_package_resources",
  139. "LOCAL_DEX_PREOPT": "dex_preopt",
  140. })
  141. }
  142. type listSplitFunc func(bpparser.Expression) (string, bpparser.Expression, error)
  143. func emptyList(value bpparser.Expression) bool {
  144. if list, ok := value.(*bpparser.List); ok {
  145. return len(list.Values) == 0
  146. }
  147. return false
  148. }
  149. func splitBpList(val bpparser.Expression, keyFunc listSplitFunc) (lists map[string]bpparser.Expression, err error) {
  150. lists = make(map[string]bpparser.Expression)
  151. switch val := val.(type) {
  152. case *bpparser.Operator:
  153. listsA, err := splitBpList(val.Args[0], keyFunc)
  154. if err != nil {
  155. return nil, err
  156. }
  157. listsB, err := splitBpList(val.Args[1], keyFunc)
  158. if err != nil {
  159. return nil, err
  160. }
  161. for k, v := range listsA {
  162. if !emptyList(v) {
  163. lists[k] = v
  164. }
  165. }
  166. for k, vB := range listsB {
  167. if emptyList(vB) {
  168. continue
  169. }
  170. if vA, ok := lists[k]; ok {
  171. expression := val.Copy().(*bpparser.Operator)
  172. expression.Args = [2]bpparser.Expression{vA, vB}
  173. lists[k] = expression
  174. } else {
  175. lists[k] = vB
  176. }
  177. }
  178. case *bpparser.Variable:
  179. key, value, err := keyFunc(val)
  180. if err != nil {
  181. return nil, err
  182. }
  183. if value.Type() == bpparser.ListType {
  184. lists[key] = value
  185. } else {
  186. lists[key] = &bpparser.List{
  187. Values: []bpparser.Expression{value},
  188. }
  189. }
  190. case *bpparser.List:
  191. for _, v := range val.Values {
  192. key, value, err := keyFunc(v)
  193. if err != nil {
  194. return nil, err
  195. }
  196. l := lists[key]
  197. if l == nil {
  198. l = &bpparser.List{}
  199. }
  200. l.(*bpparser.List).Values = append(l.(*bpparser.List).Values, value)
  201. lists[key] = l
  202. }
  203. default:
  204. panic(fmt.Errorf("unexpected type %t", val))
  205. }
  206. return lists, nil
  207. }
  208. // classifyLocalOrGlobalPath tells whether a file path should be interpreted relative to the current module (local)
  209. // or relative to the root of the source checkout (global)
  210. func classifyLocalOrGlobalPath(value bpparser.Expression) (string, bpparser.Expression, error) {
  211. switch v := value.(type) {
  212. case *bpparser.Variable:
  213. if v.Name == "LOCAL_PATH" {
  214. return "local", &bpparser.String{
  215. Value: ".",
  216. }, nil
  217. } else {
  218. // TODO: Should we split variables?
  219. return "global", value, nil
  220. }
  221. case *bpparser.Operator:
  222. if v.Type() != bpparser.StringType {
  223. return "", nil, fmt.Errorf("classifyLocalOrGlobalPath expected a string, got %s", value.Type)
  224. }
  225. if v.Operator != '+' {
  226. return "global", value, nil
  227. }
  228. firstOperand := v.Args[0]
  229. secondOperand := v.Args[1]
  230. if firstOperand.Type() != bpparser.StringType {
  231. return "global", value, nil
  232. }
  233. if _, ok := firstOperand.(*bpparser.Operator); ok {
  234. return "global", value, nil
  235. }
  236. if variable, ok := firstOperand.(*bpparser.Variable); !ok || variable.Name != "LOCAL_PATH" {
  237. return "global", value, nil
  238. }
  239. local := secondOperand
  240. if s, ok := secondOperand.(*bpparser.String); ok {
  241. if strings.HasPrefix(s.Value, "/") {
  242. s.Value = s.Value[1:]
  243. }
  244. }
  245. return "local", local, nil
  246. case *bpparser.String:
  247. return "global", value, nil
  248. default:
  249. return "", nil, fmt.Errorf("classifyLocalOrGlobalPath expected a string, got %s", value.Type)
  250. }
  251. }
  252. func sortedMapKeys(inputMap map[string]string) (sortedKeys []string) {
  253. keys := make([]string, 0, len(inputMap))
  254. for key := range inputMap {
  255. keys = append(keys, key)
  256. }
  257. sort.Strings(keys)
  258. return keys
  259. }
  260. // splitAndAssign splits a Make list into components and then
  261. // creates the corresponding variable assignments.
  262. func splitAndAssign(ctx variableAssignmentContext, splitFunc listSplitFunc, namesByClassification map[string]string) error {
  263. val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
  264. if err != nil {
  265. return err
  266. }
  267. lists, err := splitBpList(val, splitFunc)
  268. if err != nil {
  269. return err
  270. }
  271. for _, nameClassification := range sortedMapKeys(namesByClassification) {
  272. name := namesByClassification[nameClassification]
  273. if component, ok := lists[nameClassification]; ok && !emptyList(component) {
  274. err = setVariable(ctx.file, ctx.append, ctx.prefix, name, component, true)
  275. if err != nil {
  276. return err
  277. }
  278. }
  279. }
  280. return nil
  281. }
  282. func localIncludeDirs(ctx variableAssignmentContext) error {
  283. return splitAndAssign(ctx, classifyLocalOrGlobalPath, map[string]string{"global": "include_dirs", "local": "local_include_dirs"})
  284. }
  285. func exportIncludeDirs(ctx variableAssignmentContext) error {
  286. // Add any paths that could not be converted to local relative paths to export_include_dirs
  287. // anyways, they will cause an error if they don't exist and can be fixed manually.
  288. return splitAndAssign(ctx, classifyLocalOrGlobalPath, map[string]string{"global": "export_include_dirs", "local": "export_include_dirs"})
  289. }
  290. func localAidlIncludes(ctx variableAssignmentContext) error {
  291. return splitAndAssign(ctx, classifyLocalOrGlobalPath, map[string]string{"global": "aidl.include_dirs", "local": "aidl.local_include_dirs"})
  292. }
  293. func stem(ctx variableAssignmentContext) error {
  294. val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.StringType)
  295. if err != nil {
  296. return err
  297. }
  298. varName := "stem"
  299. if exp, ok := val.(*bpparser.Operator); ok && exp.Operator == '+' {
  300. if variable, ok := exp.Args[0].(*bpparser.Variable); ok && variable.Name == "LOCAL_MODULE" {
  301. varName = "suffix"
  302. val = exp.Args[1]
  303. }
  304. }
  305. return setVariable(ctx.file, ctx.append, ctx.prefix, varName, val, true)
  306. }
  307. func hostOs(ctx variableAssignmentContext) error {
  308. val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
  309. if err != nil {
  310. return err
  311. }
  312. inList := func(s string) bool {
  313. for _, v := range val.(*bpparser.List).Values {
  314. if v.(*bpparser.String).Value == s {
  315. return true
  316. }
  317. }
  318. return false
  319. }
  320. falseValue := &bpparser.Bool{
  321. Value: false,
  322. }
  323. trueValue := &bpparser.Bool{
  324. Value: true,
  325. }
  326. if inList("windows") {
  327. err = setVariable(ctx.file, ctx.append, "target.windows", "enabled", trueValue, true)
  328. }
  329. if !inList("linux") && err == nil {
  330. err = setVariable(ctx.file, ctx.append, "target.linux_glibc", "enabled", falseValue, true)
  331. }
  332. if !inList("darwin") && err == nil {
  333. err = setVariable(ctx.file, ctx.append, "target.darwin", "enabled", falseValue, true)
  334. }
  335. return err
  336. }
  337. func splitSrcsLogtags(value bpparser.Expression) (string, bpparser.Expression, error) {
  338. switch v := value.(type) {
  339. case *bpparser.Variable:
  340. // TODO: attempt to split variables?
  341. return "srcs", value, nil
  342. case *bpparser.Operator:
  343. // TODO: attempt to handle expressions?
  344. return "srcs", value, nil
  345. case *bpparser.String:
  346. if strings.HasSuffix(v.Value, ".logtags") {
  347. return "logtags", value, nil
  348. }
  349. return "srcs", value, nil
  350. default:
  351. return "", nil, fmt.Errorf("splitSrcsLogtags expected a string, got %s", value.Type())
  352. }
  353. }
  354. func srcFiles(ctx variableAssignmentContext) error {
  355. val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
  356. if err != nil {
  357. return err
  358. }
  359. lists, err := splitBpList(val, splitSrcsLogtags)
  360. if srcs, ok := lists["srcs"]; ok && !emptyList(srcs) {
  361. err = setVariable(ctx.file, ctx.append, ctx.prefix, "srcs", srcs, true)
  362. if err != nil {
  363. return err
  364. }
  365. }
  366. if logtags, ok := lists["logtags"]; ok && !emptyList(logtags) {
  367. err = setVariable(ctx.file, true, ctx.prefix, "logtags", logtags, true)
  368. if err != nil {
  369. return err
  370. }
  371. }
  372. return nil
  373. }
  374. func sanitize(sub string) func(ctx variableAssignmentContext) error {
  375. return func(ctx variableAssignmentContext) error {
  376. val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
  377. if err != nil {
  378. return err
  379. }
  380. if _, ok := val.(*bpparser.List); !ok {
  381. return fmt.Errorf("unsupported sanitize expression")
  382. }
  383. misc := &bpparser.List{}
  384. for _, v := range val.(*bpparser.List).Values {
  385. switch v := v.(type) {
  386. case *bpparser.Variable, *bpparser.Operator:
  387. ctx.file.errorf(ctx.mkvalue, "unsupported sanitize expression")
  388. case *bpparser.String:
  389. switch v.Value {
  390. case "never", "address", "coverage", "thread", "undefined", "cfi":
  391. bpTrue := &bpparser.Bool{
  392. Value: true,
  393. }
  394. err = setVariable(ctx.file, false, ctx.prefix, "sanitize."+sub+v.Value, bpTrue, true)
  395. if err != nil {
  396. return err
  397. }
  398. default:
  399. misc.Values = append(misc.Values, v)
  400. }
  401. default:
  402. return fmt.Errorf("sanitize expected a string, got %s", v.Type())
  403. }
  404. }
  405. if len(misc.Values) > 0 {
  406. err = setVariable(ctx.file, false, ctx.prefix, "sanitize."+sub+"misc_undefined", misc, true)
  407. if err != nil {
  408. return err
  409. }
  410. }
  411. return err
  412. }
  413. }
  414. func prebuiltClass(ctx variableAssignmentContext) error {
  415. class := ctx.mkvalue.Value(ctx.file.scope)
  416. if v, ok := prebuiltTypes[class]; ok {
  417. ctx.file.scope.Set("BUILD_PREBUILT", v)
  418. } else {
  419. // reset to default
  420. ctx.file.scope.Set("BUILD_PREBUILT", "prebuilt")
  421. }
  422. return nil
  423. }
  424. func ldflags(ctx variableAssignmentContext) error {
  425. val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.ListType)
  426. if err != nil {
  427. return err
  428. }
  429. lists, err := splitBpList(val, func(value bpparser.Expression) (string, bpparser.Expression, error) {
  430. // Anything other than "-Wl,--version_script," + LOCAL_PATH + "<path>" matches ldflags
  431. exp1, ok := value.(*bpparser.Operator)
  432. if !ok {
  433. return "ldflags", value, nil
  434. }
  435. exp2, ok := exp1.Args[0].(*bpparser.Operator)
  436. if !ok {
  437. return "ldflags", value, nil
  438. }
  439. if s, ok := exp2.Args[0].(*bpparser.String); !ok || s.Value != "-Wl,--version-script," {
  440. return "ldflags", value, nil
  441. }
  442. if v, ok := exp2.Args[1].(*bpparser.Variable); !ok || v.Name != "LOCAL_PATH" {
  443. ctx.file.errorf(ctx.mkvalue, "Unrecognized version-script")
  444. return "ldflags", value, nil
  445. }
  446. s, ok := exp1.Args[1].(*bpparser.String)
  447. if !ok {
  448. ctx.file.errorf(ctx.mkvalue, "Unrecognized version-script")
  449. return "ldflags", value, nil
  450. }
  451. s.Value = strings.TrimPrefix(s.Value, "/")
  452. return "version", s, nil
  453. })
  454. if err != nil {
  455. return err
  456. }
  457. if ldflags, ok := lists["ldflags"]; ok && !emptyList(ldflags) {
  458. err = setVariable(ctx.file, ctx.append, ctx.prefix, "ldflags", ldflags, true)
  459. if err != nil {
  460. return err
  461. }
  462. }
  463. if version_script, ok := lists["version"]; ok && !emptyList(version_script) {
  464. if len(version_script.(*bpparser.List).Values) > 1 {
  465. ctx.file.errorf(ctx.mkvalue, "multiple version scripts found?")
  466. }
  467. err = setVariable(ctx.file, false, ctx.prefix, "version_script", version_script.(*bpparser.List).Values[0], true)
  468. if err != nil {
  469. return err
  470. }
  471. }
  472. return nil
  473. }
  474. func cflags(ctx variableAssignmentContext) error {
  475. // The Soong replacement for CFLAGS doesn't need the same extra escaped quotes that were present in Make
  476. ctx.mkvalue = ctx.mkvalue.Clone()
  477. ctx.mkvalue.ReplaceLiteral(`\"`, `"`)
  478. return includeVariableNow(bpVariable{"cflags", bpparser.ListType}, ctx)
  479. }
  480. func invert(name string) func(ctx variableAssignmentContext) error {
  481. return func(ctx variableAssignmentContext) error {
  482. val, err := makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpparser.BoolType)
  483. if err != nil {
  484. return err
  485. }
  486. val.(*bpparser.Bool).Value = !val.(*bpparser.Bool).Value
  487. return setVariable(ctx.file, ctx.append, ctx.prefix, name, val, true)
  488. }
  489. }
  490. // given a conditional, returns a function that will insert a variable assignment or not, based on the conditional
  491. func includeVariableIf(bpVar bpVariable, conditional func(ctx variableAssignmentContext) bool) func(ctx variableAssignmentContext) error {
  492. return func(ctx variableAssignmentContext) error {
  493. var err error
  494. if conditional(ctx) {
  495. err = includeVariableNow(bpVar, ctx)
  496. }
  497. return err
  498. }
  499. }
  500. // given a variable, returns a function that will always insert a variable assignment
  501. func includeVariable(bpVar bpVariable) func(ctx variableAssignmentContext) error {
  502. return includeVariableIf(bpVar, always)
  503. }
  504. func includeVariableNow(bpVar bpVariable, ctx variableAssignmentContext) error {
  505. var val bpparser.Expression
  506. var err error
  507. val, err = makeVariableToBlueprint(ctx.file, ctx.mkvalue, bpVar.variableType)
  508. if err == nil {
  509. err = setVariable(ctx.file, ctx.append, ctx.prefix, bpVar.name, val, true)
  510. }
  511. return err
  512. }
  513. // given a function that returns a bool, returns a function that returns the opposite
  514. func not(conditional func(ctx variableAssignmentContext) bool) func(ctx variableAssignmentContext) bool {
  515. return func(ctx variableAssignmentContext) bool {
  516. return !conditional(ctx)
  517. }
  518. }
  519. // returns a function that tells whether mkvalue.Dump equals the given query string
  520. func valueDumpEquals(textToMatch string) func(ctx variableAssignmentContext) bool {
  521. return func(ctx variableAssignmentContext) bool {
  522. return (ctx.mkvalue.Dump() == textToMatch)
  523. }
  524. }
  525. func always(ctx variableAssignmentContext) bool {
  526. return true
  527. }
  528. func skip(ctx variableAssignmentContext) error {
  529. return nil
  530. }
  531. // Shorter suffixes of other suffixes must be at the end of the list
  532. var propertyPrefixes = []struct{ mk, bp string }{
  533. {"arm", "arch.arm"},
  534. {"arm64", "arch.arm64"},
  535. {"mips", "arch.mips"},
  536. {"mips64", "arch.mips64"},
  537. {"x86", "arch.x86"},
  538. {"x86_64", "arch.x86_64"},
  539. {"32", "multilib.lib32"},
  540. // 64 must be after x86_64
  541. {"64", "multilib.lib64"},
  542. {"darwin", "target.darwin"},
  543. {"linux", "target.linux_glibc"},
  544. {"windows", "target.windows"},
  545. }
  546. var conditionalTranslations = map[string]map[bool]string{
  547. "($(HOST_OS),darwin)": {
  548. true: "target.darwin",
  549. false: "target.not_darwin"},
  550. "($(HOST_OS), darwin)": {
  551. true: "target.darwin",
  552. false: "target.not_darwin"},
  553. "($(HOST_OS),windows)": {
  554. true: "target.windows",
  555. false: "target.not_windows"},
  556. "($(HOST_OS), windows)": {
  557. true: "target.windows",
  558. false: "target.not_windows"},
  559. "($(HOST_OS),linux)": {
  560. true: "target.linux_glibc",
  561. false: "target.not_linux_glibc"},
  562. "($(HOST_OS), linux)": {
  563. true: "target.linux_glibc",
  564. false: "target.not_linux_glibc"},
  565. "($(BUILD_OS),darwin)": {
  566. true: "target.darwin",
  567. false: "target.not_darwin"},
  568. "($(BUILD_OS), darwin)": {
  569. true: "target.darwin",
  570. false: "target.not_darwin"},
  571. "($(BUILD_OS),linux)": {
  572. true: "target.linux_glibc",
  573. false: "target.not_linux_glibc"},
  574. "($(BUILD_OS), linux)": {
  575. true: "target.linux_glibc",
  576. false: "target.not_linux_glibc"},
  577. "(,$(TARGET_BUILD_APPS))": {
  578. false: "product_variables.unbundled_build"},
  579. "($(TARGET_BUILD_PDK),true)": {
  580. true: "product_variables.pdk"},
  581. "($(TARGET_BUILD_PDK), true)": {
  582. true: "product_variables.pdk"},
  583. }
  584. func mydir(args []string) string {
  585. return "."
  586. }
  587. func allJavaFilesUnder(args []string) string {
  588. dir := ""
  589. if len(args) > 0 {
  590. dir = strings.TrimSpace(args[0])
  591. }
  592. return fmt.Sprintf("%s/**/*.java", dir)
  593. }
  594. func allProtoFilesUnder(args []string) string {
  595. dir := ""
  596. if len(args) > 0 {
  597. dir = strings.TrimSpace(args[0])
  598. }
  599. return fmt.Sprintf("%s/**/*.proto", dir)
  600. }
  601. func allSubdirJavaFiles(args []string) string {
  602. return "**/*.java"
  603. }
  604. var moduleTypes = map[string]string{
  605. "BUILD_SHARED_LIBRARY": "cc_library_shared",
  606. "BUILD_STATIC_LIBRARY": "cc_library_static",
  607. "BUILD_HOST_SHARED_LIBRARY": "cc_library_host_shared",
  608. "BUILD_HOST_STATIC_LIBRARY": "cc_library_host_static",
  609. "BUILD_HEADER_LIBRARY": "cc_library_headers",
  610. "BUILD_EXECUTABLE": "cc_binary",
  611. "BUILD_HOST_EXECUTABLE": "cc_binary_host",
  612. "BUILD_NATIVE_TEST": "cc_test",
  613. "BUILD_HOST_NATIVE_TEST": "cc_test_host",
  614. "BUILD_NATIVE_BENCHMARK": "cc_benchmark",
  615. "BUILD_HOST_NATIVE_BENCHMARK": "cc_benchmark_host",
  616. "BUILD_JAVA_LIBRARY": "java_library",
  617. "BUILD_STATIC_JAVA_LIBRARY": "java_library_static",
  618. "BUILD_HOST_JAVA_LIBRARY": "java_library_host",
  619. "BUILD_HOST_DALVIK_JAVA_LIBRARY": "java_library_host_dalvik",
  620. "BUILD_PACKAGE": "android_app",
  621. }
  622. var prebuiltTypes = map[string]string{
  623. "SHARED_LIBRARIES": "cc_prebuilt_library_shared",
  624. "STATIC_LIBRARIES": "cc_prebuilt_library_static",
  625. "EXECUTABLES": "cc_prebuilt_binary",
  626. "JAVA_LIBRARIES": "java_import",
  627. }
  628. var soongModuleTypes = map[string]bool{}
  629. func androidScope() mkparser.Scope {
  630. globalScope := mkparser.NewScope(nil)
  631. globalScope.Set("CLEAR_VARS", clear_vars)
  632. globalScope.SetFunc("my-dir", mydir)
  633. globalScope.SetFunc("all-java-files-under", allJavaFilesUnder)
  634. globalScope.SetFunc("all-proto-files-under", allProtoFilesUnder)
  635. globalScope.SetFunc("all-subdir-java-files", allSubdirJavaFiles)
  636. for k, v := range moduleTypes {
  637. globalScope.Set(k, v)
  638. soongModuleTypes[v] = true
  639. }
  640. for _, v := range prebuiltTypes {
  641. soongModuleTypes[v] = true
  642. }
  643. return globalScope
  644. }