xref: /aosp_15_r20/build/soong/cc/stl.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage cc
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker
20*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
21*333d2b36SAndroid Build Coastguard Worker)
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Workerfunc getNdkStlFamily(m LinkableInterface) string {
24*333d2b36SAndroid Build Coastguard Worker	family, _ := getNdkStlFamilyAndLinkType(m)
25*333d2b36SAndroid Build Coastguard Worker	return family
26*333d2b36SAndroid Build Coastguard Worker}
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Workerfunc deduplicateStlInput(stl string) string {
29*333d2b36SAndroid Build Coastguard Worker	switch stl {
30*333d2b36SAndroid Build Coastguard Worker	case "c++_shared":
31*333d2b36SAndroid Build Coastguard Worker		return "libc++"
32*333d2b36SAndroid Build Coastguard Worker	case "c++_static":
33*333d2b36SAndroid Build Coastguard Worker		return "libc++_static"
34*333d2b36SAndroid Build Coastguard Worker	}
35*333d2b36SAndroid Build Coastguard Worker	return stl
36*333d2b36SAndroid Build Coastguard Worker}
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Workerfunc getNdkStlFamilyAndLinkType(m LinkableInterface) (string, string) {
39*333d2b36SAndroid Build Coastguard Worker	stl := m.SelectedStl()
40*333d2b36SAndroid Build Coastguard Worker	switch stl {
41*333d2b36SAndroid Build Coastguard Worker	case "ndk_libc++_shared", "libc++":
42*333d2b36SAndroid Build Coastguard Worker		return "libc++", "shared"
43*333d2b36SAndroid Build Coastguard Worker	case "ndk_libc++_static", "libc++_static":
44*333d2b36SAndroid Build Coastguard Worker		return "libc++", "static"
45*333d2b36SAndroid Build Coastguard Worker	case "ndk_system":
46*333d2b36SAndroid Build Coastguard Worker		return "system", "shared"
47*333d2b36SAndroid Build Coastguard Worker	case "":
48*333d2b36SAndroid Build Coastguard Worker		return "none", "none"
49*333d2b36SAndroid Build Coastguard Worker	default:
50*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("stl: %q is not a valid STL", stl))
51*333d2b36SAndroid Build Coastguard Worker	}
52*333d2b36SAndroid Build Coastguard Worker}
53*333d2b36SAndroid Build Coastguard Worker
54*333d2b36SAndroid Build Coastguard Workertype StlProperties struct {
55*333d2b36SAndroid Build Coastguard Worker	// Select the STL library to use.  Possible values are "libc++",
56*333d2b36SAndroid Build Coastguard Worker	// "libc++_static", "libstdc++", or "none". Leave blank to select the
57*333d2b36SAndroid Build Coastguard Worker	// default.
58*333d2b36SAndroid Build Coastguard Worker	Stl *string `android:"arch_variant"`
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker	SelectedStl string `blueprint:"mutated"`
61*333d2b36SAndroid Build Coastguard Worker}
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Workertype stl struct {
64*333d2b36SAndroid Build Coastguard Worker	Properties StlProperties
65*333d2b36SAndroid Build Coastguard Worker}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Workerfunc (stl *stl) props() []interface{} {
68*333d2b36SAndroid Build Coastguard Worker	return []interface{}{&stl.Properties}
69*333d2b36SAndroid Build Coastguard Worker}
70*333d2b36SAndroid Build Coastguard Worker
71*333d2b36SAndroid Build Coastguard Workerfunc (stl *stl) begin(ctx BaseModuleContext) {
72*333d2b36SAndroid Build Coastguard Worker	stl.Properties.SelectedStl = func() string {
73*333d2b36SAndroid Build Coastguard Worker		s := ""
74*333d2b36SAndroid Build Coastguard Worker		if stl.Properties.Stl != nil {
75*333d2b36SAndroid Build Coastguard Worker			s = *stl.Properties.Stl
76*333d2b36SAndroid Build Coastguard Worker		} else if ctx.header() {
77*333d2b36SAndroid Build Coastguard Worker			s = "none"
78*333d2b36SAndroid Build Coastguard Worker		}
79*333d2b36SAndroid Build Coastguard Worker		if s == "none" {
80*333d2b36SAndroid Build Coastguard Worker			return ""
81*333d2b36SAndroid Build Coastguard Worker		}
82*333d2b36SAndroid Build Coastguard Worker		s = deduplicateStlInput(s)
83*333d2b36SAndroid Build Coastguard Worker		if ctx.useSdk() && ctx.Device() {
84*333d2b36SAndroid Build Coastguard Worker			switch s {
85*333d2b36SAndroid Build Coastguard Worker			case "", "system":
86*333d2b36SAndroid Build Coastguard Worker				return "ndk_system"
87*333d2b36SAndroid Build Coastguard Worker			case "libc++":
88*333d2b36SAndroid Build Coastguard Worker				return "ndk_libc++_shared"
89*333d2b36SAndroid Build Coastguard Worker			case "libc++_static":
90*333d2b36SAndroid Build Coastguard Worker				return "ndk_libc++_static"
91*333d2b36SAndroid Build Coastguard Worker			default:
92*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
93*333d2b36SAndroid Build Coastguard Worker				return ""
94*333d2b36SAndroid Build Coastguard Worker			}
95*333d2b36SAndroid Build Coastguard Worker		} else if ctx.Windows() {
96*333d2b36SAndroid Build Coastguard Worker			switch s {
97*333d2b36SAndroid Build Coastguard Worker			case "libc++", "libc++_static", "":
98*333d2b36SAndroid Build Coastguard Worker				// Only use static libc++ for Windows.
99*333d2b36SAndroid Build Coastguard Worker				return "libc++_static"
100*333d2b36SAndroid Build Coastguard Worker			default:
101*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
102*333d2b36SAndroid Build Coastguard Worker				return ""
103*333d2b36SAndroid Build Coastguard Worker			}
104*333d2b36SAndroid Build Coastguard Worker		} else {
105*333d2b36SAndroid Build Coastguard Worker			switch s {
106*333d2b36SAndroid Build Coastguard Worker			case "libc++", "libc++_static":
107*333d2b36SAndroid Build Coastguard Worker				return s
108*333d2b36SAndroid Build Coastguard Worker			case "", "system":
109*333d2b36SAndroid Build Coastguard Worker				if ctx.static() {
110*333d2b36SAndroid Build Coastguard Worker					return "libc++_static"
111*333d2b36SAndroid Build Coastguard Worker				} else {
112*333d2b36SAndroid Build Coastguard Worker					return "libc++"
113*333d2b36SAndroid Build Coastguard Worker				}
114*333d2b36SAndroid Build Coastguard Worker			default:
115*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("stl: %q is not a supported STL", s)
116*333d2b36SAndroid Build Coastguard Worker				return ""
117*333d2b36SAndroid Build Coastguard Worker			}
118*333d2b36SAndroid Build Coastguard Worker		}
119*333d2b36SAndroid Build Coastguard Worker	}()
120*333d2b36SAndroid Build Coastguard Worker}
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard Workerfunc staticUnwinder(ctx android.BaseModuleContext) string {
123*333d2b36SAndroid Build Coastguard Worker	vndkVersion := ctx.Module().(*Module).VndkVersion()
124*333d2b36SAndroid Build Coastguard Worker
125*333d2b36SAndroid Build Coastguard Worker	// Modules using R vndk use different unwinder
126*333d2b36SAndroid Build Coastguard Worker	if vndkVersion == "30" {
127*333d2b36SAndroid Build Coastguard Worker		if ctx.Arch().ArchType == android.Arm {
128*333d2b36SAndroid Build Coastguard Worker			return "libunwind_llvm"
129*333d2b36SAndroid Build Coastguard Worker		} else {
130*333d2b36SAndroid Build Coastguard Worker			return "libgcc_stripped"
131*333d2b36SAndroid Build Coastguard Worker		}
132*333d2b36SAndroid Build Coastguard Worker	}
133*333d2b36SAndroid Build Coastguard Worker
134*333d2b36SAndroid Build Coastguard Worker	return "libunwind"
135*333d2b36SAndroid Build Coastguard Worker}
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Workerfunc (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
138*333d2b36SAndroid Build Coastguard Worker	switch stl.Properties.SelectedStl {
139*333d2b36SAndroid Build Coastguard Worker	case "libstdc++":
140*333d2b36SAndroid Build Coastguard Worker		// Nothing
141*333d2b36SAndroid Build Coastguard Worker	case "libc++", "libc++_static":
142*333d2b36SAndroid Build Coastguard Worker		if stl.Properties.SelectedStl == "libc++" {
143*333d2b36SAndroid Build Coastguard Worker			deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
144*333d2b36SAndroid Build Coastguard Worker		} else {
145*333d2b36SAndroid Build Coastguard Worker			deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
146*333d2b36SAndroid Build Coastguard Worker		}
147*333d2b36SAndroid Build Coastguard Worker		if ctx.Device() && !ctx.useSdk() {
148*333d2b36SAndroid Build Coastguard Worker			// __cxa_demangle is not a part of libc++.so on the device since
149*333d2b36SAndroid Build Coastguard Worker			// it's large and most processes don't need it. Statically link
150*333d2b36SAndroid Build Coastguard Worker			// libc++demangle into every process so that users still have it if
151*333d2b36SAndroid Build Coastguard Worker			// needed, but the linker won't include this unless it is actually
152*333d2b36SAndroid Build Coastguard Worker			// called.
153*333d2b36SAndroid Build Coastguard Worker			// http://b/138245375
154*333d2b36SAndroid Build Coastguard Worker			deps.StaticLibs = append(deps.StaticLibs, "libc++demangle")
155*333d2b36SAndroid Build Coastguard Worker		}
156*333d2b36SAndroid Build Coastguard Worker		if ctx.toolchain().Bionic() {
157*333d2b36SAndroid Build Coastguard Worker			if ctx.staticBinary() {
158*333d2b36SAndroid Build Coastguard Worker				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", staticUnwinder(ctx))
159*333d2b36SAndroid Build Coastguard Worker			} else {
160*333d2b36SAndroid Build Coastguard Worker				deps.StaticUnwinderIfLegacy = true
161*333d2b36SAndroid Build Coastguard Worker			}
162*333d2b36SAndroid Build Coastguard Worker		}
163*333d2b36SAndroid Build Coastguard Worker	case "":
164*333d2b36SAndroid Build Coastguard Worker		// None or error.
165*333d2b36SAndroid Build Coastguard Worker		if ctx.toolchain().Bionic() && ctx.Module().Name() == "libc++" {
166*333d2b36SAndroid Build Coastguard Worker			deps.StaticUnwinderIfLegacy = true
167*333d2b36SAndroid Build Coastguard Worker		}
168*333d2b36SAndroid Build Coastguard Worker	case "ndk_system":
169*333d2b36SAndroid Build Coastguard Worker		// TODO: Make a system STL prebuilt for the NDK.
170*333d2b36SAndroid Build Coastguard Worker		// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
171*333d2b36SAndroid Build Coastguard Worker		// its own includes. The includes are handled in CCBase.Flags().
172*333d2b36SAndroid Build Coastguard Worker		deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
173*333d2b36SAndroid Build Coastguard Worker		deps.HeaderLibs = append([]string{"ndk_system"}, deps.HeaderLibs...)
174*333d2b36SAndroid Build Coastguard Worker	case "ndk_libc++_shared", "ndk_libc++_static":
175*333d2b36SAndroid Build Coastguard Worker		if stl.Properties.SelectedStl == "ndk_libc++_shared" {
176*333d2b36SAndroid Build Coastguard Worker			deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
177*333d2b36SAndroid Build Coastguard Worker		} else {
178*333d2b36SAndroid Build Coastguard Worker			deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
179*333d2b36SAndroid Build Coastguard Worker		}
180*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = append(deps.StaticLibs, "libunwind")
181*333d2b36SAndroid Build Coastguard Worker	default:
182*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
183*333d2b36SAndroid Build Coastguard Worker	}
184*333d2b36SAndroid Build Coastguard Worker
185*333d2b36SAndroid Build Coastguard Worker	return deps
186*333d2b36SAndroid Build Coastguard Worker}
187*333d2b36SAndroid Build Coastguard Worker
188*333d2b36SAndroid Build Coastguard Workerfunc (stl *stl) flags(ctx ModuleContext, flags Flags) Flags {
189*333d2b36SAndroid Build Coastguard Worker	switch stl.Properties.SelectedStl {
190*333d2b36SAndroid Build Coastguard Worker	case "libc++", "libc++_static":
191*333d2b36SAndroid Build Coastguard Worker		if ctx.Darwin() {
192*333d2b36SAndroid Build Coastguard Worker			// libc++'s headers are annotated with availability macros that
193*333d2b36SAndroid Build Coastguard Worker			// indicate which version of Mac OS was the first to ship with a
194*333d2b36SAndroid Build Coastguard Worker			// libc++ feature available in its *system's* libc++.dylib. We do
195*333d2b36SAndroid Build Coastguard Worker			// not use the system's library, but rather ship our own. As such,
196*333d2b36SAndroid Build Coastguard Worker			// these availability attributes are meaningless for us but cause
197*333d2b36SAndroid Build Coastguard Worker			// build breaks when we try to use code that would not be available
198*333d2b36SAndroid Build Coastguard Worker			// in the system's dylib.
199*333d2b36SAndroid Build Coastguard Worker			flags.Local.CppFlags = append(flags.Local.CppFlags,
200*333d2b36SAndroid Build Coastguard Worker				"-D_LIBCPP_DISABLE_AVAILABILITY")
201*333d2b36SAndroid Build Coastguard Worker		}
202*333d2b36SAndroid Build Coastguard Worker
203*333d2b36SAndroid Build Coastguard Worker		if !ctx.toolchain().Bionic() {
204*333d2b36SAndroid Build Coastguard Worker			flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
205*333d2b36SAndroid Build Coastguard Worker			flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
206*333d2b36SAndroid Build Coastguard Worker			if ctx.Windows() {
207*333d2b36SAndroid Build Coastguard Worker				flags.Local.CppFlags = append(flags.Local.CppFlags,
208*333d2b36SAndroid Build Coastguard Worker					// These macros can also be defined by libc++'s __config
209*333d2b36SAndroid Build Coastguard Worker					// or __config_site headers so define them the same way
210*333d2b36SAndroid Build Coastguard Worker					// (i.e. to nothing). Disable visibility annotations since
211*333d2b36SAndroid Build Coastguard Worker					// we're using static libc++.
212*333d2b36SAndroid Build Coastguard Worker					"-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=",
213*333d2b36SAndroid Build Coastguard Worker					"-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS=",
214*333d2b36SAndroid Build Coastguard Worker					// Use Win32 threads in libc++.
215*333d2b36SAndroid Build Coastguard Worker					"-D_LIBCPP_HAS_THREAD_API_WIN32=")
216*333d2b36SAndroid Build Coastguard Worker			}
217*333d2b36SAndroid Build Coastguard Worker		}
218*333d2b36SAndroid Build Coastguard Worker	case "libstdc++":
219*333d2b36SAndroid Build Coastguard Worker		// Nothing
220*333d2b36SAndroid Build Coastguard Worker	case "ndk_system":
221*333d2b36SAndroid Build Coastguard Worker		// Nothing: The exports of ndk_system will be added automatically to the local cflags
222*333d2b36SAndroid Build Coastguard Worker	case "ndk_libc++_shared", "ndk_libc++_static":
223*333d2b36SAndroid Build Coastguard Worker		if ctx.Arch().ArchType == android.Arm {
224*333d2b36SAndroid Build Coastguard Worker			// Make sure the _Unwind_XXX symbols are not re-exported.
225*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind.a")
226*333d2b36SAndroid Build Coastguard Worker		}
227*333d2b36SAndroid Build Coastguard Worker	case "":
228*333d2b36SAndroid Build Coastguard Worker		// None or error.
229*333d2b36SAndroid Build Coastguard Worker		if !ctx.toolchain().Bionic() {
230*333d2b36SAndroid Build Coastguard Worker			flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
231*333d2b36SAndroid Build Coastguard Worker			flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
232*333d2b36SAndroid Build Coastguard Worker		}
233*333d2b36SAndroid Build Coastguard Worker	default:
234*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
235*333d2b36SAndroid Build Coastguard Worker	}
236*333d2b36SAndroid Build Coastguard Worker
237*333d2b36SAndroid Build Coastguard Worker	return flags
238*333d2b36SAndroid Build Coastguard Worker}
239