Home | History | Annotate | Download | only in androidmk
      1 // Copyright 2016 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 
     15 package main
     16 
     17 import (
     18 	"bytes"
     19 	"fmt"
     20 	"strings"
     21 	"testing"
     22 
     23 	"android/soong/bpfix/bpfix"
     24 )
     25 
     26 var testCases = []struct {
     27 	desc     string
     28 	in       string
     29 	expected string
     30 }{
     31 	{
     32 		desc: "basic cc_library_shared with comments",
     33 		in: `
     34 #
     35 # Copyright
     36 #
     37 
     38 # Module Comment
     39 include $(CLEAR_VARS)
     40 # Name Comment
     41 LOCAL_MODULE := test
     42 # Source comment
     43 LOCAL_SRC_FILES_EXCLUDE := a.c
     44 # Second source comment
     45 LOCAL_SRC_FILES_EXCLUDE += b.c
     46 include $(BUILD_SHARED_LIBRARY)`,
     47 		expected: `
     48 //
     49 // Copyright
     50 //
     51 
     52 // Module Comment
     53 cc_library_shared {
     54     // Name Comment
     55     name: "test",
     56     // Source comment
     57     exclude_srcs: ["a.c"] + ["b.c"], // Second source comment
     58 
     59 }`,
     60 	},
     61 	{
     62 		desc: "split local/global include_dirs (1)",
     63 		in: `
     64 include $(CLEAR_VARS)
     65 LOCAL_C_INCLUDES := $(LOCAL_PATH)
     66 include $(BUILD_SHARED_LIBRARY)`,
     67 		expected: `
     68 cc_library_shared {
     69     local_include_dirs: ["."],
     70 }`,
     71 	},
     72 	{
     73 		desc: "split local/global include_dirs (2)",
     74 		in: `
     75 include $(CLEAR_VARS)
     76 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
     77 include $(BUILD_SHARED_LIBRARY)`,
     78 		expected: `
     79 cc_library_shared {
     80     local_include_dirs: ["include"],
     81 }`,
     82 	},
     83 	{
     84 		desc: "split local/global include_dirs (3)",
     85 		in: `
     86 include $(CLEAR_VARS)
     87 LOCAL_C_INCLUDES := system/core/include
     88 include $(BUILD_SHARED_LIBRARY)`,
     89 		expected: `
     90 cc_library_shared {
     91     include_dirs: ["system/core/include"],
     92 }`,
     93 	},
     94 	{
     95 		desc: "split local/global include_dirs (4)",
     96 		in: `
     97 input := testing/include
     98 include $(CLEAR_VARS)
     99 # Comment 1
    100 LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include system/core/include $(input)
    101 # Comment 2
    102 LOCAL_C_INCLUDES += $(TOP)/system/core/include $(LOCAL_PATH)/test/include
    103 # Comment 3
    104 include $(BUILD_SHARED_LIBRARY)`,
    105 		expected: `
    106 input = ["testing/include"]
    107 cc_library_shared {
    108     // Comment 1
    109     include_dirs: ["system/core/include"] + input + ["system/core/include"], // Comment 2
    110     local_include_dirs: ["."] + ["include"] + ["test/include"],
    111     // Comment 3
    112 }`,
    113 	},
    114 	{
    115 		desc: "LOCAL_MODULE_STEM",
    116 		in: `
    117 include $(CLEAR_VARS)
    118 LOCAL_MODULE := libtest
    119 LOCAL_MODULE_STEM := $(LOCAL_MODULE).so
    120 include $(BUILD_SHARED_LIBRARY)
    121 
    122 include $(CLEAR_VARS)
    123 LOCAL_MODULE := libtest2
    124 LOCAL_MODULE_STEM := testing.so
    125 include $(BUILD_SHARED_LIBRARY)
    126 `,
    127 		expected: `
    128 cc_library_shared {
    129     name: "libtest",
    130     suffix: ".so",
    131 }
    132 
    133 cc_library_shared {
    134     name: "libtest2",
    135     stem: "testing.so",
    136 }
    137 `,
    138 	},
    139 	{
    140 		desc: "LOCAL_MODULE_HOST_OS",
    141 		in: `
    142 include $(CLEAR_VARS)
    143 LOCAL_MODULE := libtest
    144 LOCAL_MODULE_HOST_OS := linux darwin windows
    145 include $(BUILD_SHARED_LIBRARY)
    146 
    147 include $(CLEAR_VARS)
    148 LOCAL_MODULE := libtest2
    149 LOCAL_MODULE_HOST_OS := linux
    150 include $(BUILD_SHARED_LIBRARY)
    151 `,
    152 		expected: `
    153 cc_library_shared {
    154     name: "libtest",
    155     target: {
    156         windows: {
    157             enabled: true,
    158         }
    159     }
    160 }
    161 
    162 cc_library_shared {
    163     name: "libtest2",
    164     target: {
    165         darwin: {
    166             enabled: false,
    167         }
    168     }
    169 }
    170 `,
    171 	},
    172 	{
    173 		desc: "LOCAL_RTTI_VALUE",
    174 		in: `
    175 include $(CLEAR_VARS)
    176 LOCAL_MODULE := libtest
    177 LOCAL_RTTI_FLAG := # Empty flag
    178 include $(BUILD_SHARED_LIBRARY)
    179 
    180 include $(CLEAR_VARS)
    181 LOCAL_MODULE := libtest2
    182 LOCAL_RTTI_FLAG := -frtti
    183 include $(BUILD_SHARED_LIBRARY)
    184 `,
    185 		expected: `
    186 cc_library_shared {
    187     name: "libtest",
    188     rtti: false, // Empty flag
    189 }
    190 
    191 cc_library_shared {
    192     name: "libtest2",
    193     rtti: true,
    194 }
    195 `,
    196 	},
    197 	{
    198 		desc: "LOCAL_ARM_MODE",
    199 		in: `
    200 include $(CLEAR_VARS)
    201 LOCAL_ARM_MODE := arm
    202 include $(BUILD_SHARED_LIBRARY)
    203 `,
    204 		expected: `
    205 cc_library_shared {
    206     arch: {
    207         arm: {
    208             instruction_set: "arm",
    209         },
    210     },
    211 }
    212 `,
    213 	},
    214 	{
    215 		desc: "_<OS> suffixes",
    216 		in: `
    217 include $(CLEAR_VARS)
    218 LOCAL_SRC_FILES_darwin := darwin.c
    219 LOCAL_SRC_FILES_linux := linux.c
    220 LOCAL_SRC_FILES_windows := windows.c
    221 include $(BUILD_SHARED_LIBRARY)
    222 `,
    223 		expected: `
    224 cc_library_shared {
    225     target: {
    226         darwin: {
    227             srcs: ["darwin.c"],
    228         },
    229         linux_glibc: {
    230             srcs: ["linux.c"],
    231         },
    232         windows: {
    233             srcs: ["windows.c"],
    234         },
    235     },
    236 }
    237 `,
    238 	},
    239 	{
    240 		desc: "LOCAL_SANITIZE := never",
    241 		in: `
    242 include $(CLEAR_VARS)
    243 LOCAL_SANITIZE := never
    244 include $(BUILD_SHARED_LIBRARY)
    245 `,
    246 		expected: `
    247 cc_library_shared {
    248     sanitize: {
    249         never: true,
    250     },
    251 }
    252 `,
    253 	},
    254 	{
    255 		desc: "LOCAL_SANITIZE unknown parameter",
    256 		in: `
    257 include $(CLEAR_VARS)
    258 LOCAL_SANITIZE := thread cfi asdf
    259 LOCAL_SANITIZE_DIAG := cfi
    260 LOCAL_SANITIZE_RECOVER := qwert
    261 include $(BUILD_SHARED_LIBRARY)
    262 `,
    263 		expected: `
    264 cc_library_shared {
    265     sanitize: {
    266         thread: true,
    267         cfi: true,
    268         misc_undefined: ["asdf"],
    269         diag: {
    270             cfi: true,
    271         },
    272         recover: ["qwert"],
    273     },
    274 }
    275 `,
    276 	},
    277 	{
    278 		desc: "LOCAL_SANITIZE_RECOVER",
    279 		in: `
    280 include $(CLEAR_VARS)
    281 LOCAL_SANITIZE_RECOVER := shift-exponent
    282 include $(BUILD_SHARED_LIBRARY)
    283 `,
    284 		expected: `
    285 cc_library_shared {
    286     sanitize: {
    287 	recover: ["shift-exponent"],
    288     },
    289 }
    290 `,
    291 	},
    292 	{
    293 		desc: "version_script in LOCAL_LDFLAGS",
    294 		in: `
    295 include $(CLEAR_VARS)
    296 LOCAL_LDFLAGS := -Wl,--link-opt -Wl,--version-script,$(LOCAL_PATH)/exported32.map
    297 include $(BUILD_SHARED_LIBRARY)
    298 `,
    299 		expected: `
    300 cc_library_shared {
    301     ldflags: ["-Wl,--link-opt"],
    302     version_script: "exported32.map",
    303 }
    304 `,
    305 	},
    306 	{
    307 		desc: "Handle TOP",
    308 		in: `
    309 include $(CLEAR_VARS)
    310 LOCAL_C_INCLUDES := $(TOP)/system/core/include $(TOP)
    311 include $(BUILD_SHARED_LIBRARY)
    312 `,
    313 		expected: `
    314 cc_library_shared {
    315 	include_dirs: ["system/core/include", "."],
    316 }
    317 `,
    318 	},
    319 	{
    320 		desc: "Remove LOCAL_MODULE_TAGS optional",
    321 		in: `
    322 include $(CLEAR_VARS)
    323 LOCAL_MODULE_TAGS := optional
    324 include $(BUILD_SHARED_LIBRARY)
    325 `,
    326 
    327 		expected: `
    328 cc_library_shared {
    329 
    330 }
    331 `,
    332 	},
    333 	{
    334 		desc: "Keep LOCAL_MODULE_TAGS non-optional",
    335 		in: `
    336 include $(CLEAR_VARS)
    337 LOCAL_MODULE_TAGS := debug
    338 include $(BUILD_SHARED_LIBRARY)
    339 `,
    340 
    341 		expected: `
    342 cc_library_shared {
    343 	tags: ["debug"],
    344 }
    345 `,
    346 	},
    347 
    348 	{
    349 		desc: "Input containing escaped quotes",
    350 		in: `
    351 include $(CLEAR_VARS)
    352 LOCAL_MODULE:= libsensorservice
    353 LOCAL_CFLAGS:= -DLOG_TAG=\"-DDontEscapeMe\"
    354 LOCAL_SRC_FILES := \"EscapeMe.cc\"
    355 include $(BUILD_SHARED_LIBRARY)
    356 `,
    357 
    358 		expected: `
    359 cc_library_shared {
    360     name: "libsensorservice",
    361     cflags: ["-DLOG_TAG=\"-DDontEscapeMe\""],
    362     srcs: ["\\\"EscapeMe.cc\\\""],
    363 }
    364 `,
    365 	},
    366 	{
    367 
    368 		desc: "Don't fail on missing CLEAR_VARS",
    369 		in: `
    370 LOCAL_MODULE := iAmAModule
    371 include $(BUILD_SHARED_LIBRARY)`,
    372 
    373 		expected: `
    374 // ANDROIDMK TRANSLATION WARNING: No 'include $(CLEAR_VARS)' detected before first assignment; clearing vars now
    375 cc_library_shared {
    376   name: "iAmAModule",
    377 
    378 }`,
    379 	},
    380 	{
    381 
    382 		desc: "LOCAL_AIDL_INCLUDES",
    383 		in: `
    384 include $(CLEAR_VARS)
    385 LOCAL_MODULE := iAmAModule
    386 LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/main/java system/core
    387 include $(BUILD_SHARED_LIBRARY)`,
    388 
    389 		expected: `
    390 cc_library_shared {
    391   name: "iAmAModule",
    392   aidl: {
    393     include_dirs: ["system/core"],
    394     local_include_dirs: ["src/main/java"],
    395   }
    396 }`,
    397 	},
    398 	{
    399 		// the important part of this test case is that it confirms that androidmk doesn't
    400 		// panic in this case
    401 		desc: "multiple directives inside recipe",
    402 		in: `
    403 ifeq ($(a),true)
    404 ifeq ($(b),false)
    405 imABuildStatement: somefile
    406 	echo begin
    407 endif # a==true
    408 	echo middle
    409 endif # b==false
    410 	echo end
    411 `,
    412 		expected: `
    413 // ANDROIDMK TRANSLATION ERROR: unsupported conditional
    414 // ifeq ($(a),true)
    415 
    416 // ANDROIDMK TRANSLATION ERROR: unsupported conditional
    417 // ifeq ($(b),false)
    418 
    419 // ANDROIDMK TRANSLATION ERROR: unsupported line
    420 // rule:       imABuildStatement: somefile
    421 // echo begin
    422 //  # a==true
    423 // echo middle
    424 //  # b==false
    425 // echo end
    426 //
    427 // ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
    428 // endif
    429 // ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
    430 // endif
    431 		`,
    432 	},
    433 	{
    434 		desc: "ignore all-makefiles-under",
    435 		in: `
    436 include $(call all-makefiles-under,$(LOCAL_PATH))
    437 `,
    438 		expected: ``,
    439 	},
    440 	{
    441 		desc: "proguard options for java library",
    442 		in: `
    443 			include $(CLEAR_VARS)
    444 			# Empty
    445 			LOCAL_PROGUARD_ENABLED :=
    446 			# Disabled
    447 			LOCAL_PROGUARD_ENABLED := disabled
    448 			# Full
    449 			LOCAL_PROGUARD_ENABLED := full
    450 			# Obfuscation and optimization
    451 			LOCAL_PROGUARD_ENABLED := obfuscation optimization
    452 			# Custom
    453 			LOCAL_PROGUARD_ENABLED := custom
    454 			include $(BUILD_JAVA_LIBRARY)
    455 		`,
    456 		expected: `
    457 			java_library {
    458 				// Empty
    459 
    460 				// Disabled
    461 				optimize: {
    462 					enabled: false,
    463 					// Full
    464 					enabled: true,
    465 					// Obfuscation and optimization
    466 					obfuscate: true,
    467 					optimize: true,
    468 					enabled: true,
    469 					// Custom
    470 					no_aapt_flags: true,
    471 					enabled: true,
    472 				},
    473 			}
    474 		`,
    475 	},
    476 	{
    477 		desc: "errorprone options for java library",
    478 		in: `
    479 			include $(CLEAR_VARS)
    480 			LOCAL_ERROR_PRONE_FLAGS := -Xep:AsyncCallableReturnsNull:ERROR -Xep:AsyncFunctionReturnsNull:ERROR
    481 			include $(BUILD_JAVA_LIBRARY)
    482 		`,
    483 		expected: `
    484 			java_library {
    485 				errorprone: {
    486 					javacflags: [
    487 						"-Xep:AsyncCallableReturnsNull:ERROR",
    488 						"-Xep:AsyncFunctionReturnsNull:ERROR",
    489 					],
    490 				},
    491 			}
    492 		`,
    493 	},
    494 	{
    495 		desc: "java prebuilt",
    496 		in: `
    497 			include $(CLEAR_VARS)
    498 			LOCAL_SRC_FILES := test.jar
    499 			LOCAL_MODULE_CLASS := JAVA_LIBRARIES
    500 			LOCAL_STATIC_ANDROID_LIBRARIES :=
    501 			include $(BUILD_PREBUILT)
    502 		`,
    503 		expected: `
    504 			java_import {
    505 				jars: ["test.jar"],
    506 
    507 			}
    508 		`,
    509 	},
    510 	{
    511 		desc: "aar prebuilt",
    512 		in: `
    513 			include $(CLEAR_VARS)
    514 			LOCAL_SRC_FILES := test.aar
    515 			LOCAL_MODULE_CLASS := JAVA_LIBRARIES
    516 			include $(BUILD_PREBUILT)
    517 		`,
    518 		expected: `
    519 			android_library_import {
    520 				aars: ["test.aar"],
    521 
    522 			}
    523 		`,
    524 	},
    525 
    526 	{
    527 		desc: "aar",
    528 		in: `
    529 			include $(CLEAR_VARS)
    530 			LOCAL_SRC_FILES := test.java
    531 			LOCAL_RESOURCE_DIR := res
    532 			include $(BUILD_STATIC_JAVA_LIBRARY)
    533 
    534 			include $(CLEAR_VARS)
    535 			LOCAL_SRC_FILES := test.java
    536 			LOCAL_STATIC_LIBRARIES := foo
    537 			LOCAL_STATIC_ANDROID_LIBRARIES := bar
    538 			include $(BUILD_STATIC_JAVA_LIBRARY)
    539 
    540 			include $(CLEAR_VARS)
    541 			LOCAL_SRC_FILES := test.java
    542 			LOCAL_SHARED_LIBRARIES := foo
    543 			LOCAL_SHARED_ANDROID_LIBRARIES := bar
    544 			include $(BUILD_STATIC_JAVA_LIBRARY)
    545 
    546 			include $(CLEAR_VARS)
    547 			LOCAL_SRC_FILES := test.java
    548 			LOCAL_STATIC_ANDROID_LIBRARIES :=
    549 			include $(BUILD_STATIC_JAVA_LIBRARY)
    550 		`,
    551 		expected: `
    552 			android_library {
    553 				srcs: ["test.java"],
    554 				resource_dirs: ["res"],
    555 			}
    556 
    557 			android_library {
    558 				srcs: ["test.java"],
    559 				static_libs: [
    560 					"foo",
    561 					"bar",
    562 				],
    563 			}
    564 
    565 			android_library {
    566 				srcs: ["test.java"],
    567 				libs: [
    568 					"foo",
    569 					"bar",
    570 				],
    571 			}
    572 
    573 			java_library_static {
    574 				srcs: ["test.java"],
    575 				static_libs: [],
    576 			}
    577 		`,
    578 	},
    579 	{
    580 		desc: "cc_library shared_libs",
    581 		in: `
    582 			include $(CLEAR_VARS)
    583 			LOCAL_SHARED_LIBRARIES := libfoo
    584 			include $(BUILD_SHARED_LIBRARY)
    585 		`,
    586 		expected: `
    587 			cc_library_shared {
    588 				shared_libs: ["libfoo"],
    589 			}
    590 		`,
    591 	},
    592 }
    593 
    594 func TestEndToEnd(t *testing.T) {
    595 	for i, test := range testCases {
    596 		expected, err := bpfix.Reformat(test.expected)
    597 		if err != nil {
    598 			t.Error(err)
    599 		}
    600 
    601 		got, errs := convertFile(fmt.Sprintf("<testcase %d>", i), bytes.NewBufferString(test.in))
    602 		if len(errs) > 0 {
    603 			t.Errorf("Unexpected errors: %q", errs)
    604 			continue
    605 		}
    606 
    607 		if got != expected {
    608 			t.Errorf("failed testcase '%s'\ninput:\n%s\n\nexpected:\n%s\ngot:\n%s\n", test.desc, strings.TrimSpace(test.in), expected, got)
    609 		}
    610 	}
    611 }
    612