Files
build_soong/androidmk/cmd/androidmk/androidmk_test.go
Colin Cross 5beccee92c Split logtags implementations for cc and java
Logtags files in cc and java are treated fundamentally differently.
In cc, they are not used for compiling at all, but need to be passed
to Make to be combined into the global logtags list, and logtag files
are listed in a logtags property.  In java they are listed in srcs
and produce generated code that is compiled in, and so shouldn't
also need to be listed in a logtags property.

Move the logtags property to cc and export it to Make from there,
and have java extract logtags files from srcs to be exported to
Make.

Test: m checkbuild
Change-Id: I31d49289efe72db60d2f33566df771b4a3ebc8a0
2017-12-07 15:32:30 -08:00

475 lines
9.1 KiB
Go

// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"bytes"
"fmt"
"os"
"strings"
"testing"
bpparser "github.com/google/blueprint/parser"
)
var testCases = []struct {
desc string
in string
expected string
}{
{
desc: "basic cc_library_shared with comments",
in: `
#
# Copyright
#
# Module Comment
include $(CLEAR_VARS)
# Name Comment
LOCAL_MODULE := test
# Source comment
LOCAL_SRC_FILES_EXCLUDE := a.c
# Second source comment
LOCAL_SRC_FILES_EXCLUDE += b.c
include $(BUILD_SHARED_LIBRARY)`,
expected: `
//
// Copyright
//
// Module Comment
cc_library_shared {
// Name Comment
name: "test",
// Source comment
exclude_srcs: ["a.c"] + ["b.c"], // Second source comment
}`,
},
{
desc: "split local/global include_dirs (1)",
in: `
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)`,
expected: `
cc_library_shared {
local_include_dirs: ["."],
}`,
},
{
desc: "split local/global include_dirs (2)",
in: `
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)`,
expected: `
cc_library_shared {
local_include_dirs: ["include"],
}`,
},
{
desc: "split local/global include_dirs (3)",
in: `
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := system/core/include
include $(BUILD_SHARED_LIBRARY)`,
expected: `
cc_library_shared {
include_dirs: ["system/core/include"],
}`,
},
{
desc: "split local/global include_dirs (4)",
in: `
input := testing/include
include $(CLEAR_VARS)
# Comment 1
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include system/core/include $(input)
# Comment 2
LOCAL_C_INCLUDES += $(TOP)/system/core/include $(LOCAL_PATH)/test/include
# Comment 3
include $(BUILD_SHARED_LIBRARY)`,
expected: `
input = ["testing/include"]
cc_library_shared {
// Comment 1
include_dirs: ["system/core/include"] + input + ["system/core/include"], // Comment 2
local_include_dirs: ["."] + ["include"] + ["test/include"],
// Comment 3
}`,
},
{
desc: "LOCAL_MODULE_STEM",
in: `
include $(CLEAR_VARS)
LOCAL_MODULE := libtest
LOCAL_MODULE_STEM := $(LOCAL_MODULE).so
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest2
LOCAL_MODULE_STEM := testing.so
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
name: "libtest",
suffix: ".so",
}
cc_library_shared {
name: "libtest2",
stem: "testing.so",
}
`,
},
{
desc: "LOCAL_MODULE_HOST_OS",
in: `
include $(CLEAR_VARS)
LOCAL_MODULE := libtest
LOCAL_MODULE_HOST_OS := linux darwin windows
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest2
LOCAL_MODULE_HOST_OS := linux
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
name: "libtest",
target: {
windows: {
enabled: true,
}
}
}
cc_library_shared {
name: "libtest2",
target: {
darwin: {
enabled: false,
}
}
}
`,
},
{
desc: "LOCAL_RTTI_VALUE",
in: `
include $(CLEAR_VARS)
LOCAL_MODULE := libtest
LOCAL_RTTI_FLAG := # Empty flag
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest2
LOCAL_RTTI_FLAG := -frtti
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
name: "libtest",
rtti: false, // Empty flag
}
cc_library_shared {
name: "libtest2",
rtti: true,
}
`,
},
{
desc: "LOCAL_ARM_MODE",
in: `
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
arch: {
arm: {
instruction_set: "arm",
},
},
}
`,
},
{
desc: "_<OS> suffixes",
in: `
include $(CLEAR_VARS)
LOCAL_SRC_FILES_darwin := darwin.c
LOCAL_SRC_FILES_linux := linux.c
LOCAL_SRC_FILES_windows := windows.c
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
target: {
darwin: {
srcs: ["darwin.c"],
},
linux_glibc: {
srcs: ["linux.c"],
},
windows: {
srcs: ["windows.c"],
},
},
}
`,
},
{
desc: "LOCAL_SANITIZE := never",
in: `
include $(CLEAR_VARS)
LOCAL_SANITIZE := never
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
sanitize: {
never: true,
},
}
`,
},
{
desc: "LOCAL_SANITIZE unknown parameter",
in: `
include $(CLEAR_VARS)
LOCAL_SANITIZE := thread cfi asdf
LOCAL_SANITIZE_DIAG := cfi
LOCAL_SANITIZE_RECOVER := qwert
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
sanitize: {
thread: true,
cfi: true,
misc_undefined: ["asdf"],
diag: {
cfi: true,
},
recover: ["qwert"],
},
}
`,
},
{
desc: "LOCAL_SANITIZE_RECOVER",
in: `
include $(CLEAR_VARS)
LOCAL_SANITIZE_RECOVER := shift-exponent
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
sanitize: {
recover: ["shift-exponent"],
},
}
`,
},
{
desc: "version_script in LOCAL_LDFLAGS",
in: `
include $(CLEAR_VARS)
LOCAL_LDFLAGS := -Wl,--link-opt -Wl,--version-script,$(LOCAL_PATH)/exported32.map
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
ldflags: ["-Wl,--link-opt"],
version_script: "exported32.map",
}
`,
},
{
desc: "Handle TOP",
in: `
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TOP)/system/core/include $(TOP)
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
include_dirs: ["system/core/include", "."],
}
`,
},
{
desc: "Remove LOCAL_MODULE_TAGS optional",
in: `
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
}
`,
},
{
desc: "Keep LOCAL_MODULE_TAGS non-optional",
in: `
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := debug
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
tags: ["debug"],
}
`,
},
{
desc: "Input containing escaped quotes",
in: `
include $(CLEAR_VARS)
LOCAL_MODULE:= libsensorservice
LOCAL_CFLAGS:= -DLOG_TAG=\"-DDontEscapeMe\"
LOCAL_SRC_FILES := \"EscapeMe.cc\"
include $(BUILD_SHARED_LIBRARY)
`,
expected: `
cc_library_shared {
name: "libsensorservice",
cflags: ["-DLOG_TAG=\"-DDontEscapeMe\""],
srcs: ["\\\"EscapeMe.cc\\\""],
}
`,
},
{
desc: "Don't fail on missing CLEAR_VARS",
in: `
LOCAL_MODULE := iAmAModule
include $(BUILD_SHARED_LIBRARY)`,
expected: `
// ANDROIDMK TRANSLATION WARNING: No 'include $(CLEAR_VARS)' detected before first assignment; clearing vars now
cc_library_shared {
name: "iAmAModule",
}`,
},
{
desc: "LOCAL_AIDL_INCLUDES",
in: `
include $(CLEAR_VARS)
LOCAL_MODULE := iAmAModule
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/main/java system/core
include $(BUILD_SHARED_LIBRARY)`,
expected: `
cc_library_shared {
name: "iAmAModule",
aidl: {
include_dirs: ["system/core"],
local_include_dirs: ["src/main/java"],
}
}`,
},
{
// the important part of this test case is that it confirms that androidmk doesn't
// panic in this case
desc: "multiple directives inside recipe",
in: `
ifeq ($(a),true)
ifeq ($(b),false)
imABuildStatement: somefile
echo begin
endif # a==true
echo middle
endif # b==false
echo end
`,
expected: `
// ANDROIDMK TRANSLATION ERROR: unsupported conditional
// ifeq ($(a),true)
// ANDROIDMK TRANSLATION ERROR: unsupported conditional
// ifeq ($(b),false)
// ANDROIDMK TRANSLATION ERROR: unsupported line
// rule: imABuildStatement: somefile
// echo begin
// # a==true
// echo middle
// # b==false
// echo end
//
// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
// endif
// ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
// endif
`,
},
{
desc: "ignore all-makefiles-under",
in: `
include $(call all-makefiles-under,$(LOCAL_PATH))
`,
expected: ``,
},
}
func reformatBlueprint(input string) string {
file, errs := bpparser.Parse("<testcase>", bytes.NewBufferString(input), bpparser.NewScope(nil))
if len(errs) > 0 {
for _, err := range errs {
fmt.Fprintln(os.Stderr, err)
}
panic(fmt.Sprintf("%d parsing errors in testcase:\n%s", len(errs), input))
}
res, err := bpparser.Print(file)
if err != nil {
panic(fmt.Sprintf("Error printing testcase: %q", err))
}
return string(res)
}
func TestEndToEnd(t *testing.T) {
for i, test := range testCases {
expected := reformatBlueprint(test.expected)
got, errs := convertFile(fmt.Sprintf("<testcase %d>", i), bytes.NewBufferString(test.in))
if len(errs) > 0 {
t.Errorf("Unexpected errors: %q", errs)
continue
}
if got != expected {
t.Errorf("failed testcase '%s'\ninput:\n%s\n\nexpected:\n%s\ngot:\n%s\n", test.desc, strings.TrimSpace(test.in), expected, got)
}
}
}