diff options
Diffstat (limited to 'cc/stl.go')
| -rw-r--r-- | cc/stl.go | 198 |
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"}, + } +} |
