Merge "[cc_fuzz] Statically link libcxx."
diff --git a/Android.bp b/Android.bp
index 4e44a0d..5c76f5a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -204,6 +204,7 @@
"cc/gen_test.go",
"cc/genrule_test.go",
"cc/library_test.go",
+ "cc/object_test.go",
"cc/prebuilt_test.go",
"cc/proto_test.go",
"cc/test_data_test.go",
diff --git a/android/apex.go b/android/apex.go
index 17df762..99b13ab 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -19,6 +19,7 @@
"sync"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
// ApexModule is the interface that a module type is expected to implement if
@@ -74,9 +75,15 @@
// Sets the name of the apex variant of this module. Called inside
// CreateApexVariations.
setApexName(apexName string)
+
+ // Return the no_apex property
+ NoApex() bool
}
type ApexProperties struct {
+ // Whether this module should not be part of any APEX. Default is false.
+ No_apex *bool
+
// Name of the apex variant that this module is mutated into
ApexName string `blueprint:"mutated"`
}
@@ -125,6 +132,10 @@
return false
}
+func (m *ApexModuleBase) NoApex() bool {
+ return proptools.Bool(m.ApexProperties.No_apex)
+}
+
func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []blueprint.Module {
if len(m.apexVariations) > 0 {
sort.Strings(m.apexVariations)
diff --git a/android/paths.go b/android/paths.go
index 5110617..0d64a61 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -989,6 +989,10 @@
var _ Path = ModuleOutPath{}
+func (p ModuleOutPath) objPathWithExt(ctx ModuleContext, subdir, ext string) ModuleObjPath {
+ return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
+}
+
func pathForModule(ctx ModuleContext) OutputPath {
return PathForOutput(ctx, ".intermediates", ctx.ModuleDir(), ctx.ModuleName(), ctx.ModuleSubDir())
}
diff --git a/apex/apex.go b/apex/apex.go
index 574604b..9e7f3a0 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -126,6 +126,16 @@
usesTag = dependencyTag{name: "uses"}
)
+var (
+ whitelistNoApex = map[string][]string{
+ "apex_test_build_features": []string{"libbinder"},
+ "com.android.neuralnetworks": []string{"libbinder"},
+ "com.android.media": []string{"libbinder"},
+ "com.android.media.swcodec": []string{"libbinder"},
+ "test_com.android.media.swcodec": []string{"libbinder"},
+ }
+)
+
func init() {
pctx.Import("android/soong/android")
pctx.Import("android/soong/java")
@@ -932,7 +942,7 @@
}
} else {
// indirect dependencies
- if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() && am.IsInstallableToApex() {
+ if am, ok := child.(android.ApexModule); ok {
// We cannot use a switch statement on `depTag` here as the checked
// tags used below are private (e.g. `cc.sharedDepTag`).
if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
@@ -972,7 +982,7 @@
filesInfo = append(filesInfo, apexFile{fileToCopy, moduleName, dirInApex, nativeTest, cc, nil})
return true
}
- } else {
+ } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
}
}
@@ -1005,6 +1015,16 @@
return filesInfo[i].builtFile.String() < filesInfo[j].builtFile.String()
})
+ // check no_apex modules
+ whitelist := whitelistNoApex[ctx.ModuleName()]
+ for i := range filesInfo {
+ if am, ok := filesInfo[i].module.(android.ApexModule); ok {
+ if am.NoApex() && !android.InList(filesInfo[i].moduleName, whitelist) {
+ ctx.ModuleErrorf("tries to include no_apex module %s", filesInfo[i].moduleName)
+ }
+ }
+ }
+
// prepend the name of this APEX to the module names. These names will be the names of
// modules that will be defined if the APEX is flattened.
for i := range filesInfo {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e06c193..387533c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -714,6 +714,58 @@
}
+func TestApexDependencyToLLNDK(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ use_vendor: true,
+ native_shared_libs: ["mylib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ shared_libs: ["libbar"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libbar",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ llndk_library {
+ name: "libbar",
+ symbol_file: "",
+ }
+
+ `)
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ // Ensure that LLNDK dep is not included
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
+
+ injectRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("injectApexDependency")
+ ensureListEmpty(t, names(injectRule.Args["provideNativeLibs"]))
+
+ // Ensure that LLNDK dep is required
+ ensureListContains(t, names(injectRule.Args["requireNativeLibs"]), "libbar.so")
+
+}
+
func TestApexWithSystemLibsStubs(t *testing.T) {
ctx, _ := testApex(t, `
apex {
@@ -1768,6 +1820,88 @@
`)
}
+func TestApexUsesFailsIfUseNoApex(t *testing.T) {
+ testApexError(t, `tries to include no_apex module mylib2`, `
+ apex {
+ name: "commonapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["mylib2"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "mylib2",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ no_apex: true,
+ }
+ `)
+
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["mylib2"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "mylib2",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["mylib3"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ }
+
+ cc_library {
+ name: "mylib3",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ no_apex: true,
+ }
+ `)
+
+ module := ctx.ModuleForTests("myapex", "android_common_myapex")
+ apexRule := module.Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/mylib3.so")
+
+}
+
func TestMain(m *testing.M) {
run := func() int {
setUp()
diff --git a/cc/builder.go b/cc/builder.go
index 3d89770..00dc742 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -65,14 +65,14 @@
ld = pctx.AndroidStaticRule("ld",
blueprint.RuleParams{
Command: "$ldCmd ${crtBegin} @${out}.rsp " +
- "${libFlags} ${crtEnd} -o ${out} ${ldFlags}",
+ "${libFlags} ${crtEnd} -o ${out} ${ldFlags} ${extraLibFlags}",
CommandDeps: []string{"$ldCmd"},
Rspfile: "${out}.rsp",
RspfileContent: "${in}",
// clang -Wl,--out-implib doesn't update its output file if it hasn't changed.
Restat: true,
},
- "ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags")
+ "ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags", "extraLibFlags")
partialLd = pctx.AndroidStaticRule("partialLd",
blueprint.RuleParams{
@@ -259,6 +259,7 @@
cppFlags string
ldFlags string
libFlags string
+ extraLibFlags string
tidyFlags string
sAbiFlags string
yasmFlags string
@@ -411,6 +412,9 @@
},
})
continue
+ case ".o":
+ objFiles[i] = srcFile
+ continue
}
var moduleCflags string
@@ -627,11 +631,12 @@
Inputs: objFiles,
Implicits: deps,
Args: map[string]string{
- "ldCmd": ldCmd,
- "crtBegin": crtBegin.String(),
- "libFlags": strings.Join(libFlagsList, " "),
- "ldFlags": flags.ldFlags,
- "crtEnd": crtEnd.String(),
+ "ldCmd": ldCmd,
+ "crtBegin": crtBegin.String(),
+ "libFlags": strings.Join(libFlagsList, " "),
+ "extraLibFlags": flags.extraLibFlags,
+ "ldFlags": flags.ldFlags,
+ "crtEnd": crtEnd.String(),
},
})
}
diff --git a/cc/cc.go b/cc/cc.go
index c853e67..0245c6a 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -153,6 +153,7 @@
rsFlags []string // Flags that apply to renderscript source files
LdFlags []string // Flags that apply to linker command lines
libFlags []string // Flags to add libraries early to the link order
+ extraLibFlags []string // Flags to add libraries late in the link order after LdFlags
TidyFlags []string // Flags that apply to clang-tidy
SAbiFlags []string // Flags that apply to header-abi-dumper
YasmFlags []string // Flags that apply to yasm assembly source files
@@ -182,17 +183,6 @@
Yacc *YaccProperties
}
-type ObjectLinkerProperties struct {
- // list of modules that should only provide headers for this module.
- Header_libs []string `android:"arch_variant,variant_prepend"`
-
- // names of other cc_object modules to link into this module using partial linking
- Objs []string `android:"arch_variant"`
-
- // if set, add an extra objcopy --prefix-symbols= step
- Prefix_symbols *string
-}
-
// Properties used to compile all C or C++ modules
type BaseProperties struct {
// Deprecated. true is the default, false is invalid.
diff --git a/cc/cc_test.go b/cc/cc_test.go
index c4799e9..52234a8 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2203,7 +2203,7 @@
ctx := testCc(t, `
cc_binary {
name: "static_test",
- srcs: ["foo.c"],
+ srcs: ["foo.c", "baz.o"],
static_executable: true,
}`)
diff --git a/cc/library.go b/cc/library.go
index 0869727..2496712 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -113,6 +113,9 @@
// Order symbols in .bss section by their sizes. Only useful for shared libraries.
Sort_bss_symbols_by_size *bool
+
+ // Inject boringssl hash into the shared library. This is only intended for use by external/boringssl.
+ Inject_bssl_hash *bool `android:"arch_variant"`
}
type LibraryMutatedProperties struct {
@@ -766,9 +769,21 @@
outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
library.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
}
-
library.unstrippedOutputFile = outputFile
+ // TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
+ if Bool(library.Properties.Inject_bssl_hash) {
+ hashedOutputfile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "unhashed", fileName)
+
+ rule := android.NewRuleBuilder()
+ rule.Command().
+ BuiltTool(ctx, "bssl_inject_hash").
+ FlagWithInput("-in-object ", outputFile).
+ FlagWithOutput("-o ", hashedOutputfile)
+ rule.Build(pctx, ctx, "injectCryptoHash", "inject crypto hash")
+ }
+
if Bool(library.baseLinker.Properties.Use_version_lib) {
if ctx.Host() {
versionedOutputFile := outputFile
diff --git a/cc/library_test.go b/cc/library_test.go
index 859b05a..2acae35 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -24,23 +24,26 @@
ctx := testCc(t, `
cc_library {
name: "libfoo",
- srcs: ["foo.c"],
+ srcs: ["foo.c", "baz.o"],
}`)
libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("ld")
libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_static").Output("libfoo.a")
- if len(libfooShared.Inputs) != 1 {
+ if len(libfooShared.Inputs) != 2 {
t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
}
- if len(libfooStatic.Inputs) != 1 {
+ if len(libfooStatic.Inputs) != 2 {
t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
}
if libfooShared.Inputs[0] != libfooStatic.Inputs[0] {
t.Errorf("static object not reused for shared library")
}
+ if libfooShared.Inputs[1] != libfooStatic.Inputs[1] {
+ t.Errorf("static object not reused for shared library")
+ }
})
t.Run("extra static source", func(t *testing.T) {
diff --git a/cc/object.go b/cc/object.go
index 15272eb..1a2711d 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -33,6 +33,20 @@
Properties ObjectLinkerProperties
}
+type ObjectLinkerProperties struct {
+ // list of modules that should only provide headers for this module.
+ Header_libs []string `android:"arch_variant,variant_prepend"`
+
+ // names of other cc_object modules to link into this module using partial linking
+ Objs []string `android:"arch_variant"`
+
+ // if set, add an extra objcopy --prefix-symbols= step
+ Prefix_symbols *string
+
+ // if set, the path to a linker script to pass to ld -r when combining multiple object files.
+ Linker_script *string `android:"path,arch_variant"`
+}
+
// cc_object runs the compiler without running the linker. It is rarely
// necessary, but sometimes used to generate .s files from .c files to use as
// input to a cc_genrule module.
@@ -71,9 +85,13 @@
return deps
}
-func (*objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+func (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags())
+ if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-T,"+lds.String())
+ flags.LdFlagsDeps = append(flags.LdFlagsDeps, lds.Path())
+ }
return flags
}
diff --git a/cc/object_test.go b/cc/object_test.go
new file mode 100644
index 0000000..6ff8a00
--- /dev/null
+++ b/cc/object_test.go
@@ -0,0 +1,31 @@
+// Copyright 2019 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 cc
+
+import (
+ "testing"
+)
+
+func TestLinkerScript(t *testing.T) {
+ t.Run("script", func(t *testing.T) {
+ testCc(t, `
+ cc_object {
+ name: "foo",
+ srcs: ["baz.o"],
+ linker_script: "foo.lds",
+ }`)
+ })
+
+}
diff --git a/cc/stl.go b/cc/stl.go
index d7feb6f..5578299 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -223,11 +223,11 @@
if !ctx.toolchain().Bionic() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
- flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
+ flags.extraLibFlags = append(flags.extraLibFlags, "-nodefaultlibs")
if ctx.staticBinary() {
- flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
+ flags.extraLibFlags = append(flags.extraLibFlags, hostStaticGccLibs[ctx.Os()]...)
} else {
- flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
+ flags.extraLibFlags = append(flags.extraLibFlags, hostDynamicGccLibs[ctx.Os()]...)
}
if ctx.Windows() {
// Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj
@@ -262,11 +262,11 @@
// None or error.
if !ctx.toolchain().Bionic() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
- flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
+ flags.extraLibFlags = append(flags.extraLibFlags, "-nodefaultlibs")
if ctx.staticBinary() {
- flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
+ flags.extraLibFlags = append(flags.extraLibFlags, hostStaticGccLibs[ctx.Os()]...)
} else {
- flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
+ flags.extraLibFlags = append(flags.extraLibFlags, hostDynamicGccLibs[ctx.Os()]...)
}
}
default:
diff --git a/cc/testing.go b/cc/testing.go
index e69b774..5a3993c 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -272,7 +272,9 @@
mockFS := map[string][]byte{
"Android.bp": []byte(bp),
"foo.c": nil,
+ "foo.lds": nil,
"bar.c": nil,
+ "baz.o": nil,
"a.proto": nil,
"b.aidl": nil,
"sub/c.aidl": nil,
diff --git a/cc/util.go b/cc/util.go
index 0d1b2f0..fb6338a 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -67,6 +67,7 @@
rsFlags: strings.Join(in.rsFlags, " "),
ldFlags: strings.Join(in.LdFlags, " "),
libFlags: strings.Join(in.libFlags, " "),
+ extraLibFlags: strings.Join(in.extraLibFlags, " "),
tidyFlags: strings.Join(in.TidyFlags, " "),
sAbiFlags: strings.Join(in.SAbiFlags, " "),
yasmFlags: strings.Join(in.YasmFlags, " "),
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 9956270..b474948 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -474,6 +474,7 @@
return strings.Join(flags, " "), deps
}
+// TODO: remove the duplication between this and the one in gen.go
func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
flags droiddocBuilderFlags) android.Paths {
@@ -487,6 +488,9 @@
case ".sysprop":
javaFile := genSysprop(ctx, srcFile)
outSrcFiles = append(outSrcFiles, javaFile)
+ case ".logtags":
+ javaFile := genLogtags(ctx, srcFile)
+ outSrcFiles = append(outSrcFiles, javaFile)
default:
outSrcFiles = append(outSrcFiles, srcFile)
}