blob: 338db84c30e6c8455cd939b4a4880c665af3fba1 [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
Dan Albert202fe492017-12-15 13:56:59 -080022func getNdkStlFamily(ctx android.ModuleContext, m *Module) string {
23 stl := m.stl.Properties.SelectedStl
24 switch stl {
25 case "ndk_libc++_shared", "ndk_libc++_static":
26 return "libc++"
27 case "ndk_libstlport_shared", "ndk_libstlport_static":
28 return "stlport"
29 case "ndk_libgnustl_static":
30 return "gnustl"
31 case "ndk_system":
32 return "system"
33 case "":
34 return "none"
35 default:
36 ctx.ModuleErrorf("stl: %q is not a valid STL", stl)
37 return ""
38 }
39}
40
Colin Crossca860ac2016-01-04 14:34:37 -080041type StlProperties struct {
42 // select the STL library to use. Possible values are "libc++", "libc++_static",
43 // "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
44 // default
Colin Cross245ced72017-07-20 16:57:46 -070045 Stl *string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -080046
47 SelectedStl string `blueprint:"mutated"`
48}
49
Colin Crossa8e07cc2016-04-04 15:07:06 -070050type stl struct {
Colin Crossca860ac2016-01-04 14:34:37 -080051 Properties StlProperties
52}
53
Colin Crossa8e07cc2016-04-04 15:07:06 -070054func (stl *stl) props() []interface{} {
Colin Crossca860ac2016-01-04 14:34:37 -080055 return []interface{}{&stl.Properties}
56}
57
Colin Crossa8e07cc2016-04-04 15:07:06 -070058func (stl *stl) begin(ctx BaseModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -080059 stl.Properties.SelectedStl = func() string {
Colin Cross79248852016-07-12 13:12:33 -070060 s := ""
61 if stl.Properties.Stl != nil {
62 s = *stl.Properties.Stl
63 }
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070064 if ctx.useSdk() && ctx.Device() {
Colin Cross79248852016-07-12 13:12:33 -070065 switch s {
Colin Crossca860ac2016-01-04 14:34:37 -080066 case "":
67 return "ndk_system"
68 case "c++_shared", "c++_static",
69 "stlport_shared", "stlport_static",
70 "gnustl_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 {
Colin Crossca860ac2016-01-04 14:34:37 -080084 case "libc++", "libc++_static", "libstdc++", "":
85 // libc++ is not supported on mingw
86 return "libstdc++"
87 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...)
Colin Crossef88ae22017-08-18 16:52:25 -0700138 case "ndk_libc++_shared", "ndk_libstlport_shared":
Colin Crossca860ac2016-01-04 14:34:37 -0800139 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
Colin Crossef88ae22017-08-18 16:52:25 -0700140 case "ndk_libc++_static", "ndk_libstlport_static", "ndk_libgnustl_static":
Colin Crossca860ac2016-01-04 14:34:37 -0800141 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
142 default:
143 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
144 }
145
146 return deps
147}
148
Colin Crossa8e07cc2016-04-04 15:07:06 -0700149func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
Colin Crossca860ac2016-01-04 14:34:37 -0800150 switch stl.Properties.SelectedStl {
151 case "libc++", "libc++_static":
152 flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
Dan Willemsen2e47b342016-11-17 01:02:25 -0800153 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800154 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
155 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
Colin Crossca860ac2016-01-04 14:34:37 -0800156 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700157 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800158 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700159 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800160 }
161 } else {
Colin Cross635c3b02016-05-18 15:37:25 -0700162 if ctx.Arch().ArchType == android.Arm {
Colin Crossca860ac2016-01-04 14:34:37 -0800163 flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
164 }
165 }
166 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700167 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800168 case "ndk_system":
Colin Cross635c3b02016-05-18 15:37:25 -0700169 ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
Colin Crossca860ac2016-01-04 14:34:37 -0800170 flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String())
171 case "ndk_libc++_shared", "ndk_libc++_static":
172 // TODO(danalbert): This really shouldn't be here...
173 flags.CppFlags = append(flags.CppFlags, "-std=c++11")
174 case "ndk_libstlport_shared", "ndk_libstlport_static", "ndk_libgnustl_static":
175 // Nothing
176 case "":
177 // None or error.
Dan Willemsen2e47b342016-11-17 01:02:25 -0800178 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800179 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
180 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
181 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700182 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800183 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700184 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800185 }
186 }
187 default:
188 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
189 }
190
191 return flags
192}
193
Colin Crossa1ad8d12016-06-01 17:09:44 -0700194var hostDynamicGccLibs, hostStaticGccLibs map[android.OsType][]string
Colin Crossca860ac2016-01-04 14:34:37 -0800195
196func init() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700197 hostDynamicGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700198 android.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
199 android.Darwin: []string{"-lc", "-lSystem"},
200 android.Windows: []string{"-lmsvcr110", "-lmingw32", "-lgcc", "-lmoldname",
Colin Crossca860ac2016-01-04 14:34:37 -0800201 "-lmingwex", "-lmsvcrt", "-ladvapi32", "-lshell32", "-luser32",
202 "-lkernel32", "-lmingw32", "-lgcc", "-lmoldname", "-lmingwex",
203 "-lmsvcrt"},
204 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700205 hostStaticGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700206 android.Linux: []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
207 android.Darwin: []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
208 android.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
Colin Crossca860ac2016-01-04 14:34:37 -0800209 }
210}