• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
18	"android/soong/android"
19	"fmt"
20)
21
22type StlProperties struct {
23	// select the STL library to use.  Possible values are "libc++", "libc++_static",
24	// "stlport", "stlport_static", "ndk", "libstdc++", or "none".  Leave blank to select the
25	// default
26	Stl *string
27
28	SelectedStl string `blueprint:"mutated"`
29}
30
31type stl struct {
32	Properties StlProperties
33}
34
35func (stl *stl) props() []interface{} {
36	return []interface{}{&stl.Properties}
37}
38
39func (stl *stl) begin(ctx BaseModuleContext) {
40	stl.Properties.SelectedStl = func() string {
41		s := ""
42		if stl.Properties.Stl != nil {
43			s = *stl.Properties.Stl
44		}
45		if ctx.sdk() && ctx.Device() {
46			switch s {
47			case "":
48				return "ndk_system"
49			case "c++_shared", "c++_static",
50				"stlport_shared", "stlport_static",
51				"gnustl_static":
52				return "ndk_lib" + s
53			case "libc++":
54				return "ndk_libc++_shared"
55			case "libc++_static":
56				return "ndk_libc++_static"
57			case "none":
58				return ""
59			default:
60				ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
61				return ""
62			}
63		} else if ctx.Windows() {
64			switch s {
65			case "libc++", "libc++_static", "libstdc++", "":
66				// libc++ is not supported on mingw
67				return "libstdc++"
68			case "none":
69				return ""
70			default:
71				ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
72				return ""
73			}
74		} else {
75			switch s {
76			case "libc++", "libc++_static":
77				return s
78			case "none":
79				return ""
80			case "":
81				if ctx.static() {
82					return "libc++_static"
83				} else {
84					return "libc++"
85				}
86			default:
87				ctx.ModuleErrorf("stl: %q is not a supported STL", s)
88				return ""
89			}
90		}
91	}()
92}
93
94func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
95	switch stl.Properties.SelectedStl {
96	case "libstdc++":
97		// Nothing
98	case "libc++", "libc++_static":
99		if stl.Properties.SelectedStl == "libc++" {
100			deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
101		} else {
102			deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
103		}
104		if ctx.toolchain().Bionic() {
105			if ctx.Arch().ArchType == android.Arm {
106				deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
107			}
108			if ctx.staticBinary() {
109				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
110			}
111		}
112	case "":
113		// None or error.
114	case "ndk_system":
115		// TODO: Make a system STL prebuilt for the NDK.
116		// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
117		// its own includes. The includes are handled in CCBase.Flags().
118		deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
119	case "ndk_libc++_shared", "ndk_libstlport_shared":
120		deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
121	case "ndk_libc++_static", "ndk_libstlport_static", "ndk_libgnustl_static":
122		deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
123	default:
124		panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
125	}
126
127	return deps
128}
129
130func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
131	switch stl.Properties.SelectedStl {
132	case "libc++", "libc++_static":
133		flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
134		if !ctx.toolchain().Bionic() {
135			flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
136			flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
137			flags.LdFlags = append(flags.LdFlags, "-lpthread", "-lm")
138			if ctx.staticBinary() {
139				flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
140			} else {
141				flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
142			}
143		} else {
144			if ctx.Arch().ArchType == android.Arm {
145				flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
146			}
147		}
148	case "libstdc++":
149		// Nothing
150	case "ndk_system":
151		ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
152		flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String())
153	case "ndk_libc++_shared", "ndk_libc++_static":
154		// TODO(danalbert): This really shouldn't be here...
155		flags.CppFlags = append(flags.CppFlags, "-std=c++11")
156	case "ndk_libstlport_shared", "ndk_libstlport_static", "ndk_libgnustl_static":
157		// Nothing
158	case "":
159		// None or error.
160		if !ctx.toolchain().Bionic() {
161			flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
162			flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
163			if ctx.staticBinary() {
164				flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
165			} else {
166				flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
167			}
168		}
169	default:
170		panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
171	}
172
173	return flags
174}
175
176var hostDynamicGccLibs, hostStaticGccLibs map[android.OsType][]string
177
178func init() {
179	hostDynamicGccLibs = map[android.OsType][]string{
180		android.Linux:  []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
181		android.Darwin: []string{"-lc", "-lSystem"},
182		android.Windows: []string{"-lmsvcr110", "-lmingw32", "-lgcc", "-lmoldname",
183			"-lmingwex", "-lmsvcrt", "-ladvapi32", "-lshell32", "-luser32",
184			"-lkernel32", "-lmingw32", "-lgcc", "-lmoldname", "-lmingwex",
185			"-lmsvcrt"},
186	}
187	hostStaticGccLibs = map[android.OsType][]string{
188		android.Linux:   []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
189		android.Darwin:  []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
190		android.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
191	}
192}
193