blob: eda8a4ffce2a29da5f4985c14da08183c3996406 [file] [log] [blame]
Colin Crossca860ac2016-01-04 14:34:37 -08001// 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 (
Colin Cross635c3b02016-05-18 15:37:25 -070018 "android/soong/android"
Colin Crossca860ac2016-01-04 14:34:37 -080019 "fmt"
Dan Albert90b9bbc2018-11-15 11:29:28 -080020 "strconv"
Colin Crossca860ac2016-01-04 14:34:37 -080021)
22
Ivan Lozano52767be2019-10-18 14:49:46 -070023func getNdkStlFamily(m LinkableInterface) string {
Colin Crossb60190a2018-09-04 16:28:17 -070024 family, _ := getNdkStlFamilyAndLinkType(m)
25 return family
26}
27
Ivan Lozano52767be2019-10-18 14:49:46 -070028func getNdkStlFamilyAndLinkType(m LinkableInterface) (string, string) {
29 stl := m.SelectedStl()
Dan Albert202fe492017-12-15 13:56:59 -080030 switch stl {
Colin Crossb60190a2018-09-04 16:28:17 -070031 case "ndk_libc++_shared":
32 return "libc++", "shared"
33 case "ndk_libc++_static":
34 return "libc++", "static"
Dan Albert202fe492017-12-15 13:56:59 -080035 case "ndk_system":
Colin Crossb60190a2018-09-04 16:28:17 -070036 return "system", "shared"
Dan Albert202fe492017-12-15 13:56:59 -080037 case "":
Colin Crossb60190a2018-09-04 16:28:17 -070038 return "none", "none"
Dan Albert202fe492017-12-15 13:56:59 -080039 default:
Colin Crossb60190a2018-09-04 16:28:17 -070040 panic(fmt.Errorf("stl: %q is not a valid STL", stl))
Dan Albert202fe492017-12-15 13:56:59 -080041 }
42}
43
Colin Crossca860ac2016-01-04 14:34:37 -080044type StlProperties struct {
Dan Albert749fc782018-01-04 14:21:14 -080045 // Select the STL library to use. Possible values are "libc++",
46 // "libc++_static", "libstdc++", or "none". Leave blank to select the
47 // default.
Colin Cross245ced72017-07-20 16:57:46 -070048 Stl *string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -080049
50 SelectedStl string `blueprint:"mutated"`
51}
52
Colin Crossa8e07cc2016-04-04 15:07:06 -070053type stl struct {
Colin Crossca860ac2016-01-04 14:34:37 -080054 Properties StlProperties
55}
56
Colin Crossa8e07cc2016-04-04 15:07:06 -070057func (stl *stl) props() []interface{} {
Colin Crossca860ac2016-01-04 14:34:37 -080058 return []interface{}{&stl.Properties}
59}
60
Colin Crossa8e07cc2016-04-04 15:07:06 -070061func (stl *stl) begin(ctx BaseModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -080062 stl.Properties.SelectedStl = func() string {
Colin Cross79248852016-07-12 13:12:33 -070063 s := ""
64 if stl.Properties.Stl != nil {
65 s = *stl.Properties.Stl
66 }
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070067 if ctx.useSdk() && ctx.Device() {
Colin Cross79248852016-07-12 13:12:33 -070068 switch s {
Sasha Smundakfc22e4e2019-03-24 14:17:56 -070069 case "", "system":
Colin Crossca860ac2016-01-04 14:34:37 -080070 return "ndk_system"
Dan Albert749fc782018-01-04 14:21:14 -080071 case "c++_shared", "c++_static":
Colin Cross79248852016-07-12 13:12:33 -070072 return "ndk_lib" + s
David Benjamin87f9f032017-01-25 14:10:04 -050073 case "libc++":
74 return "ndk_libc++_shared"
75 case "libc++_static":
76 return "ndk_libc++_static"
Colin Cross4a97cb42016-04-21 15:53:42 -070077 case "none":
78 return ""
Colin Crossca860ac2016-01-04 14:34:37 -080079 default:
Colin Cross79248852016-07-12 13:12:33 -070080 ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
Colin Crossca860ac2016-01-04 14:34:37 -080081 return ""
82 }
Colin Cross3edeee12017-04-04 12:59:48 -070083 } else if ctx.Windows() {
Colin Cross79248852016-07-12 13:12:33 -070084 switch s {
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -070085 case "libc++", "libc++_static", "":
86 // Only use static libc++ for Windows.
87 return "libc++_static"
Colin Crossca860ac2016-01-04 14:34:37 -080088 case "none":
89 return ""
90 default:
Colin Cross79248852016-07-12 13:12:33 -070091 ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
Colin Crossca860ac2016-01-04 14:34:37 -080092 return ""
93 }
Doug Hornc32c6b02019-01-17 14:44:05 -080094 } else if ctx.Fuchsia() {
95 switch s {
96 case "c++_static":
97 return "libc++_static"
98 case "c++_shared":
99 return "libc++"
100 case "libc++", "libc++_static":
101 return s
102 case "none":
103 return ""
104 case "":
105 if ctx.static() {
106 return "libc++_static"
107 } else {
108 return "libc++"
109 }
110 default:
111 ctx.ModuleErrorf("stl: %q is not a supported STL on Fuchsia", s)
112 return ""
113 }
Colin Crossca860ac2016-01-04 14:34:37 -0800114 } else {
Colin Cross79248852016-07-12 13:12:33 -0700115 switch s {
Dan Willemsen141d5662016-06-15 13:47:51 -0700116 case "libc++", "libc++_static":
Colin Cross79248852016-07-12 13:12:33 -0700117 return s
Colin Crossca860ac2016-01-04 14:34:37 -0800118 case "none":
119 return ""
120 case "":
121 if ctx.static() {
122 return "libc++_static"
123 } else {
124 return "libc++"
125 }
126 default:
Colin Cross79248852016-07-12 13:12:33 -0700127 ctx.ModuleErrorf("stl: %q is not a supported STL", s)
Colin Crossca860ac2016-01-04 14:34:37 -0800128 return ""
129 }
130 }
131 }()
132}
133
Dan Albert90b9bbc2018-11-15 11:29:28 -0800134func needsLibAndroidSupport(ctx BaseModuleContext) bool {
135 versionStr, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch())
136 if err != nil {
137 ctx.PropertyErrorf("sdk_version", err.Error())
138 }
139
140 if versionStr == "current" {
141 return false
142 }
143
144 version, err := strconv.Atoi(versionStr)
145 if err != nil {
146 panic(fmt.Sprintf(
147 "invalid API level returned from normalizeNdkApiLevel: %q",
148 versionStr))
149 }
150
151 return version < 21
152}
153
Peter Collingbournedc4f9862020-02-12 17:13:25 -0800154func staticUnwinder(ctx android.BaseModuleContext) string {
155 if ctx.Arch().ArchType == android.Arm {
156 return "libunwind_llvm"
157 } else {
158 return "libgcc_stripped"
159 }
160}
161
Colin Crossa8e07cc2016-04-04 15:07:06 -0700162func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Crossca860ac2016-01-04 14:34:37 -0800163 switch stl.Properties.SelectedStl {
164 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700165 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800166 case "libc++", "libc++_static":
167 if stl.Properties.SelectedStl == "libc++" {
168 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
169 } else {
170 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
171 }
Dan Albert2da19cb2019-07-24 12:17:40 -0700172 if ctx.Device() && !ctx.useSdk() {
173 // __cxa_demangle is not a part of libc++.so on the device since
174 // it's large and most processes don't need it. Statically link
175 // libc++demangle into every process so that users still have it if
176 // needed, but the linker won't include this unless it is actually
177 // called.
178 // http://b/138245375
179 deps.StaticLibs = append(deps.StaticLibs, "libc++demangle")
180 }
Dan Willemsen2e47b342016-11-17 01:02:25 -0800181 if ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800182 if ctx.staticBinary() {
Peter Collingbournedc4f9862020-02-12 17:13:25 -0800183 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", staticUnwinder(ctx))
184 } else {
185 deps.StaticUnwinderIfLegacy = true
Colin Crossca860ac2016-01-04 14:34:37 -0800186 }
187 }
188 case "":
189 // None or error.
Peter Collingbournedc4f9862020-02-12 17:13:25 -0800190 if ctx.toolchain().Bionic() && ctx.Module().Name() == "libc++" {
191 deps.StaticUnwinderIfLegacy = true
192 }
Colin Crossca860ac2016-01-04 14:34:37 -0800193 case "ndk_system":
194 // TODO: Make a system STL prebuilt for the NDK.
195 // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
196 // its own includes. The includes are handled in CCBase.Flags().
197 deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
Ryan Prichardb1703652018-03-26 16:30:31 -0700198 case "ndk_libc++_shared", "ndk_libc++_static":
199 if stl.Properties.SelectedStl == "ndk_libc++_shared" {
200 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
201 } else {
202 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
203 }
Dan Albert90b9bbc2018-11-15 11:29:28 -0800204 if needsLibAndroidSupport(ctx) {
205 deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
206 }
Ryan Prichardb1703652018-03-26 16:30:31 -0700207 if ctx.Arch().ArchType == android.Arm {
208 deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
Peter Collingbournee5ba2862019-12-10 18:37:45 -0800209 } else {
210 deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped")
Ryan Prichardb1703652018-03-26 16:30:31 -0700211 }
Colin Crossca860ac2016-01-04 14:34:37 -0800212 default:
213 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
214 }
215
216 return deps
217}
218
Colin Crossa8e07cc2016-04-04 15:07:06 -0700219func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
Colin Crossca860ac2016-01-04 14:34:37 -0800220 switch stl.Properties.SelectedStl {
221 case "libc++", "libc++_static":
Dan Alberta07b8452018-01-11 13:00:46 -0800222 if ctx.Darwin() {
223 // libc++'s headers are annotated with availability macros that
224 // indicate which version of Mac OS was the first to ship with a
225 // libc++ feature available in its *system's* libc++.dylib. We do
226 // not use the system's library, but rather ship our own. As such,
227 // these availability attributes are meaningless for us but cause
228 // build breaks when we try to use code that would not be available
229 // in the system's dylib.
Colin Cross4af21ed2019-11-04 09:37:55 -0800230 flags.Local.CppFlags = append(flags.Local.CppFlags,
Dan Alberta07b8452018-01-11 13:00:46 -0800231 "-D_LIBCPP_DISABLE_AVAILABILITY")
232 }
233
Dan Willemsen2e47b342016-11-17 01:02:25 -0800234 if !ctx.toolchain().Bionic() {
Colin Cross4af21ed2019-11-04 09:37:55 -0800235 flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
Colin Crossf7a17da2019-10-03 15:48:34 -0700236 flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700237 if ctx.Windows() {
Colin Crossf7a17da2019-10-03 15:48:34 -0700238 if stl.Properties.SelectedStl == "libc++_static" {
239 // These are transitively needed by libc++_static.
240 flags.extraLibFlags = append(flags.extraLibFlags,
241 "-lmsvcrt", "-lucrt")
242 }
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700243 // Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj
244 // exception model for 32-bit.
245 if ctx.Arch().ArchType == android.X86 {
Colin Cross4af21ed2019-11-04 09:37:55 -0800246 flags.Local.CppFlags = append(flags.Local.CppFlags, "-fsjlj-exceptions")
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700247 }
Colin Cross4af21ed2019-11-04 09:37:55 -0800248 flags.Local.CppFlags = append(flags.Local.CppFlags,
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700249 // Disable visiblity annotations since we're using static
250 // libc++.
251 "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
252 "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
253 // Use Win32 threads in libc++.
254 "-D_LIBCPP_HAS_THREAD_API_WIN32")
255 }
Colin Crossca860ac2016-01-04 14:34:37 -0800256 } else {
Colin Cross635c3b02016-05-18 15:37:25 -0700257 if ctx.Arch().ArchType == android.Arm {
Colin Cross4af21ed2019-11-04 09:37:55 -0800258 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
Colin Crossca860ac2016-01-04 14:34:37 -0800259 }
260 }
261 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700262 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800263 case "ndk_system":
Colin Cross635c3b02016-05-18 15:37:25 -0700264 ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
Colin Cross4af21ed2019-11-04 09:37:55 -0800265 flags.Local.CFlags = append(flags.Local.CFlags, "-isystem "+ndkSrcRoot.String())
Colin Crossca860ac2016-01-04 14:34:37 -0800266 case "ndk_libc++_shared", "ndk_libc++_static":
Christopher Ferrisc3a1e222019-04-10 17:57:50 -0700267 if ctx.Arch().ArchType == android.Arm {
268 // Make sure the _Unwind_XXX symbols are not re-exported.
Colin Cross4af21ed2019-11-04 09:37:55 -0800269 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind.a")
Christopher Ferrisc3a1e222019-04-10 17:57:50 -0700270 }
Colin Crossca860ac2016-01-04 14:34:37 -0800271 case "":
272 // None or error.
Dan Willemsen2e47b342016-11-17 01:02:25 -0800273 if !ctx.toolchain().Bionic() {
Colin Cross4af21ed2019-11-04 09:37:55 -0800274 flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
Colin Crossf7a17da2019-10-03 15:48:34 -0700275 flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
Colin Crossca860ac2016-01-04 14:34:37 -0800276 }
277 default:
278 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
279 }
280
281 return flags
282}