blob: de2066f30c996021bbedf25957a1e6a7edf52cd6 [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 Crossca860ac2016-01-04 14:34:37 -080018 "fmt"
Colin Crosscb0ac952021-07-20 13:17:15 -070019
20 "android/soong/android"
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
Liz Kammer7128d382022-05-12 11:42:33 -040028func deduplicateStlInput(stl string) string {
29 switch stl {
30 case "c++_shared":
31 return "libc++"
32 case "c++_static":
33 return "libc++_static"
34 }
35 return stl
36}
37
Ivan Lozano52767be2019-10-18 14:49:46 -070038func getNdkStlFamilyAndLinkType(m LinkableInterface) (string, string) {
39 stl := m.SelectedStl()
Dan Albert202fe492017-12-15 13:56:59 -080040 switch stl {
Colin Cross4c608f52023-01-17 12:06:45 -080041 case "ndk_libc++_shared", "libc++":
Colin Crossb60190a2018-09-04 16:28:17 -070042 return "libc++", "shared"
Colin Cross4c608f52023-01-17 12:06:45 -080043 case "ndk_libc++_static", "libc++_static":
Colin Crossb60190a2018-09-04 16:28:17 -070044 return "libc++", "static"
Dan Albert202fe492017-12-15 13:56:59 -080045 case "ndk_system":
Colin Crossb60190a2018-09-04 16:28:17 -070046 return "system", "shared"
Dan Albert202fe492017-12-15 13:56:59 -080047 case "":
Colin Crossb60190a2018-09-04 16:28:17 -070048 return "none", "none"
Dan Albert202fe492017-12-15 13:56:59 -080049 default:
Colin Crossb60190a2018-09-04 16:28:17 -070050 panic(fmt.Errorf("stl: %q is not a valid STL", stl))
Dan Albert202fe492017-12-15 13:56:59 -080051 }
52}
53
Colin Crossca860ac2016-01-04 14:34:37 -080054type StlProperties struct {
Dan Albert749fc782018-01-04 14:21:14 -080055 // Select the STL library to use. Possible values are "libc++",
56 // "libc++_static", "libstdc++", or "none". Leave blank to select the
57 // default.
Colin Cross245ced72017-07-20 16:57:46 -070058 Stl *string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -080059
60 SelectedStl string `blueprint:"mutated"`
61}
62
Colin Crossa8e07cc2016-04-04 15:07:06 -070063type stl struct {
Colin Crossca860ac2016-01-04 14:34:37 -080064 Properties StlProperties
65}
66
Colin Crossa8e07cc2016-04-04 15:07:06 -070067func (stl *stl) props() []interface{} {
Colin Crossca860ac2016-01-04 14:34:37 -080068 return []interface{}{&stl.Properties}
69}
70
Colin Crossa8e07cc2016-04-04 15:07:06 -070071func (stl *stl) begin(ctx BaseModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -080072 stl.Properties.SelectedStl = func() string {
Colin Cross79248852016-07-12 13:12:33 -070073 s := ""
74 if stl.Properties.Stl != nil {
75 s = *stl.Properties.Stl
Colin Crossbe763f72021-04-26 17:07:17 -070076 } else if ctx.header() {
77 s = "none"
Colin Cross79248852016-07-12 13:12:33 -070078 }
Liz Kammer7128d382022-05-12 11:42:33 -040079 if s == "none" {
80 return ""
81 }
82 s = deduplicateStlInput(s)
Prashanth Swaminathan08e634d2023-07-26 09:42:41 -070083 if ctx.useSdk() && ctx.Device() {
Colin Cross79248852016-07-12 13:12:33 -070084 switch s {
Sasha Smundakfc22e4e2019-03-24 14:17:56 -070085 case "", "system":
Colin Crossca860ac2016-01-04 14:34:37 -080086 return "ndk_system"
David Benjamin87f9f032017-01-25 14:10:04 -050087 case "libc++":
88 return "ndk_libc++_shared"
89 case "libc++_static":
90 return "ndk_libc++_static"
Colin Crossca860ac2016-01-04 14:34:37 -080091 default:
Colin Cross79248852016-07-12 13:12:33 -070092 ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
Colin Crossca860ac2016-01-04 14:34:37 -080093 return ""
94 }
Colin Cross3edeee12017-04-04 12:59:48 -070095 } else if ctx.Windows() {
Colin Cross79248852016-07-12 13:12:33 -070096 switch s {
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -070097 case "libc++", "libc++_static", "":
98 // Only use static libc++ for Windows.
99 return "libc++_static"
Colin Crossca860ac2016-01-04 14:34:37 -0800100 default:
Colin Cross79248852016-07-12 13:12:33 -0700101 ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
Colin Crossca860ac2016-01-04 14:34:37 -0800102 return ""
103 }
104 } else {
Colin Cross79248852016-07-12 13:12:33 -0700105 switch s {
Dan Willemsen141d5662016-06-15 13:47:51 -0700106 case "libc++", "libc++_static":
Colin Cross79248852016-07-12 13:12:33 -0700107 return s
Colin Crossc511bc52020-04-07 16:50:32 +0000108 case "", "system":
Colin Crossca860ac2016-01-04 14:34:37 -0800109 if ctx.static() {
110 return "libc++_static"
111 } else {
112 return "libc++"
113 }
114 default:
Colin Cross79248852016-07-12 13:12:33 -0700115 ctx.ModuleErrorf("stl: %q is not a supported STL", s)
Colin Crossca860ac2016-01-04 14:34:37 -0800116 return ""
117 }
118 }
119 }()
120}
121
Peter Collingbournedc4f9862020-02-12 17:13:25 -0800122func staticUnwinder(ctx android.BaseModuleContext) string {
Inseob Kimd4c9f552021-04-08 19:28:28 +0900123 vndkVersion := ctx.Module().(*Module).VndkVersion()
124
125 // Modules using R vndk use different unwinder
126 if vndkVersion == "30" {
127 if ctx.Arch().ArchType == android.Arm {
128 return "libunwind_llvm"
129 } else {
130 return "libgcc_stripped"
131 }
132 }
133
Ryan Prichardb35a85e2021-01-13 19:18:53 -0800134 return "libunwind"
Peter Collingbournedc4f9862020-02-12 17:13:25 -0800135}
136
Colin Crossa8e07cc2016-04-04 15:07:06 -0700137func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Crossca860ac2016-01-04 14:34:37 -0800138 switch stl.Properties.SelectedStl {
139 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700140 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800141 case "libc++", "libc++_static":
142 if stl.Properties.SelectedStl == "libc++" {
143 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
144 } else {
145 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
146 }
Dan Albert2da19cb2019-07-24 12:17:40 -0700147 if ctx.Device() && !ctx.useSdk() {
148 // __cxa_demangle is not a part of libc++.so on the device since
149 // it's large and most processes don't need it. Statically link
150 // libc++demangle into every process so that users still have it if
151 // needed, but the linker won't include this unless it is actually
152 // called.
153 // http://b/138245375
154 deps.StaticLibs = append(deps.StaticLibs, "libc++demangle")
155 }
Dan Willemsen2e47b342016-11-17 01:02:25 -0800156 if ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800157 if ctx.staticBinary() {
Peter Collingbournedc4f9862020-02-12 17:13:25 -0800158 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", staticUnwinder(ctx))
159 } else {
160 deps.StaticUnwinderIfLegacy = true
Colin Crossca860ac2016-01-04 14:34:37 -0800161 }
162 }
163 case "":
164 // None or error.
Peter Collingbournedc4f9862020-02-12 17:13:25 -0800165 if ctx.toolchain().Bionic() && ctx.Module().Name() == "libc++" {
166 deps.StaticUnwinderIfLegacy = true
167 }
Colin Crossca860ac2016-01-04 14:34:37 -0800168 case "ndk_system":
169 // TODO: Make a system STL prebuilt for the NDK.
170 // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
171 // its own includes. The includes are handled in CCBase.Flags().
172 deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
Spandan Das72b8fcb2023-09-05 23:02:27 +0000173 deps.HeaderLibs = append([]string{"ndk_system"}, deps.HeaderLibs...)
Ryan Prichardb1703652018-03-26 16:30:31 -0700174 case "ndk_libc++_shared", "ndk_libc++_static":
175 if stl.Properties.SelectedStl == "ndk_libc++_shared" {
176 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
177 } else {
178 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
179 }
Ryan Prichard4ccd4902021-03-31 15:29:11 -0700180 deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
Colin Crossca860ac2016-01-04 14:34:37 -0800181 default:
182 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
183 }
184
185 return deps
186}
187
Colin Crossa8e07cc2016-04-04 15:07:06 -0700188func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
Colin Crossca860ac2016-01-04 14:34:37 -0800189 switch stl.Properties.SelectedStl {
190 case "libc++", "libc++_static":
Dan Alberta07b8452018-01-11 13:00:46 -0800191 if ctx.Darwin() {
192 // libc++'s headers are annotated with availability macros that
193 // indicate which version of Mac OS was the first to ship with a
194 // libc++ feature available in its *system's* libc++.dylib. We do
195 // not use the system's library, but rather ship our own. As such,
196 // these availability attributes are meaningless for us but cause
197 // build breaks when we try to use code that would not be available
198 // in the system's dylib.
Colin Cross4af21ed2019-11-04 09:37:55 -0800199 flags.Local.CppFlags = append(flags.Local.CppFlags,
Dan Alberta07b8452018-01-11 13:00:46 -0800200 "-D_LIBCPP_DISABLE_AVAILABILITY")
201 }
202
Dan Willemsen2e47b342016-11-17 01:02:25 -0800203 if !ctx.toolchain().Bionic() {
Colin Cross4af21ed2019-11-04 09:37:55 -0800204 flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
Colin Crossf7a17da2019-10-03 15:48:34 -0700205 flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700206 if ctx.Windows() {
Colin Cross4af21ed2019-11-04 09:37:55 -0800207 flags.Local.CppFlags = append(flags.Local.CppFlags,
Ryan Prichard718cf5b2024-01-18 23:57:38 -0800208 // These macros can also be defined by libc++'s __config
209 // or __config_site headers so define them the same way
210 // (i.e. to nothing). Disable visibility annotations since
211 // we're using static libc++.
212 "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=",
213 "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS=",
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700214 // Use Win32 threads in libc++.
Ryan Prichard718cf5b2024-01-18 23:57:38 -0800215 "-D_LIBCPP_HAS_THREAD_API_WIN32=")
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700216 }
Colin Crossca860ac2016-01-04 14:34:37 -0800217 }
218 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700219 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800220 case "ndk_system":
Spandan Das72b8fcb2023-09-05 23:02:27 +0000221 // Nothing: The exports of ndk_system will be added automatically to the local cflags
Colin Crossca860ac2016-01-04 14:34:37 -0800222 case "ndk_libc++_shared", "ndk_libc++_static":
Christopher Ferrisc3a1e222019-04-10 17:57:50 -0700223 if ctx.Arch().ArchType == android.Arm {
224 // Make sure the _Unwind_XXX symbols are not re-exported.
Colin Cross4af21ed2019-11-04 09:37:55 -0800225 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind.a")
Christopher Ferrisc3a1e222019-04-10 17:57:50 -0700226 }
Colin Crossca860ac2016-01-04 14:34:37 -0800227 case "":
228 // None or error.
Dan Willemsen2e47b342016-11-17 01:02:25 -0800229 if !ctx.toolchain().Bionic() {
Colin Cross4af21ed2019-11-04 09:37:55 -0800230 flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
Colin Crossf7a17da2019-10-03 15:48:34 -0700231 flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
Colin Crossca860ac2016-01-04 14:34:37 -0800232 }
233 default:
234 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
235 }
236
237 return flags
238}