aboutsummaryrefslogtreecommitdiffstats
path: root/cc/stl.go
diff options
context:
space:
mode:
Diffstat (limited to 'cc/stl.go')
-rw-r--r--cc/stl.go198
1 files changed, 198 insertions, 0 deletions
diff --git a/cc/stl.go b/cc/stl.go
new file mode 100644
index 00000000..580570d7
--- /dev/null
+++ b/cc/stl.go
@@ -0,0 +1,198 @@
+// 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 (
+ "android/soong/common"
+ "fmt"
+)
+
+type StlProperties struct {
+ // select the STL library to use. Possible values are "libc++", "libc++_static",
+ // "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
+ // default
+ Stl string
+
+ SelectedStl string `blueprint:"mutated"`
+}
+
+type stlFeature struct {
+ Properties StlProperties
+}
+
+var _ feature = (*stlFeature)(nil)
+
+func (stl *stlFeature) props() []interface{} {
+ return []interface{}{&stl.Properties}
+}
+
+func (stl *stlFeature) begin(ctx BaseModuleContext) {
+ stl.Properties.SelectedStl = func() string {
+ if ctx.sdk() && ctx.Device() {
+ switch stl.Properties.Stl {
+ case "":
+ return "ndk_system"
+ case "c++_shared", "c++_static",
+ "stlport_shared", "stlport_static",
+ "gnustl_static":
+ return "ndk_lib" + stl.Properties.Stl
+ default:
+ ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", stl.Properties.Stl)
+ return ""
+ }
+ } else if ctx.HostType() == common.Windows {
+ switch stl.Properties.Stl {
+ case "libc++", "libc++_static", "libstdc++", "":
+ // libc++ is not supported on mingw
+ return "libstdc++"
+ case "none":
+ return ""
+ default:
+ ctx.ModuleErrorf("stl: %q is not a supported STL", stl.Properties.Stl)
+ return ""
+ }
+ } else {
+ switch stl.Properties.Stl {
+ case "libc++", "libc++_static",
+ "libstdc++":
+ return stl.Properties.Stl
+ case "none":
+ return ""
+ case "":
+ if ctx.static() {
+ return "libc++_static"
+ } else {
+ return "libc++"
+ }
+ default:
+ ctx.ModuleErrorf("stl: %q is not a supported STL", stl.Properties.Stl)
+ return ""
+ }
+ }
+ }()
+}
+
+func (stl *stlFeature) deps(ctx BaseModuleContext, deps Deps) Deps {
+ switch stl.Properties.SelectedStl {
+ case "libstdc++":
+ if ctx.Device() {
+ deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
+ }
+ 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)
+ }
+ if ctx.Device() {
+ if ctx.Arch().ArchType == common.Arm {
+ deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
+ }
+ if ctx.staticBinary() {
+ deps.StaticLibs = append(deps.StaticLibs, "libdl")
+ } else {
+ deps.SharedLibs = append(deps.SharedLibs, "libdl")
+ }
+ }
+ 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...)
+ case "ndk_libc++_shared", "ndk_libstlport_shared":
+ deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
+ case "ndk_libc++_static", "ndk_libstlport_static", "ndk_libgnustl_static":
+ deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
+ default:
+ panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
+ }
+
+ return deps
+}
+
+func (stl *stlFeature) flags(ctx ModuleContext, flags Flags) Flags {
+ switch stl.Properties.SelectedStl {
+ case "libc++", "libc++_static":
+ flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
+ if ctx.Host() {
+ flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
+ flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
+ flags.LdFlags = append(flags.LdFlags, "-lpthread", "-lm")
+ if ctx.staticBinary() {
+ flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.HostType()]...)
+ } else {
+ flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.HostType()]...)
+ }
+ } else {
+ if ctx.Arch().ArchType == common.Arm {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
+ }
+ }
+ case "libstdc++":
+ // Using bionic's basic libstdc++. Not actually an STL. Only around until the
+ // tree is in good enough shape to not need it.
+ // Host builds will use GNU libstdc++.
+ if ctx.Device() {
+ flags.CFlags = append(flags.CFlags, "-I"+common.PathForSource(ctx, "bionic/libstdc++/include").String())
+ } else {
+ // Host builds will use the system C++. libc++ on Darwin, GNU libstdc++ everywhere else
+ flags.CppFlags = append(flags.CppFlags, flags.Toolchain.SystemCppCppflags())
+ flags.LdFlags = append(flags.LdFlags, flags.Toolchain.SystemCppLdflags())
+ }
+ case "ndk_system":
+ ndkSrcRoot := common.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
+ flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String())
+ case "ndk_libc++_shared", "ndk_libc++_static":
+ // TODO(danalbert): This really shouldn't be here...
+ flags.CppFlags = append(flags.CppFlags, "-std=c++11")
+ case "ndk_libstlport_shared", "ndk_libstlport_static", "ndk_libgnustl_static":
+ // Nothing
+ case "":
+ // None or error.
+ if ctx.Host() {
+ flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
+ flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
+ if ctx.staticBinary() {
+ flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.HostType()]...)
+ } else {
+ flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.HostType()]...)
+ }
+ }
+ default:
+ panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
+ }
+
+ return flags
+}
+
+var hostDynamicGccLibs, hostStaticGccLibs map[common.HostType][]string
+
+func init() {
+ hostDynamicGccLibs = map[common.HostType][]string{
+ common.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
+ common.Darwin: []string{"-lc", "-lSystem"},
+ common.Windows: []string{"-lmsvcr110", "-lmingw32", "-lgcc", "-lmoldname",
+ "-lmingwex", "-lmsvcrt", "-ladvapi32", "-lshell32", "-luser32",
+ "-lkernel32", "-lmingw32", "-lgcc", "-lmoldname", "-lmingwex",
+ "-lmsvcrt"},
+ }
+ hostStaticGccLibs = map[common.HostType][]string{
+ common.Linux: []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
+ common.Darwin: []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
+ common.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
+ }
+}