2016-01-04 23:34:37 +01:00
|
|
|
// 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 cc
|
|
|
|
|
|
|
|
import (
|
2016-05-19 00:37:25 +02:00
|
|
|
"android/soong/android"
|
2016-01-04 23:34:37 +01:00
|
|
|
"fmt"
|
2018-11-15 20:29:28 +01:00
|
|
|
"strconv"
|
2016-01-04 23:34:37 +01:00
|
|
|
)
|
|
|
|
|
2019-10-18 23:49:46 +02:00
|
|
|
func getNdkStlFamily(m LinkableInterface) string {
|
2018-09-05 01:28:17 +02:00
|
|
|
family, _ := getNdkStlFamilyAndLinkType(m)
|
|
|
|
return family
|
|
|
|
}
|
|
|
|
|
2019-10-18 23:49:46 +02:00
|
|
|
func getNdkStlFamilyAndLinkType(m LinkableInterface) (string, string) {
|
|
|
|
stl := m.SelectedStl()
|
2017-12-15 22:56:59 +01:00
|
|
|
switch stl {
|
2018-09-05 01:28:17 +02:00
|
|
|
case "ndk_libc++_shared":
|
|
|
|
return "libc++", "shared"
|
|
|
|
case "ndk_libc++_static":
|
|
|
|
return "libc++", "static"
|
2017-12-15 22:56:59 +01:00
|
|
|
case "ndk_system":
|
2018-09-05 01:28:17 +02:00
|
|
|
return "system", "shared"
|
2017-12-15 22:56:59 +01:00
|
|
|
case "":
|
2018-09-05 01:28:17 +02:00
|
|
|
return "none", "none"
|
2017-12-15 22:56:59 +01:00
|
|
|
default:
|
2018-09-05 01:28:17 +02:00
|
|
|
panic(fmt.Errorf("stl: %q is not a valid STL", stl))
|
2017-12-15 22:56:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-04 23:34:37 +01:00
|
|
|
type StlProperties struct {
|
2018-01-04 23:21:14 +01:00
|
|
|
// Select the STL library to use. Possible values are "libc++",
|
|
|
|
// "libc++_static", "libstdc++", or "none". Leave blank to select the
|
|
|
|
// default.
|
2017-07-21 01:57:46 +02:00
|
|
|
Stl *string `android:"arch_variant"`
|
2016-01-04 23:34:37 +01:00
|
|
|
|
|
|
|
SelectedStl string `blueprint:"mutated"`
|
|
|
|
}
|
|
|
|
|
2016-04-05 00:07:06 +02:00
|
|
|
type stl struct {
|
2016-01-04 23:34:37 +01:00
|
|
|
Properties StlProperties
|
|
|
|
}
|
|
|
|
|
2016-04-05 00:07:06 +02:00
|
|
|
func (stl *stl) props() []interface{} {
|
2016-01-04 23:34:37 +01:00
|
|
|
return []interface{}{&stl.Properties}
|
|
|
|
}
|
|
|
|
|
2016-04-05 00:07:06 +02:00
|
|
|
func (stl *stl) begin(ctx BaseModuleContext) {
|
2016-01-04 23:34:37 +01:00
|
|
|
stl.Properties.SelectedStl = func() string {
|
2016-07-12 22:12:33 +02:00
|
|
|
s := ""
|
|
|
|
if stl.Properties.Stl != nil {
|
|
|
|
s = *stl.Properties.Stl
|
|
|
|
}
|
2017-09-28 02:01:44 +02:00
|
|
|
if ctx.useSdk() && ctx.Device() {
|
2016-07-12 22:12:33 +02:00
|
|
|
switch s {
|
2019-03-24 22:17:56 +01:00
|
|
|
case "", "system":
|
2016-01-04 23:34:37 +01:00
|
|
|
return "ndk_system"
|
2018-01-04 23:21:14 +01:00
|
|
|
case "c++_shared", "c++_static":
|
2016-07-12 22:12:33 +02:00
|
|
|
return "ndk_lib" + s
|
2017-01-25 20:10:04 +01:00
|
|
|
case "libc++":
|
|
|
|
return "ndk_libc++_shared"
|
|
|
|
case "libc++_static":
|
|
|
|
return "ndk_libc++_static"
|
2016-04-22 00:53:42 +02:00
|
|
|
case "none":
|
|
|
|
return ""
|
2016-01-04 23:34:37 +01:00
|
|
|
default:
|
2016-07-12 22:12:33 +02:00
|
|
|
ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
|
2016-01-04 23:34:37 +01:00
|
|
|
return ""
|
|
|
|
}
|
2017-04-04 21:59:48 +02:00
|
|
|
} else if ctx.Windows() {
|
2016-07-12 22:12:33 +02:00
|
|
|
switch s {
|
2018-08-08 19:28:12 +02:00
|
|
|
case "libc++", "libc++_static", "":
|
|
|
|
// Only use static libc++ for Windows.
|
|
|
|
return "libc++_static"
|
2016-01-04 23:34:37 +01:00
|
|
|
case "none":
|
|
|
|
return ""
|
|
|
|
default:
|
2016-07-12 22:12:33 +02:00
|
|
|
ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
|
2016-01-04 23:34:37 +01:00
|
|
|
return ""
|
|
|
|
}
|
2019-01-17 23:44:05 +01:00
|
|
|
} else if ctx.Fuchsia() {
|
|
|
|
switch s {
|
|
|
|
case "c++_static":
|
|
|
|
return "libc++_static"
|
|
|
|
case "c++_shared":
|
|
|
|
return "libc++"
|
|
|
|
case "libc++", "libc++_static":
|
|
|
|
return s
|
|
|
|
case "none":
|
|
|
|
return ""
|
|
|
|
case "":
|
|
|
|
if ctx.static() {
|
|
|
|
return "libc++_static"
|
|
|
|
} else {
|
|
|
|
return "libc++"
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ctx.ModuleErrorf("stl: %q is not a supported STL on Fuchsia", s)
|
|
|
|
return ""
|
|
|
|
}
|
2016-01-04 23:34:37 +01:00
|
|
|
} else {
|
2016-07-12 22:12:33 +02:00
|
|
|
switch s {
|
2016-06-15 22:47:51 +02:00
|
|
|
case "libc++", "libc++_static":
|
2016-07-12 22:12:33 +02:00
|
|
|
return s
|
2016-01-04 23:34:37 +01:00
|
|
|
case "none":
|
|
|
|
return ""
|
|
|
|
case "":
|
|
|
|
if ctx.static() {
|
|
|
|
return "libc++_static"
|
|
|
|
} else {
|
|
|
|
return "libc++"
|
|
|
|
}
|
|
|
|
default:
|
2016-07-12 22:12:33 +02:00
|
|
|
ctx.ModuleErrorf("stl: %q is not a supported STL", s)
|
2016-01-04 23:34:37 +01:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2018-11-15 20:29:28 +01:00
|
|
|
func needsLibAndroidSupport(ctx BaseModuleContext) bool {
|
|
|
|
versionStr, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch())
|
|
|
|
if err != nil {
|
|
|
|
ctx.PropertyErrorf("sdk_version", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if versionStr == "current" {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
version, err := strconv.Atoi(versionStr)
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Sprintf(
|
|
|
|
"invalid API level returned from normalizeNdkApiLevel: %q",
|
|
|
|
versionStr))
|
|
|
|
}
|
|
|
|
|
|
|
|
return version < 21
|
|
|
|
}
|
|
|
|
|
2016-04-05 00:07:06 +02:00
|
|
|
func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
|
2016-01-04 23:34:37 +01:00
|
|
|
switch stl.Properties.SelectedStl {
|
|
|
|
case "libstdc++":
|
2016-06-15 22:47:51 +02:00
|
|
|
// Nothing
|
2016-01-04 23:34:37 +01:00
|
|
|
case "libc++", "libc++_static":
|
|
|
|
if stl.Properties.SelectedStl == "libc++" {
|
|
|
|
deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
|
|
|
|
} else {
|
|
|
|
deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
|
|
|
|
}
|
2019-07-24 21:17:40 +02:00
|
|
|
if ctx.Device() && !ctx.useSdk() {
|
|
|
|
// __cxa_demangle is not a part of libc++.so on the device since
|
|
|
|
// it's large and most processes don't need it. Statically link
|
|
|
|
// libc++demangle into every process so that users still have it if
|
|
|
|
// needed, but the linker won't include this unless it is actually
|
|
|
|
// called.
|
|
|
|
// http://b/138245375
|
|
|
|
deps.StaticLibs = append(deps.StaticLibs, "libc++demangle")
|
|
|
|
}
|
2016-11-17 10:02:25 +01:00
|
|
|
if ctx.toolchain().Bionic() {
|
2016-05-19 00:37:25 +02:00
|
|
|
if ctx.Arch().ArchType == android.Arm {
|
2016-01-04 23:34:37 +01:00
|
|
|
deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
|
|
|
|
}
|
|
|
|
if ctx.staticBinary() {
|
Stop linking libdl.a into static bins
libdl.a has a no-op dlopen, which breaks static libraries that need a real
dlopen. Instead of automatically linking libdl.a into static executables,
make it optional.
Until recently, the libunwind_llvm.a unwinder, used on arm32, needed the
no-op dladdr, but it's now built using -D_LIBUNWIND_USE_DLADDR=0.
The HWASan run-time uses dlsym and dladdr, so add a libdl dependency for
HWASan-built static binaries. We could also remove the dependency from
libclang_rt.hwasan_static-*.a, but this is also easy to do.
Bug: http://b/141485154
Test: bionic unit tests, device boots, verify that static and dynamic
executables can throw/catch an exception
Test: verify that a static executable using dlopen doesn't link (unless it
adds an explicit dependency on libdl)
Change-Id: Ic52c3f336b671b4ed335e99c94a64dfe8614b618
2019-10-12 00:03:34 +02:00
|
|
|
deps.StaticLibs = append(deps.StaticLibs, "libm", "libc")
|
2016-01-04 23:34:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
case "":
|
|
|
|
// None or error.
|
|
|
|
case "ndk_system":
|
|
|
|
// TODO: Make a system STL prebuilt for the NDK.
|
|
|
|
// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
|
|
|
|
// its own includes. The includes are handled in CCBase.Flags().
|
|
|
|
deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
|
2018-03-27 01:30:31 +02:00
|
|
|
case "ndk_libc++_shared", "ndk_libc++_static":
|
|
|
|
if stl.Properties.SelectedStl == "ndk_libc++_shared" {
|
|
|
|
deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
|
|
|
|
} else {
|
|
|
|
deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
|
|
|
|
}
|
2018-11-15 20:29:28 +01:00
|
|
|
if needsLibAndroidSupport(ctx) {
|
|
|
|
deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
|
|
|
|
}
|
2018-03-27 01:30:31 +02:00
|
|
|
if ctx.Arch().ArchType == android.Arm {
|
|
|
|
deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
|
|
|
|
}
|
2016-01-04 23:34:37 +01:00
|
|
|
default:
|
|
|
|
panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
|
|
|
|
}
|
|
|
|
|
|
|
|
return deps
|
|
|
|
}
|
|
|
|
|
2016-04-05 00:07:06 +02:00
|
|
|
func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
|
2016-01-04 23:34:37 +01:00
|
|
|
switch stl.Properties.SelectedStl {
|
|
|
|
case "libc++", "libc++_static":
|
2018-01-11 22:00:46 +01:00
|
|
|
if ctx.Darwin() {
|
|
|
|
// libc++'s headers are annotated with availability macros that
|
|
|
|
// indicate which version of Mac OS was the first to ship with a
|
|
|
|
// libc++ feature available in its *system's* libc++.dylib. We do
|
|
|
|
// not use the system's library, but rather ship our own. As such,
|
|
|
|
// these availability attributes are meaningless for us but cause
|
|
|
|
// build breaks when we try to use code that would not be available
|
|
|
|
// in the system's dylib.
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.CppFlags = append(flags.Local.CppFlags,
|
2018-01-11 22:00:46 +01:00
|
|
|
"-D_LIBCPP_DISABLE_AVAILABILITY")
|
|
|
|
}
|
|
|
|
|
2016-11-17 10:02:25 +01:00
|
|
|
if !ctx.toolchain().Bionic() {
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
|
2019-10-04 00:48:34 +02:00
|
|
|
flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
|
2018-08-08 19:28:12 +02:00
|
|
|
if ctx.Windows() {
|
2019-10-04 00:48:34 +02:00
|
|
|
if stl.Properties.SelectedStl == "libc++_static" {
|
|
|
|
// These are transitively needed by libc++_static.
|
|
|
|
flags.extraLibFlags = append(flags.extraLibFlags,
|
|
|
|
"-lmsvcrt", "-lucrt")
|
|
|
|
}
|
2018-08-08 19:28:12 +02:00
|
|
|
// Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj
|
|
|
|
// exception model for 32-bit.
|
|
|
|
if ctx.Arch().ArchType == android.X86 {
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.CppFlags = append(flags.Local.CppFlags, "-fsjlj-exceptions")
|
2018-08-08 19:28:12 +02:00
|
|
|
}
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.CppFlags = append(flags.Local.CppFlags,
|
2018-08-08 19:28:12 +02:00
|
|
|
// Disable visiblity annotations since we're using static
|
|
|
|
// libc++.
|
|
|
|
"-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
|
|
|
|
"-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
|
|
|
|
// Use Win32 threads in libc++.
|
|
|
|
"-D_LIBCPP_HAS_THREAD_API_WIN32")
|
|
|
|
}
|
2016-01-04 23:34:37 +01:00
|
|
|
} else {
|
2016-05-19 00:37:25 +02:00
|
|
|
if ctx.Arch().ArchType == android.Arm {
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
|
2016-01-04 23:34:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
case "libstdc++":
|
2016-06-15 22:47:51 +02:00
|
|
|
// Nothing
|
2016-01-04 23:34:37 +01:00
|
|
|
case "ndk_system":
|
2016-05-19 00:37:25 +02:00
|
|
|
ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.CFlags = append(flags.Local.CFlags, "-isystem "+ndkSrcRoot.String())
|
2016-01-04 23:34:37 +01:00
|
|
|
case "ndk_libc++_shared", "ndk_libc++_static":
|
2019-04-11 02:57:50 +02:00
|
|
|
if ctx.Arch().ArchType == android.Arm {
|
|
|
|
// Make sure the _Unwind_XXX symbols are not re-exported.
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind.a")
|
2019-04-11 02:57:50 +02:00
|
|
|
}
|
2016-01-04 23:34:37 +01:00
|
|
|
case "":
|
|
|
|
// None or error.
|
2016-11-17 10:02:25 +01:00
|
|
|
if !ctx.toolchain().Bionic() {
|
2019-11-04 18:37:55 +01:00
|
|
|
flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
|
2019-10-04 00:48:34 +02:00
|
|
|
flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
|
2016-01-04 23:34:37 +01:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
|
|
|
|
}
|
|
|
|
|
|
|
|
return flags
|
|
|
|
}
|