blob: 487087015808b3e1d4a3976e6c92a0dae259fc99 [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
Colin Crossb60190a2018-09-04 16:28:17 -070023func getNdkStlFamily(m *Module) string {
24 family, _ := getNdkStlFamilyAndLinkType(m)
25 return family
26}
27
28func getNdkStlFamilyAndLinkType(m *Module) (string, string) {
Dan Albert202fe492017-12-15 13:56:59 -080029 stl := m.stl.Properties.SelectedStl
30 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 {
Colin Crossca860ac2016-01-04 14:34:37 -080069 case "":
70 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 }
94 } else {
Colin Cross79248852016-07-12 13:12:33 -070095 switch s {
Dan Willemsen141d5662016-06-15 13:47:51 -070096 case "libc++", "libc++_static":
Colin Cross79248852016-07-12 13:12:33 -070097 return s
Colin Crossca860ac2016-01-04 14:34:37 -080098 case "none":
99 return ""
100 case "":
101 if ctx.static() {
102 return "libc++_static"
103 } else {
104 return "libc++"
105 }
106 default:
Colin Cross79248852016-07-12 13:12:33 -0700107 ctx.ModuleErrorf("stl: %q is not a supported STL", s)
Colin Crossca860ac2016-01-04 14:34:37 -0800108 return ""
109 }
110 }
111 }()
112}
113
Dan Albert90b9bbc2018-11-15 11:29:28 -0800114func needsLibAndroidSupport(ctx BaseModuleContext) bool {
115 versionStr, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch())
116 if err != nil {
117 ctx.PropertyErrorf("sdk_version", err.Error())
118 }
119
120 if versionStr == "current" {
121 return false
122 }
123
124 version, err := strconv.Atoi(versionStr)
125 if err != nil {
126 panic(fmt.Sprintf(
127 "invalid API level returned from normalizeNdkApiLevel: %q",
128 versionStr))
129 }
130
131 return version < 21
132}
133
Colin Crossa8e07cc2016-04-04 15:07:06 -0700134func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Crossca860ac2016-01-04 14:34:37 -0800135 switch stl.Properties.SelectedStl {
136 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700137 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800138 case "libc++", "libc++_static":
139 if stl.Properties.SelectedStl == "libc++" {
140 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
141 } else {
142 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
143 }
Dan Willemsen2e47b342016-11-17 01:02:25 -0800144 if ctx.toolchain().Bionic() {
Colin Cross635c3b02016-05-18 15:37:25 -0700145 if ctx.Arch().ArchType == android.Arm {
Colin Crossca860ac2016-01-04 14:34:37 -0800146 deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
147 }
148 if ctx.staticBinary() {
Colin Cross3d92b272016-07-14 15:59:32 -0700149 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Crossca860ac2016-01-04 14:34:37 -0800150 }
151 }
152 case "":
153 // None or error.
154 case "ndk_system":
155 // TODO: Make a system STL prebuilt for the NDK.
156 // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
157 // its own includes. The includes are handled in CCBase.Flags().
158 deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
Ryan Prichardb1703652018-03-26 16:30:31 -0700159 case "ndk_libc++_shared", "ndk_libc++_static":
160 if stl.Properties.SelectedStl == "ndk_libc++_shared" {
161 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
162 } else {
163 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
164 }
Dan Albert90b9bbc2018-11-15 11:29:28 -0800165 if needsLibAndroidSupport(ctx) {
166 deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
167 }
Ryan Prichardb1703652018-03-26 16:30:31 -0700168 if ctx.Arch().ArchType == android.Arm {
169 deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
170 }
Colin Crossca860ac2016-01-04 14:34:37 -0800171 default:
172 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
173 }
174
175 return deps
176}
177
Colin Crossa8e07cc2016-04-04 15:07:06 -0700178func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
Colin Crossca860ac2016-01-04 14:34:37 -0800179 switch stl.Properties.SelectedStl {
180 case "libc++", "libc++_static":
181 flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
Dan Alberta07b8452018-01-11 13:00:46 -0800182
183 if ctx.Darwin() {
184 // libc++'s headers are annotated with availability macros that
185 // indicate which version of Mac OS was the first to ship with a
186 // libc++ feature available in its *system's* libc++.dylib. We do
187 // not use the system's library, but rather ship our own. As such,
188 // these availability attributes are meaningless for us but cause
189 // build breaks when we try to use code that would not be available
190 // in the system's dylib.
191 flags.CppFlags = append(flags.CppFlags,
192 "-D_LIBCPP_DISABLE_AVAILABILITY")
193 }
194
Dan Willemsen2e47b342016-11-17 01:02:25 -0800195 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800196 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
197 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
Colin Crossca860ac2016-01-04 14:34:37 -0800198 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700199 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800200 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700201 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800202 }
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700203 if ctx.Windows() {
204 // Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj
205 // exception model for 32-bit.
206 if ctx.Arch().ArchType == android.X86 {
207 flags.CppFlags = append(flags.CppFlags, "-fsjlj-exceptions")
208 }
209 flags.CppFlags = append(flags.CppFlags,
210 // Disable visiblity annotations since we're using static
211 // libc++.
212 "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
213 "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
214 // Use Win32 threads in libc++.
215 "-D_LIBCPP_HAS_THREAD_API_WIN32")
216 }
Colin Crossca860ac2016-01-04 14:34:37 -0800217 } else {
Colin Cross635c3b02016-05-18 15:37:25 -0700218 if ctx.Arch().ArchType == android.Arm {
Colin Crossca860ac2016-01-04 14:34:37 -0800219 flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
220 }
221 }
222 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700223 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800224 case "ndk_system":
Colin Cross635c3b02016-05-18 15:37:25 -0700225 ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
Colin Crossca860ac2016-01-04 14:34:37 -0800226 flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String())
227 case "ndk_libc++_shared", "ndk_libc++_static":
Elliott Hughes5789ca92018-02-16 17:15:19 -0800228 // Nothing.
Colin Crossca860ac2016-01-04 14:34:37 -0800229 case "":
230 // None or error.
Dan Willemsen2e47b342016-11-17 01:02:25 -0800231 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800232 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
233 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
234 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700235 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800236 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700237 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800238 }
239 }
240 default:
241 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
242 }
243
244 return flags
245}
246
Colin Crossa1ad8d12016-06-01 17:09:44 -0700247var hostDynamicGccLibs, hostStaticGccLibs map[android.OsType][]string
Colin Crossca860ac2016-01-04 14:34:37 -0800248
249func init() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700250 hostDynamicGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700251 android.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
252 android.Darwin: []string{"-lc", "-lSystem"},
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700253 android.Windows: []string{"-Wl,--start-group", "-lmingw32", "-lgcc", "-lgcc_eh",
Pirama Arumuga Nainar087bba72018-11-29 17:19:25 -0800254 "-lmoldname", "-lmingwex", "-lmsvcrt", "-lucrt", "-lpthread",
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700255 "-ladvapi32", "-lshell32", "-luser32", "-lkernel32", "-lpsapi",
256 "-Wl,--end-group"},
Colin Crossca860ac2016-01-04 14:34:37 -0800257 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700258 hostStaticGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700259 android.Linux: []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
260 android.Darwin: []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
261 android.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
Colin Crossca860ac2016-01-04 14:34:37 -0800262 }
263}