blob: 8eee6124deaabb1acd478ef763db24028b3d3764 [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"
20)
21
Colin Crossb60190a2018-09-04 16:28:17 -070022func getNdkStlFamily(m *Module) string {
23 family, _ := getNdkStlFamilyAndLinkType(m)
24 return family
25}
26
27func getNdkStlFamilyAndLinkType(m *Module) (string, string) {
Dan Albert202fe492017-12-15 13:56:59 -080028 stl := m.stl.Properties.SelectedStl
29 switch stl {
Colin Crossb60190a2018-09-04 16:28:17 -070030 case "ndk_libc++_shared":
31 return "libc++", "shared"
32 case "ndk_libc++_static":
33 return "libc++", "static"
Dan Albert202fe492017-12-15 13:56:59 -080034 case "ndk_system":
Colin Crossb60190a2018-09-04 16:28:17 -070035 return "system", "shared"
Dan Albert202fe492017-12-15 13:56:59 -080036 case "":
Colin Crossb60190a2018-09-04 16:28:17 -070037 return "none", "none"
Dan Albert202fe492017-12-15 13:56:59 -080038 default:
Colin Crossb60190a2018-09-04 16:28:17 -070039 panic(fmt.Errorf("stl: %q is not a valid STL", stl))
Dan Albert202fe492017-12-15 13:56:59 -080040 }
41}
42
Colin Crossca860ac2016-01-04 14:34:37 -080043type StlProperties struct {
Dan Albert749fc782018-01-04 14:21:14 -080044 // Select the STL library to use. Possible values are "libc++",
45 // "libc++_static", "libstdc++", or "none". Leave blank to select the
46 // default.
Colin Cross245ced72017-07-20 16:57:46 -070047 Stl *string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -080048
49 SelectedStl string `blueprint:"mutated"`
50}
51
Colin Crossa8e07cc2016-04-04 15:07:06 -070052type stl struct {
Colin Crossca860ac2016-01-04 14:34:37 -080053 Properties StlProperties
54}
55
Colin Crossa8e07cc2016-04-04 15:07:06 -070056func (stl *stl) props() []interface{} {
Colin Crossca860ac2016-01-04 14:34:37 -080057 return []interface{}{&stl.Properties}
58}
59
Colin Crossa8e07cc2016-04-04 15:07:06 -070060func (stl *stl) begin(ctx BaseModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -080061 stl.Properties.SelectedStl = func() string {
Colin Cross79248852016-07-12 13:12:33 -070062 s := ""
63 if stl.Properties.Stl != nil {
64 s = *stl.Properties.Stl
65 }
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070066 if ctx.useSdk() && ctx.Device() {
Colin Cross79248852016-07-12 13:12:33 -070067 switch s {
Colin Crossca860ac2016-01-04 14:34:37 -080068 case "":
69 return "ndk_system"
Dan Albert749fc782018-01-04 14:21:14 -080070 case "c++_shared", "c++_static":
Colin Cross79248852016-07-12 13:12:33 -070071 return "ndk_lib" + s
David Benjamin87f9f032017-01-25 14:10:04 -050072 case "libc++":
73 return "ndk_libc++_shared"
74 case "libc++_static":
75 return "ndk_libc++_static"
Colin Cross4a97cb42016-04-21 15:53:42 -070076 case "none":
77 return ""
Colin Crossca860ac2016-01-04 14:34:37 -080078 default:
Colin Cross79248852016-07-12 13:12:33 -070079 ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
Colin Crossca860ac2016-01-04 14:34:37 -080080 return ""
81 }
Colin Cross3edeee12017-04-04 12:59:48 -070082 } else if ctx.Windows() {
Colin Cross79248852016-07-12 13:12:33 -070083 switch s {
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -070084 case "libc++", "libc++_static", "":
85 // Only use static libc++ for Windows.
86 return "libc++_static"
Colin Crossca860ac2016-01-04 14:34:37 -080087 case "none":
88 return ""
89 default:
Colin Cross79248852016-07-12 13:12:33 -070090 ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
Colin Crossca860ac2016-01-04 14:34:37 -080091 return ""
92 }
93 } else {
Colin Cross79248852016-07-12 13:12:33 -070094 switch s {
Dan Willemsen141d5662016-06-15 13:47:51 -070095 case "libc++", "libc++_static":
Colin Cross79248852016-07-12 13:12:33 -070096 return s
Colin Crossca860ac2016-01-04 14:34:37 -080097 case "none":
98 return ""
99 case "":
100 if ctx.static() {
101 return "libc++_static"
102 } else {
103 return "libc++"
104 }
105 default:
Colin Cross79248852016-07-12 13:12:33 -0700106 ctx.ModuleErrorf("stl: %q is not a supported STL", s)
Colin Crossca860ac2016-01-04 14:34:37 -0800107 return ""
108 }
109 }
110 }()
111}
112
Colin Crossa8e07cc2016-04-04 15:07:06 -0700113func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Crossca860ac2016-01-04 14:34:37 -0800114 switch stl.Properties.SelectedStl {
115 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700116 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800117 case "libc++", "libc++_static":
118 if stl.Properties.SelectedStl == "libc++" {
119 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
120 } else {
121 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
122 }
Dan Willemsen2e47b342016-11-17 01:02:25 -0800123 if ctx.toolchain().Bionic() {
Colin Cross635c3b02016-05-18 15:37:25 -0700124 if ctx.Arch().ArchType == android.Arm {
Colin Crossca860ac2016-01-04 14:34:37 -0800125 deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
126 }
127 if ctx.staticBinary() {
Colin Cross3d92b272016-07-14 15:59:32 -0700128 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Crossca860ac2016-01-04 14:34:37 -0800129 }
130 }
131 case "":
132 // None or error.
133 case "ndk_system":
134 // TODO: Make a system STL prebuilt for the NDK.
135 // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
136 // its own includes. The includes are handled in CCBase.Flags().
137 deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
Ryan Prichardb1703652018-03-26 16:30:31 -0700138 case "ndk_libc++_shared", "ndk_libc++_static":
139 if stl.Properties.SelectedStl == "ndk_libc++_shared" {
140 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
141 } else {
142 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
143 }
144 deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
145 if ctx.Arch().ArchType == android.Arm {
146 deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
147 }
Colin Crossca860ac2016-01-04 14:34:37 -0800148 default:
149 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
150 }
151
152 return deps
153}
154
Colin Crossa8e07cc2016-04-04 15:07:06 -0700155func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
Colin Crossca860ac2016-01-04 14:34:37 -0800156 switch stl.Properties.SelectedStl {
157 case "libc++", "libc++_static":
158 flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
Dan Alberta07b8452018-01-11 13:00:46 -0800159
160 if ctx.Darwin() {
161 // libc++'s headers are annotated with availability macros that
162 // indicate which version of Mac OS was the first to ship with a
163 // libc++ feature available in its *system's* libc++.dylib. We do
164 // not use the system's library, but rather ship our own. As such,
165 // these availability attributes are meaningless for us but cause
166 // build breaks when we try to use code that would not be available
167 // in the system's dylib.
168 flags.CppFlags = append(flags.CppFlags,
169 "-D_LIBCPP_DISABLE_AVAILABILITY")
170 }
171
Dan Willemsen2e47b342016-11-17 01:02:25 -0800172 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800173 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
174 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
Colin Crossca860ac2016-01-04 14:34:37 -0800175 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700176 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800177 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700178 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800179 }
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700180 if ctx.Windows() {
181 // Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj
182 // exception model for 32-bit.
183 if ctx.Arch().ArchType == android.X86 {
184 flags.CppFlags = append(flags.CppFlags, "-fsjlj-exceptions")
185 }
186 flags.CppFlags = append(flags.CppFlags,
187 // Disable visiblity annotations since we're using static
188 // libc++.
189 "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
190 "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
191 // Use Win32 threads in libc++.
192 "-D_LIBCPP_HAS_THREAD_API_WIN32")
193 }
Colin Crossca860ac2016-01-04 14:34:37 -0800194 } else {
Colin Cross635c3b02016-05-18 15:37:25 -0700195 if ctx.Arch().ArchType == android.Arm {
Colin Crossca860ac2016-01-04 14:34:37 -0800196 flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
197 }
198 }
199 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700200 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800201 case "ndk_system":
Colin Cross635c3b02016-05-18 15:37:25 -0700202 ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
Colin Crossca860ac2016-01-04 14:34:37 -0800203 flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String())
204 case "ndk_libc++_shared", "ndk_libc++_static":
Elliott Hughes5789ca92018-02-16 17:15:19 -0800205 // Nothing.
Colin Crossca860ac2016-01-04 14:34:37 -0800206 case "":
207 // None or error.
Dan Willemsen2e47b342016-11-17 01:02:25 -0800208 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800209 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
210 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
211 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700212 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800213 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700214 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800215 }
216 }
217 default:
218 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
219 }
220
221 return flags
222}
223
Colin Crossa1ad8d12016-06-01 17:09:44 -0700224var hostDynamicGccLibs, hostStaticGccLibs map[android.OsType][]string
Colin Crossca860ac2016-01-04 14:34:37 -0800225
226func init() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700227 hostDynamicGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700228 android.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
229 android.Darwin: []string{"-lc", "-lSystem"},
Pirama Arumuga Nainara403cc72018-08-08 10:28:12 -0700230 android.Windows: []string{"-Wl,--start-group", "-lmingw32", "-lgcc", "-lgcc_eh",
231 "-lmoldname", "-lmingwex", "-lmsvcr110", "-lmsvcrt", "-lpthread",
232 "-ladvapi32", "-lshell32", "-luser32", "-lkernel32", "-lpsapi",
233 "-Wl,--end-group"},
Colin Crossca860ac2016-01-04 14:34:37 -0800234 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700235 hostStaticGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700236 android.Linux: []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
237 android.Darwin: []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
238 android.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
Colin Crossca860ac2016-01-04 14:34:37 -0800239 }
240}