blob: 6f63835c4d03503c823940d5b1aa0b32c4f26e9d [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++"
Dan Albert202fe492017-12-15 13:56:59 -080027 case "ndk_system":
28 return "system"
29 case "":
30 return "none"
31 default:
32 ctx.ModuleErrorf("stl: %q is not a valid STL", stl)
33 return ""
34 }
35}
36
Colin Crossca860ac2016-01-04 14:34:37 -080037type StlProperties struct {
Dan Albert749fc782018-01-04 14:21:14 -080038 // Select the STL library to use. Possible values are "libc++",
39 // "libc++_static", "libstdc++", or "none". Leave blank to select the
40 // default.
Colin Cross245ced72017-07-20 16:57:46 -070041 Stl *string `android:"arch_variant"`
Colin Crossca860ac2016-01-04 14:34:37 -080042
43 SelectedStl string `blueprint:"mutated"`
44}
45
Colin Crossa8e07cc2016-04-04 15:07:06 -070046type stl struct {
Colin Crossca860ac2016-01-04 14:34:37 -080047 Properties StlProperties
48}
49
Colin Crossa8e07cc2016-04-04 15:07:06 -070050func (stl *stl) props() []interface{} {
Colin Crossca860ac2016-01-04 14:34:37 -080051 return []interface{}{&stl.Properties}
52}
53
Colin Crossa8e07cc2016-04-04 15:07:06 -070054func (stl *stl) begin(ctx BaseModuleContext) {
Colin Crossca860ac2016-01-04 14:34:37 -080055 stl.Properties.SelectedStl = func() string {
Colin Cross79248852016-07-12 13:12:33 -070056 s := ""
57 if stl.Properties.Stl != nil {
58 s = *stl.Properties.Stl
59 }
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070060 if ctx.useSdk() && ctx.Device() {
Colin Cross79248852016-07-12 13:12:33 -070061 switch s {
Colin Crossca860ac2016-01-04 14:34:37 -080062 case "":
63 return "ndk_system"
Dan Albert749fc782018-01-04 14:21:14 -080064 case "c++_shared", "c++_static":
Colin Cross79248852016-07-12 13:12:33 -070065 return "ndk_lib" + s
David Benjamin87f9f032017-01-25 14:10:04 -050066 case "libc++":
67 return "ndk_libc++_shared"
68 case "libc++_static":
69 return "ndk_libc++_static"
Colin Cross4a97cb42016-04-21 15:53:42 -070070 case "none":
71 return ""
Colin Crossca860ac2016-01-04 14:34:37 -080072 default:
Colin Cross79248852016-07-12 13:12:33 -070073 ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
Colin Crossca860ac2016-01-04 14:34:37 -080074 return ""
75 }
Colin Cross3edeee12017-04-04 12:59:48 -070076 } else if ctx.Windows() {
Colin Cross79248852016-07-12 13:12:33 -070077 switch s {
Colin Crossca860ac2016-01-04 14:34:37 -080078 case "libc++", "libc++_static", "libstdc++", "":
79 // libc++ is not supported on mingw
80 return "libstdc++"
81 case "none":
82 return ""
83 default:
Colin Cross79248852016-07-12 13:12:33 -070084 ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
Colin Crossca860ac2016-01-04 14:34:37 -080085 return ""
86 }
87 } else {
Colin Cross79248852016-07-12 13:12:33 -070088 switch s {
Dan Willemsen141d5662016-06-15 13:47:51 -070089 case "libc++", "libc++_static":
Colin Cross79248852016-07-12 13:12:33 -070090 return s
Colin Crossca860ac2016-01-04 14:34:37 -080091 case "none":
92 return ""
93 case "":
94 if ctx.static() {
95 return "libc++_static"
96 } else {
97 return "libc++"
98 }
99 default:
Colin Cross79248852016-07-12 13:12:33 -0700100 ctx.ModuleErrorf("stl: %q is not a supported STL", s)
Colin Crossca860ac2016-01-04 14:34:37 -0800101 return ""
102 }
103 }
104 }()
105}
106
Colin Crossa8e07cc2016-04-04 15:07:06 -0700107func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
Colin Crossca860ac2016-01-04 14:34:37 -0800108 switch stl.Properties.SelectedStl {
109 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700110 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800111 case "libc++", "libc++_static":
112 if stl.Properties.SelectedStl == "libc++" {
113 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
114 } else {
115 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
116 }
Dan Willemsen2e47b342016-11-17 01:02:25 -0800117 if ctx.toolchain().Bionic() {
Colin Cross635c3b02016-05-18 15:37:25 -0700118 if ctx.Arch().ArchType == android.Arm {
Colin Crossca860ac2016-01-04 14:34:37 -0800119 deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
120 }
121 if ctx.staticBinary() {
Colin Cross3d92b272016-07-14 15:59:32 -0700122 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
Colin Crossca860ac2016-01-04 14:34:37 -0800123 }
124 }
125 case "":
126 // None or error.
127 case "ndk_system":
128 // TODO: Make a system STL prebuilt for the NDK.
129 // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
130 // its own includes. The includes are handled in CCBase.Flags().
131 deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
Ryan Prichardb1703652018-03-26 16:30:31 -0700132 case "ndk_libc++_shared", "ndk_libc++_static":
133 if stl.Properties.SelectedStl == "ndk_libc++_shared" {
134 deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
135 } else {
136 deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
137 }
138 deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
139 if ctx.Arch().ArchType == android.Arm {
140 deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
141 }
Colin Crossca860ac2016-01-04 14:34:37 -0800142 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 Alberta07b8452018-01-11 13:00:46 -0800153
154 if ctx.Darwin() {
155 // libc++'s headers are annotated with availability macros that
156 // indicate which version of Mac OS was the first to ship with a
157 // libc++ feature available in its *system's* libc++.dylib. We do
158 // not use the system's library, but rather ship our own. As such,
159 // these availability attributes are meaningless for us but cause
160 // build breaks when we try to use code that would not be available
161 // in the system's dylib.
162 flags.CppFlags = append(flags.CppFlags,
163 "-D_LIBCPP_DISABLE_AVAILABILITY")
164 }
165
Dan Willemsen2e47b342016-11-17 01:02:25 -0800166 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800167 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
168 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
Colin Crossca860ac2016-01-04 14:34:37 -0800169 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700170 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800171 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700172 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800173 }
174 } else {
Colin Cross635c3b02016-05-18 15:37:25 -0700175 if ctx.Arch().ArchType == android.Arm {
Colin Crossca860ac2016-01-04 14:34:37 -0800176 flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
177 }
178 }
179 case "libstdc++":
Dan Willemsen141d5662016-06-15 13:47:51 -0700180 // Nothing
Colin Crossca860ac2016-01-04 14:34:37 -0800181 case "ndk_system":
Colin Cross635c3b02016-05-18 15:37:25 -0700182 ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
Colin Crossca860ac2016-01-04 14:34:37 -0800183 flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String())
184 case "ndk_libc++_shared", "ndk_libc++_static":
Elliott Hughes5789ca92018-02-16 17:15:19 -0800185 // Nothing.
Colin Crossca860ac2016-01-04 14:34:37 -0800186 case "":
187 // None or error.
Dan Willemsen2e47b342016-11-17 01:02:25 -0800188 if !ctx.toolchain().Bionic() {
Colin Crossca860ac2016-01-04 14:34:37 -0800189 flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
190 flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
191 if ctx.staticBinary() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700192 flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800193 } else {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700194 flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.Os()]...)
Colin Crossca860ac2016-01-04 14:34:37 -0800195 }
196 }
197 default:
198 panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
199 }
200
201 return flags
202}
203
Colin Crossa1ad8d12016-06-01 17:09:44 -0700204var hostDynamicGccLibs, hostStaticGccLibs map[android.OsType][]string
Colin Crossca860ac2016-01-04 14:34:37 -0800205
206func init() {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700207 hostDynamicGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700208 android.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
209 android.Darwin: []string{"-lc", "-lSystem"},
210 android.Windows: []string{"-lmsvcr110", "-lmingw32", "-lgcc", "-lmoldname",
Colin Crossca860ac2016-01-04 14:34:37 -0800211 "-lmingwex", "-lmsvcrt", "-ladvapi32", "-lshell32", "-luser32",
212 "-lkernel32", "-lmingw32", "-lgcc", "-lmoldname", "-lmingwex",
213 "-lmsvcrt"},
214 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700215 hostStaticGccLibs = map[android.OsType][]string{
Colin Cross635c3b02016-05-18 15:37:25 -0700216 android.Linux: []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
217 android.Darwin: []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
218 android.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
Colin Crossca860ac2016-01-04 14:34:37 -0800219 }
220}