1//
2// Copyright (C) 2017 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17package clangprebuilts
18
19import (
20	"path"
21	"strings"
22
23	"github.com/google/blueprint/proptools"
24
25	"android/soong/android"
26	"android/soong/cc"
27	"android/soong/cc/config"
28	"android/soong/genrule"
29)
30
31var (
32	// Files included in the llvm-tools filegroup in ../Android.bp
33	llvmToolsFiles = []string{
34		"bin/llvm-cov",
35		"bin/llvm-cxxfilt",
36		"bin/llvm-profdata",
37		"bin/llvm-symbolizer",
38		"lib/libc++.so",
39		"lib/x86_64-unknown-linux-gnu/libc++.so",
40	}
41)
42
43// This module is used to generate libfuzzer, libomp static libraries and
44// libclang_rt.* shared libraries. When LLVM_PREBUILTS_VERSION and
45// LLVM_RELEASE_VERSION are set, the library will generated from the given
46// path.
47func init() {
48	android.RegisterModuleType("llvm_host_defaults",
49		llvmHostDefaultsFactory)
50	android.RegisterModuleType("llvm_prebuilt_library_shared",
51		llvmPrebuiltLibrarySharedFactory)
52	android.RegisterModuleType("llvm_prebuilt_library_static",
53		llvmPrebuiltLibraryStaticFactory)
54	android.RegisterModuleType("llvm_prebuilt_build_tool",
55		llvmPrebuiltBuildToolFactory)
56	android.RegisterModuleType("ndk_prebuilt_shared_stl",
57		ndkPrebuiltSharedStlFactory)
58	android.RegisterModuleType("ndk_prebuilt_static_stl",
59		ndkPrebuiltStaticStlFactory)
60	android.RegisterModuleType("libclang_rt_prebuilt_library_shared",
61		libClangRtPrebuiltLibrarySharedFactory)
62	android.RegisterModuleType("libclang_rt_prebuilt_library_static",
63		libClangRtPrebuiltLibraryStaticFactory)
64	android.RegisterModuleType("libclang_rt_prebuilt_object",
65		libClangRtPrebuiltObjectFactory)
66	android.RegisterModuleType("llvm_darwin_filegroup",
67		llvmDarwinFileGroupFactory)
68	android.RegisterModuleType("clang_builtin_headers",
69		clangBuiltinHeadersFactory)
70	android.RegisterModuleType("llvm_tools_filegroup",
71		llvmToolsFilegroupFactory)
72}
73
74func getClangPrebuiltDir(ctx android.LoadHookContext) string {
75	return path.Join(
76		"./",
77		ctx.Config().GetenvWithDefault("LLVM_PREBUILTS_VERSION", config.ClangDefaultVersion),
78	)
79}
80
81func getClangResourceDir(ctx android.LoadHookContext) string {
82	clangDir := getClangPrebuiltDir(ctx)
83	releaseVersion := ctx.Config().GetenvWithDefault("LLVM_RELEASE_VERSION",
84		config.ClangDefaultShortVersion)
85	return path.Join(clangDir, "lib", "clang", releaseVersion, "lib", "linux")
86}
87
88func getSymbolFilePath(ctx android.LoadHookContext, arch string) string {
89	libDir := getClangResourceDir(ctx)
90	// Strip the prebuilt_ prefix
91	baseModuleName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
92	return path.Join(libDir, strings.TrimSuffix(baseModuleName, ".llndk")+arch+".map.txt")
93}
94
95func trimVersionNumbers(ver string, retain int) string {
96	sep := "."
97	versions := strings.Split(ver, sep)
98	return strings.Join(versions[0:retain], sep)
99}
100
101func androidLibcxxHeaderDirs(ctx android.LoadHookContext, kind string, arch string) []string {
102	clangDir := getClangPrebuiltDir(ctx)
103	// Ensure that the target-specific __config_site header comes first so it
104	// overrides the default __config_site header.
105	return []string{
106		path.Join(clangDir, "android_libc++", kind, arch, "include", "c++", "v1"),
107		path.Join(clangDir, "include", "c++", "v1"),
108	}
109}
110
111func hostLibcxxHeaderDirs(ctx android.LoadHookContext, triple string) []string {
112	clangDir := getClangPrebuiltDir(ctx)
113	// Ensure that the target-specific __config_site header comes first so it
114	// overrides the default __config_site header.
115	return []string{
116		path.Join(clangDir, "include", triple, "c++", "v1"),
117		path.Join(clangDir, "include", "c++", "v1"),
118	}
119}
120
121// The darwin-x86 directory sometimes isn't checked out on Linux machines, and
122// if it's missing, then the Darwin filegroups won't be defined. For
123// master-plus-llvm, on the other hand, the Darwin filegroups are defined, but
124// the build uses clang-dev instead of clang-rNNNNNN, and clang-dev only exists
125// for linux-x86, not darwin-x86.
126func hasDarwinClangPrebuilt(ctx android.LoadHookContext) bool {
127	return android.ExistentPathForSource(
128		ctx, "prebuilts/clang/host/darwin-x86", getClangPrebuiltDir(ctx),
129		"bin/clang").Valid()
130}
131
132type archInnerProps struct {
133	Enabled             *bool
134	Export_include_dirs []string
135	Srcs                []string
136	Stem                *string
137	Sanitized           struct {
138		None struct {
139			Srcs []string
140		}
141		Hwaddress struct {
142			Srcs []string
143		}
144	}
145	Stubs struct {
146		Symbol_file *string
147	}
148	Llndk struct {
149		Symbol_file *string
150	}
151}
152
153type archProps struct {
154	Android_arm         archInnerProps
155	Android_arm64       archInnerProps
156	Android_riscv64     archInnerProps
157	Android_x86         archInnerProps
158	Android_x86_64      archInnerProps
159	Linux_bionic_arm64  archInnerProps
160	Linux_bionic_x86_64 archInnerProps
161	Glibc_x86           archInnerProps
162	Glibc_x86_64        archInnerProps
163	Linux_musl_x86      archInnerProps
164	Linux_musl_x86_64   archInnerProps
165	Linux_musl_arm      archInnerProps
166	Linux_musl_arm64    archInnerProps
167	Darwin              archInnerProps
168	Windows_x86         archInnerProps
169	Windows_x86_64      archInnerProps
170}
171
172func invokeOnAndroidTargets(p *archProps, fn func(ap *archInnerProps, arch string)) {
173	fn(&p.Android_arm, "arm")
174	fn(&p.Android_arm64, "aarch64")
175	fn(&p.Android_riscv64, "riscv64")
176	fn(&p.Android_x86, "i386")
177	fn(&p.Android_x86_64, "x86_64")
178	fn(&p.Linux_bionic_arm64, "aarch64")
179	fn(&p.Linux_bionic_x86_64, "x86_64")
180}
181
182func setAndroidLibcxxSrcProps(ctx android.LoadHookContext, ap *archInnerProps, kind string,
183	arch string, libName string) {
184
185	clangDir := getClangPrebuiltDir(ctx)
186	setSrcsField := func(field *[]string, subdir string) {
187		*field = []string{path.Join(clangDir, "android_libc++", subdir, arch, "lib", libName)}
188	}
189
190	if arch == "aarch64" {
191		setSrcsField(&ap.Sanitized.None.Srcs, kind)
192		setSrcsField(&ap.Sanitized.Hwaddress.Srcs, kind+"_hwasan")
193	} else {
194		setSrcsField(&ap.Srcs, kind)
195	}
196}
197
198func llvmPrebuiltLibraryShared(ctx android.LoadHookContext) {
199	moduleName := strings.TrimPrefix(ctx.ModuleName(), "prebuilt_")
200
201	clangDir := getClangPrebuiltDir(ctx)
202
203	type props struct {
204		Export_include_dirs []string
205		Target              archProps
206		Stl                 *string
207	}
208
209	p := &props{}
210
211	if moduleName == "libc++" {
212		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
213			setAndroidLibcxxSrcProps(ctx, ap, "platform", arch, "libc++.so")
214			ap.Export_include_dirs = androidLibcxxHeaderDirs(ctx, "platform", arch)
215		})
216		setHostProps := func(ap *archInnerProps, triple string) {
217			ap.Srcs = []string{path.Join(clangDir, "lib", triple, "libc++.so")}
218			ap.Export_include_dirs = hostLibcxxHeaderDirs(ctx, triple)
219		}
220		setHostProps(&p.Target.Glibc_x86, "i386-unknown-linux-gnu")
221		setHostProps(&p.Target.Glibc_x86_64, "x86_64-unknown-linux-gnu")
222		setHostProps(&p.Target.Linux_musl_arm, "arm-unknown-linux-musleabihf")
223		setHostProps(&p.Target.Linux_musl_arm64, "aarch64-unknown-linux-musl")
224		setHostProps(&p.Target.Linux_musl_x86, "i686-unknown-linux-musl")
225		setHostProps(&p.Target.Linux_musl_x86_64, "x86_64-unknown-linux-musl")
226		if hasDarwinClangPrebuilt(ctx) {
227			p.Target.Darwin.Srcs = []string{":libc++_darwin"}
228			// TODO: At the moment, the Darwin __config_site header is the same as the
229			// Linux __config_site headers, but for correctness we ought to use the
230			// Darwin header somehow.
231			p.Target.Darwin.Export_include_dirs = []string{path.Join(clangDir, "include", "c++", "v1")}
232		}
233	} else if moduleName == "ndk_libc++_shared" {
234		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
235			setAndroidLibcxxSrcProps(ctx, ap, "ndk", arch, "libc++_shared.so")
236			ap.Export_include_dirs = androidLibcxxHeaderDirs(ctx, "ndk", arch)
237		})
238	} else if moduleName == "libc++abi_shared" {
239		// TODO: It's not clear that libc++abi_shared is needed, because the libc++
240		// shared library has libc++abi linked into it. The Darwin libc++.1.dylib
241		// previously depended on libc++abi.1.dylib, but when it was renamed to
242		// libc++.dylib, it also lost its runtime dependency on the ABI dylib.
243		libcxxabiSoName := "libc++abi.so"
244		p.Target.Glibc_x86.Srcs = []string{path.Join(clangDir, "lib", "i386-unknown-linux-gnu", libcxxabiSoName)}
245		p.Target.Glibc_x86_64.Srcs = []string{path.Join(clangDir, "lib", "x86_64-unknown-linux-gnu", libcxxabiSoName)}
246		p.Target.Linux_musl_x86.Srcs = []string{path.Join(clangDir, "lib", "i686-unknown-linux-musl", libcxxabiSoName)}
247		p.Target.Linux_musl_x86_64.Srcs = []string{path.Join(clangDir, "lib", "x86_64-unknown-linux-musl", libcxxabiSoName)}
248		p.Target.Linux_musl_arm.Srcs = []string{path.Join(clangDir, "lib", "arm-unknown-linux-musleabihf", libcxxabiSoName)}
249		p.Target.Linux_musl_arm64.Srcs = []string{path.Join(clangDir, "lib", "aarch64-unknown-linux-musl", libcxxabiSoName)}
250		if hasDarwinClangPrebuilt(ctx) {
251			p.Target.Darwin.Srcs = []string{":libc++abi_shared_darwin"}
252		}
253	} else if moduleName == "libclang-cpp_host" {
254		p.Export_include_dirs = []string{path.Join(clangDir, "include")}
255		p.Target.Glibc_x86_64.Srcs = []string{path.Join(clangDir, "lib", "libclang-cpp.so")}
256		if hasDarwinClangPrebuilt(ctx) {
257			p.Target.Darwin.Srcs = []string{":libclang-cpp_host_darwin"}
258		}
259	} else {
260		ctx.ModuleErrorf("unsupported LLVM prebuilt shared library: " + moduleName)
261	}
262
263	p.Stl = proptools.StringPtr("none")
264	ctx.AppendProperties(p)
265}
266
267func llvmPrebuiltLibraryStatic(ctx android.LoadHookContext) {
268	clangDir := getClangPrebuiltDir(ctx)
269	libDir := getClangResourceDir(ctx)
270	moduleName := strings.TrimPrefix(ctx.ModuleName(), "prebuilt_")
271
272	type props struct {
273		Export_include_dirs []string
274		Target              archProps
275	}
276
277	p := &props{}
278
279	if moduleName == "libc++_static" {
280		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
281			setAndroidLibcxxSrcProps(ctx, ap, "platform", arch, "libc++_static.a")
282			ap.Export_include_dirs = androidLibcxxHeaderDirs(ctx, "platform", arch)
283		})
284		setHostProps := func(ap *archInnerProps, triple string) {
285			ap.Srcs = []string{path.Join(clangDir, "lib", triple, "libc++.a")}
286			ap.Export_include_dirs = hostLibcxxHeaderDirs(ctx, triple)
287		}
288		setHostProps(&p.Target.Glibc_x86, "i386-unknown-linux-gnu")
289		setHostProps(&p.Target.Glibc_x86_64, "x86_64-unknown-linux-gnu")
290		setHostProps(&p.Target.Linux_musl_arm, "arm-unknown-linux-musleabihf")
291		setHostProps(&p.Target.Linux_musl_arm64, "aarch64-unknown-linux-musl")
292		setHostProps(&p.Target.Linux_musl_x86, "i686-unknown-linux-musl")
293		setHostProps(&p.Target.Linux_musl_x86_64, "x86_64-unknown-linux-musl")
294		setHostProps(&p.Target.Windows_x86, "i686-w64-windows-gnu")
295		setHostProps(&p.Target.Windows_x86_64, "x86_64-w64-windows-gnu")
296		if hasDarwinClangPrebuilt(ctx) {
297			p.Target.Darwin.Srcs = []string{":libc++_static_darwin"}
298			// TODO: At the moment, the Darwin __config_site header is the same as the
299			// Linux __config_site headers, but for correctness we ought to use the
300			// Darwin header somehow.
301			p.Target.Darwin.Export_include_dirs = []string{path.Join(clangDir, "include", "c++", "v1")}
302		}
303	} else if moduleName == "libc++_static_noexcept" {
304		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
305			setAndroidLibcxxSrcProps(ctx, ap, "platform_noexcept", arch, "libc++_static_noexcept.a")
306			ap.Export_include_dirs = androidLibcxxHeaderDirs(ctx, "platform", arch)
307		})
308	} else if moduleName == "ndk_libc++_static" {
309		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
310			setAndroidLibcxxSrcProps(ctx, ap, "ndk", arch, "libc++_static.a")
311			ap.Export_include_dirs = androidLibcxxHeaderDirs(ctx, "ndk", arch)
312		})
313	} else if moduleName == "libc++demangle" {
314		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
315			setAndroidLibcxxSrcProps(ctx, ap, "platform", arch, "libc++demangle.a")
316		})
317	} else if moduleName == "libc++demangle_noexcept" {
318		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
319			setAndroidLibcxxSrcProps(ctx, ap, "platform_noexcept", arch, "libc++demangle_noexcept.a")
320		})
321	} else if moduleName == "libc++abi_static" {
322		// TODO: It's not clear that libc++abi_static is actually needed, because
323		// its object files are in libc++_static anyway.
324		name := "libc++abi.a"
325		p.Target.Glibc_x86.Srcs = []string{path.Join(clangDir, "lib", "i386-unknown-linux-gnu", name)}
326		p.Target.Glibc_x86_64.Srcs = []string{path.Join(clangDir, "lib", "x86_64-unknown-linux-gnu", name)}
327		p.Target.Windows_x86.Srcs = []string{path.Join(clangDir, "lib", "i686-w64-windows-gnu", name)}
328		p.Target.Windows_x86_64.Srcs = []string{path.Join(clangDir, "lib", "x86_64-w64-windows-gnu", name)}
329		if hasDarwinClangPrebuilt(ctx) {
330			p.Target.Darwin.Srcs = []string{":libc++abi_static_darwin"}
331		}
332	} else if moduleName == "ndk_libc++abi" {
333		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
334			setAndroidLibcxxSrcProps(ctx, ap, "ndk", arch, "libc++abi.a")
335		})
336	} else if moduleName == "libsimpleperf_readelf" {
337		name := "libsimpleperf_readelf.a"
338		headerDir := path.Join(clangDir, "include")
339		p.Export_include_dirs = []string{headerDir}
340		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
341			ap.Srcs = []string{path.Join(libDir, arch, name)}
342		})
343		p.Target.Glibc_x86_64.Srcs = []string{path.Join(clangDir, "lib/x86_64-unknown-linux-gnu", name)}
344		p.Target.Linux_musl_x86_64.Srcs = []string{path.Join(libDir, "x86_64-unknown-linux-musl/lib", name)}
345		p.Target.Linux_musl_arm64.Srcs = []string{path.Join(libDir, "aarch64-unknown-linux-musl/lib", name)}
346		p.Target.Windows_x86_64.Srcs = []string{path.Join(clangDir, "lib/x86_64-w64-windows-gnu", name)}
347		if hasDarwinClangPrebuilt(ctx) {
348			p.Target.Darwin.Srcs = []string{":libsimpleperf_readelf_darwin"}
349		}
350	} else {
351		// Default behavior for a runtime library (like libunwind or libomp). Find
352		// the library from in the Clang resource directory.
353		name := moduleName + ".a"
354		if name == "libFuzzer.a" {
355			// TODO: Should these headers be removed? They declare internal symbols
356			// that aren't exported from libFuzzer.a(fuzzer.o). See b/303175229,
357			// aosp/2898988. Should libFuzzer be replaced by libclang_rt.fuzzer?
358			headerDir := path.Join(clangDir, "prebuilt_include", "llvm", "lib", "Fuzzer")
359			p.Export_include_dirs = []string{headerDir}
360		}
361		invokeOnAndroidTargets(&p.Target, func(ap *archInnerProps, arch string) {
362			ap.Srcs = []string{path.Join(libDir, arch, name)}
363		})
364		p.Target.Linux_musl_x86.Srcs = []string{path.Join(libDir, "i686-unknown-linux-musl/lib", name)}
365		p.Target.Linux_musl_x86_64.Srcs = []string{path.Join(libDir, "x86_64-unknown-linux-musl/lib", name)}
366		p.Target.Linux_musl_arm.Srcs = []string{path.Join(libDir, "arm-unknown-linux-musleabihf/lib", name)}
367		p.Target.Linux_musl_arm64.Srcs = []string{path.Join(libDir, "aarch64-unknown-linux-musl/lib", name)}
368	}
369
370	ctx.AppendProperties(p)
371}
372
373func llvmPrebuiltBuildTool(ctx android.LoadHookContext) {
374	clangDir := getClangPrebuiltDir(ctx)
375	name := strings.TrimPrefix(ctx.ModuleName(), "prebuilt_")
376	src := path.Join(clangDir, "bin", name)
377	deps := []string{
378		path.Join(clangDir, "lib", "libc++.so"),
379		path.Join(clangDir, "lib", "x86_64-unknown-linux-gnu", "libc++.so"),
380	}
381
382	type props struct {
383		Enabled *bool
384		Target  struct {
385			Linux struct {
386				Enabled *bool
387				Src     *string
388				Deps    []string
389			}
390		}
391	}
392	p := &props{}
393	p.Enabled = proptools.BoolPtr(false)
394	p.Target.Linux.Enabled = proptools.BoolPtr(true)
395	p.Target.Linux.Src = &src
396	p.Target.Linux.Deps = deps
397	ctx.AppendProperties(p)
398}
399
400type prebuiltLibrarySharedProps struct {
401	Is_llndk            *bool
402	Llndk_moved_to_apex *bool
403
404	Shared_libs []string
405}
406
407type prebuiltLibraryProps struct {
408	Lib_name *string
409
410	Suffix *string
411}
412
413func libClangRtPrebuiltLibraryShared(ctx android.LoadHookContext, libProps *prebuiltLibraryProps,
414	sharedProps *prebuiltLibrarySharedProps) {
415
416	if ctx.Config().IsEnvTrue("FORCE_BUILD_SANITIZER_SHARED_OBJECTS") {
417		return
418	}
419
420	libDir := getClangResourceDir(ctx)
421
422	type props struct {
423		Target             archProps
424		System_shared_libs []string
425		No_libcrt          *bool
426		Sanitize           struct {
427			Never *bool
428		}
429		Strip struct {
430			None *bool
431		}
432		Pack_relocations *bool
433		Stl              *string
434		Stubs            struct {
435			Symbol_file *string
436			Versions    []string
437		}
438		Llndk struct {
439			Symbol_file   *string
440			Moved_to_apex *bool
441		}
442	}
443
444	p := &props{}
445
446	name := proptools.StringDefault(libProps.Lib_name, strings.TrimPrefix(ctx.ModuleName(), "prebuilt_"))
447	suffix := proptools.String(libProps.Suffix)
448
449	p.Target.Android_arm.Srcs = []string{path.Join(libDir, name+"-arm-android"+suffix+".so")}
450	p.Target.Android_arm.Stem = proptools.StringPtr(name + "-arm-android" + suffix)
451	p.Target.Android_arm.Srcs = []string{path.Join(libDir, name+"-arm-android"+suffix+".so")}
452	p.Target.Android_arm.Stem = proptools.StringPtr(name + "-arm-android" + suffix)
453	p.Target.Android_arm64.Srcs = []string{path.Join(libDir, name+"-aarch64-android"+suffix+".so")}
454	p.Target.Android_arm64.Stem = proptools.StringPtr(name + "-aarch64-android" + suffix)
455	p.Target.Android_riscv64.Srcs = []string{path.Join(libDir, name+"-riscv64-android"+suffix+".so")}
456	p.Target.Android_riscv64.Stem = proptools.StringPtr(name + "-riscv64-android" + suffix)
457	p.Target.Android_x86.Srcs = []string{path.Join(libDir, name+"-i686-android"+suffix+".so")}
458	p.Target.Android_x86.Stem = proptools.StringPtr(name + "-i686-android" + suffix)
459	p.Target.Android_x86_64.Srcs = []string{path.Join(libDir, name+"-x86_64-android"+suffix+".so")}
460	p.Target.Android_x86_64.Stem = proptools.StringPtr(name + "-x86_64-android" + suffix)
461	p.Target.Linux_bionic_arm64.Srcs = []string{path.Join(libDir, name+"-aarch64-android"+suffix+".so")}
462	p.Target.Linux_bionic_arm64.Stem = proptools.StringPtr(name + "-aarch64-android" + suffix)
463	p.Target.Linux_bionic_x86_64.Srcs = []string{path.Join(libDir, name+"-x86_64-android"+suffix+".so")}
464	p.Target.Linux_bionic_x86_64.Stem = proptools.StringPtr(name + "-x86_64-android" + suffix)
465	p.Target.Glibc_x86.Srcs = []string{path.Join(libDir, name+"-i386"+suffix+".so")}
466	p.Target.Glibc_x86.Stem = proptools.StringPtr(name + "-i386" + suffix)
467	p.Target.Glibc_x86_64.Srcs = []string{path.Join(libDir, name+"-x86_64"+suffix+".so")}
468	p.Target.Glibc_x86_64.Stem = proptools.StringPtr(name + "-x86_64" + suffix)
469	p.Target.Linux_musl_x86.Srcs = []string{path.Join(libDir, "i686-unknown-linux-musl/lib/linux", name+"-i386"+suffix+".so")}
470	p.Target.Linux_musl_x86.Stem = proptools.StringPtr(name + "-i386" + suffix)
471	p.Target.Linux_musl_x86_64.Srcs = []string{path.Join(libDir, "x86_64-unknown-linux-musl/lib/linux", name+"-x86_64"+suffix+".so")}
472	p.Target.Linux_musl_x86_64.Stem = proptools.StringPtr(name + "-x86_64" + suffix)
473	p.Target.Linux_musl_arm.Srcs = []string{path.Join(libDir, "arm-unknown-linux-musleabihf/lib/linux", name+"-armhf"+suffix+".so")}
474	p.Target.Linux_musl_arm.Stem = proptools.StringPtr(name + "-armhf" + suffix)
475	p.Target.Linux_musl_arm64.Srcs = []string{path.Join(libDir, "aarch64-unknown-linux-musl/lib/linux", name+"-aarch64"+suffix+".so")}
476	p.Target.Linux_musl_arm64.Stem = proptools.StringPtr(name + "-aarch64" + suffix)
477
478	p.System_shared_libs = []string{}
479	p.No_libcrt = proptools.BoolPtr(true)
480	p.Sanitize.Never = proptools.BoolPtr(true)
481	p.Strip.None = proptools.BoolPtr(true)
482	disable := false
483	p.Pack_relocations = &disable
484	p.Stl = proptools.StringPtr("none")
485
486	if proptools.Bool(sharedProps.Is_llndk) {
487		p.Stubs.Versions = []string{"29", "10000"}
488		p.Llndk.Moved_to_apex = sharedProps.Llndk_moved_to_apex
489		// Set the symbol_file of the "base" variant to a fake file. This will be overridden later.
490		// This is necessary today since `image` mutator which creates the llndk variants runs before `arch` mutator.
491		// Without this hack, the llndk variants will not be created.
492		p.Llndk.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-does-not-exist"))
493		p.Stubs.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-does-not-exist"))
494		// Arch specific overrides
495		p.Target.Android_arm.Stubs.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-arm-android"))
496		p.Target.Android_arm.Llndk.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-arm-android"))
497		p.Target.Android_arm64.Stubs.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-aarch64-android"))
498		p.Target.Android_arm64.Llndk.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-aarch64-android"))
499		p.Target.Android_riscv64.Stubs.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-riscv64-android"))
500		p.Target.Android_riscv64.Llndk.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-riscv64-android"))
501		p.Target.Android_x86.Stubs.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-i686-android"))
502		p.Target.Android_x86.Llndk.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-i686-android"))
503		p.Target.Android_x86_64.Stubs.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-x86_64-android"))
504		p.Target.Android_x86_64.Llndk.Symbol_file = proptools.StringPtr(getSymbolFilePath(ctx, "-x86_64-android"))
505	}
506
507	ctx.AppendProperties(p)
508}
509
510func libClangRtPrebuiltLibraryStatic(ctx android.LoadHookContext, libProps *prebuiltLibraryProps) {
511	libDir := getClangResourceDir(ctx)
512
513	type props struct {
514		Target             archProps
515		System_shared_libs []string
516		No_libcrt          *bool
517		Stl                *string
518	}
519
520	name := proptools.StringDefault(libProps.Lib_name, strings.TrimPrefix(ctx.ModuleName(), "prebuilt_"))
521	name = strings.TrimSuffix(name, ".static")
522	suffix := proptools.String(libProps.Suffix)
523
524	p := &props{}
525
526	p.Target.Android_arm.Srcs = []string{path.Join(libDir, name+"-arm-android"+suffix+".a")}
527	p.Target.Android_arm64.Srcs = []string{path.Join(libDir, name+"-aarch64-android"+suffix+".a")}
528	p.Target.Android_riscv64.Srcs = []string{path.Join(libDir, name+"-riscv64-android"+suffix+".a")}
529	p.Target.Android_x86.Srcs = []string{path.Join(libDir, name+"-i686-android"+suffix+".a")}
530	p.Target.Android_x86_64.Srcs = []string{path.Join(libDir, name+"-x86_64-android"+suffix+".a")}
531	p.Target.Linux_bionic_arm64.Srcs = []string{path.Join(libDir, name+"-aarch64-android"+suffix+".a")}
532	p.Target.Linux_bionic_x86_64.Srcs = []string{path.Join(libDir, name+"-x86_64-android"+suffix+".a")}
533	p.Target.Glibc_x86.Srcs = []string{path.Join(libDir, name+"-i386"+suffix+".a")}
534	p.Target.Glibc_x86_64.Srcs = []string{path.Join(libDir, name+"-x86_64"+suffix+".a")}
535	p.Target.Linux_musl_x86.Srcs = []string{path.Join(libDir, "i686-unknown-linux-musl/lib/linux", name+"-i386"+suffix+".a")}
536	p.Target.Linux_musl_x86_64.Srcs = []string{path.Join(libDir, "x86_64-unknown-linux-musl/lib/linux", name+"-x86_64"+suffix+".a")}
537	p.Target.Linux_musl_arm.Srcs = []string{path.Join(libDir, "arm-unknown-linux-musleabihf/lib/linux", name+"-armhf"+suffix+".a")}
538	p.Target.Linux_musl_arm64.Srcs = []string{path.Join(libDir, "aarch64-unknown-linux-musl/lib/linux", name+"-aarch64"+suffix+".a")}
539	p.System_shared_libs = []string{}
540	p.No_libcrt = proptools.BoolPtr(true)
541	p.Stl = proptools.StringPtr("none")
542	ctx.AppendProperties(p)
543}
544
545func libClangRtPrebuiltObject(ctx android.LoadHookContext) {
546	libDir := getClangResourceDir(ctx)
547
548	type props struct {
549		Arch struct {
550			X86 struct {
551				Srcs []string
552			}
553			X86_64 struct {
554				Srcs []string
555			}
556			Arm struct {
557				Srcs []string
558			}
559			Arm64 struct {
560				Srcs []string
561			}
562		}
563		System_shared_libs []string
564		Stl                *string
565	}
566
567	name := strings.TrimPrefix(ctx.ModuleName(), "prebuilt_")
568
569	p := &props{}
570	p.Arch.X86.Srcs = []string{path.Join(libDir, name+"-i386.o")}
571	p.Arch.X86_64.Srcs = []string{path.Join(libDir, name+"-x86_64.o")}
572	p.Arch.Arm.Srcs = []string{path.Join(libDir, "arm-unknown-linux-musleabihf/lib/linux", name+"-armhf.o")}
573	p.Arch.Arm64.Srcs = []string{path.Join(libDir, "aarch64-unknown-linux-musl/lib/linux", name+"-aarch64.o")}
574	p.System_shared_libs = []string{}
575	p.Stl = proptools.StringPtr("none")
576	ctx.AppendProperties(p)
577}
578
579func llvmDarwinFileGroup(ctx android.LoadHookContext) {
580	clangDir := getClangPrebuiltDir(ctx)
581	moduleName := ctx.ModuleName()
582	var libName string
583
584	switch moduleName {
585	case "libclang-cpp_host_darwin":
586		libName = "libclang-cpp.dylib"
587	case "libc++_darwin":
588		libName = "libc++.dylib"
589	case "libc++abi_shared_darwin":
590		libName = "libc++abi.dylib"
591	case "libc++_static_darwin":
592		libName = "libc++.a"
593	case "libc++abi_static_darwin":
594		libName = "libc++abi.a"
595	case "libsimpleperf_readelf_darwin":
596		libName = "libsimpleperf_readelf.a"
597	default:
598		ctx.ModuleErrorf("unsupported host LLVM file group: " + moduleName)
599	}
600	lib := path.Join(clangDir, "lib", libName)
601
602	if hasDarwinClangPrebuilt(ctx) {
603		type props struct {
604			Srcs []string
605		}
606		p := &props{}
607		p.Srcs = []string{lib}
608		ctx.AppendProperties(p)
609	}
610}
611
612func llvmPrebuiltLibraryStaticFactory() android.Module {
613	module, _ := cc.NewPrebuiltStaticLibrary(android.HostAndDeviceSupported)
614	android.AddLoadHook(module, llvmPrebuiltLibraryStatic)
615	return module.Init()
616}
617
618func llvmPrebuiltBuildToolFactory() android.Module {
619	module := android.NewPrebuiltBuildTool()
620	android.AddLoadHook(module, llvmPrebuiltBuildTool)
621	return module
622}
623
624func llvmPrebuiltLibrarySharedFactory() android.Module {
625	module, _ := cc.NewPrebuiltSharedLibrary(android.HostAndDeviceSupported)
626	android.AddLoadHook(module, llvmPrebuiltLibraryShared)
627	return module.Init()
628}
629
630func ndkPrebuiltStaticStlFactory() android.Module {
631	module, _ := cc.NewPrebuiltStaticLibrary(android.DeviceSupported)
632	module.Properties.AlwaysSdk = true
633	module.Properties.HideFromMake = true
634	module.SetPreventInstall()
635	android.AddLoadHook(module, llvmPrebuiltLibraryStatic)
636	return module.Init()
637}
638
639func ndkPrebuiltSharedStlFactory() android.Module {
640	module, _ := cc.NewPrebuiltSharedLibrary(android.DeviceSupported)
641	module.Properties.AlwaysSdk = true
642	module.Properties.HideFromMake = true
643	module.SetPreventInstall()
644	android.AddLoadHook(module, llvmPrebuiltLibraryShared)
645	return module.Init()
646}
647
648func libClangRtPrebuiltLibrarySharedFactory() android.Module {
649	module, _ := cc.NewPrebuiltSharedLibrary(android.HostAndDeviceSupported)
650	props := &prebuiltLibraryProps{}
651	sharedProps := &prebuiltLibrarySharedProps{}
652	module.AddProperties(props, sharedProps)
653	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
654		libClangRtPrebuiltLibraryShared(ctx, props, sharedProps)
655	})
656	return module.Init()
657}
658
659func libClangRtPrebuiltLibraryStaticFactory() android.Module {
660	module, _ := cc.NewPrebuiltStaticLibrary(android.HostAndDeviceSupported)
661	props := &prebuiltLibraryProps{}
662	module.AddProperties(props)
663	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
664		libClangRtPrebuiltLibraryStatic(ctx, props)
665	})
666	return module.Init()
667}
668
669func libClangRtPrebuiltObjectFactory() android.Module {
670	module := cc.NewPrebuiltObject(android.HostAndDeviceSupported)
671	android.AddLoadHook(module, libClangRtPrebuiltObject)
672	return module.Init()
673}
674
675func llvmDarwinFileGroupFactory() android.Module {
676	module := android.FileGroupFactory()
677	android.AddLoadHook(module, llvmDarwinFileGroup)
678	return module
679}
680
681func llvmHostDefaults(ctx android.LoadHookContext) {
682	type props struct {
683		Enabled *bool
684	}
685
686	p := &props{}
687	if !ctx.Config().IsEnvTrue("LLVM_BUILD_HOST_TOOLS") {
688		p.Enabled = proptools.BoolPtr(false)
689	}
690	ctx.AppendProperties(p)
691}
692
693func llvmHostDefaultsFactory() android.Module {
694	module := cc.DefaultsFactory()
695	android.AddLoadHook(module, llvmHostDefaults)
696	return module
697}
698
699func clangBuiltinHeaders(ctx android.LoadHookContext) {
700	type props struct {
701		Cmd  *string
702		Srcs []string
703	}
704
705	p := &props{}
706	builtinHeadersDir := path.Join(
707		getClangPrebuiltDir(ctx), "lib", "clang",
708		ctx.Config().GetenvWithDefault("LLVM_RELEASE_VERSION",
709			config.ClangDefaultShortVersion), "include")
710	s := "$(location) " + path.Join(ctx.ModuleDir(), builtinHeadersDir) + " $(in) >$(out)"
711	p.Cmd = &s
712
713	p.Srcs = []string{path.Join(builtinHeadersDir, "**", "*.h")}
714	ctx.AppendProperties(p)
715}
716
717func clangBuiltinHeadersFactory() android.Module {
718	module := genrule.GenRuleFactory()
719	android.AddLoadHook(module, clangBuiltinHeaders)
720	return module
721}
722
723func llvmToolsFileGroup(ctx android.LoadHookContext) {
724	type props struct {
725		Srcs []string
726	}
727
728	p := &props{}
729	prebuiltDir := path.Join(getClangPrebuiltDir(ctx))
730	for _, src := range llvmToolsFiles {
731		p.Srcs = append(p.Srcs, path.Join(prebuiltDir, src))
732	}
733	ctx.AppendProperties(p)
734}
735
736func llvmToolsFilegroupFactory() android.Module {
737	module := android.FileGroupFactory()
738	android.AddLoadHook(module, llvmToolsFileGroup)
739	return module
740}
741