xref: /aosp_15_r20/external/boringssl/src/util/pregenerate/build.go (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker// Copyright (c) 2024, Google Inc.
2*8fb009dcSAndroid Build Coastguard Worker//
3*8fb009dcSAndroid Build Coastguard Worker// Permission to use, copy, modify, and/or distribute this software for any
4*8fb009dcSAndroid Build Coastguard Worker// purpose with or without fee is hereby granted, provided that the above
5*8fb009dcSAndroid Build Coastguard Worker// copyright notice and this permission notice appear in all copies.
6*8fb009dcSAndroid Build Coastguard Worker//
7*8fb009dcSAndroid Build Coastguard Worker// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8*8fb009dcSAndroid Build Coastguard Worker// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9*8fb009dcSAndroid Build Coastguard Worker// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10*8fb009dcSAndroid Build Coastguard Worker// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11*8fb009dcSAndroid Build Coastguard Worker// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12*8fb009dcSAndroid Build Coastguard Worker// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13*8fb009dcSAndroid Build Coastguard Worker// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14*8fb009dcSAndroid Build Coastguard Worker
15*8fb009dcSAndroid Build Coastguard Workerpackage main
16*8fb009dcSAndroid Build Coastguard Worker
17*8fb009dcSAndroid Build Coastguard Workerimport (
18*8fb009dcSAndroid Build Coastguard Worker	"bytes"
19*8fb009dcSAndroid Build Coastguard Worker	"cmp"
20*8fb009dcSAndroid Build Coastguard Worker	"encoding/json"
21*8fb009dcSAndroid Build Coastguard Worker	"fmt"
22*8fb009dcSAndroid Build Coastguard Worker	"path"
23*8fb009dcSAndroid Build Coastguard Worker	"path/filepath"
24*8fb009dcSAndroid Build Coastguard Worker	"slices"
25*8fb009dcSAndroid Build Coastguard Worker	"strings"
26*8fb009dcSAndroid Build Coastguard Worker
27*8fb009dcSAndroid Build Coastguard Worker	"boringssl.googlesource.com/boringssl/util/build"
28*8fb009dcSAndroid Build Coastguard Worker)
29*8fb009dcSAndroid Build Coastguard Worker
30*8fb009dcSAndroid Build Coastguard Worker// An InputTarget is a build target with build inputs that still need to be
31*8fb009dcSAndroid Build Coastguard Worker// pregenerated. All file lists in InputTarget are interpreted with glob
32*8fb009dcSAndroid Build Coastguard Worker// patterns as in filepath.Glob.
33*8fb009dcSAndroid Build Coastguard Workertype InputTarget struct {
34*8fb009dcSAndroid Build Coastguard Worker	build.Target
35*8fb009dcSAndroid Build Coastguard Worker	// ErrData contains a list of errordata files to combine into err_data.c.
36*8fb009dcSAndroid Build Coastguard Worker	ErrData []string `json:"err_data,omitempty"`
37*8fb009dcSAndroid Build Coastguard Worker	// The following fields define perlasm sources for the corresponding
38*8fb009dcSAndroid Build Coastguard Worker	// architecture.
39*8fb009dcSAndroid Build Coastguard Worker	PerlasmAarch64 []PerlasmSource `json:"perlasm_aarch64,omitempty"`
40*8fb009dcSAndroid Build Coastguard Worker	PerlasmArm     []PerlasmSource `json:"perlasm_arm,omitempty"`
41*8fb009dcSAndroid Build Coastguard Worker	PerlasmX86     []PerlasmSource `json:"perlasm_x86,omitempty"`
42*8fb009dcSAndroid Build Coastguard Worker	PerlasmX86_64  []PerlasmSource `json:"perlasm_x86_64,omitempty"`
43*8fb009dcSAndroid Build Coastguard Worker}
44*8fb009dcSAndroid Build Coastguard Worker
45*8fb009dcSAndroid Build Coastguard Workertype PerlasmSource struct {
46*8fb009dcSAndroid Build Coastguard Worker	// Src the path to the input perlasm file.
47*8fb009dcSAndroid Build Coastguard Worker	Src string `json:"src"`
48*8fb009dcSAndroid Build Coastguard Worker	// Dst, if not empty, is base name of the destination file. If empty, this
49*8fb009dcSAndroid Build Coastguard Worker	// is determined from Src by default. It should be overriden if a single
50*8fb009dcSAndroid Build Coastguard Worker	// source file generates multiple functions (e.g. SHA-256 vs SHA-512) or
51*8fb009dcSAndroid Build Coastguard Worker	// multiple architectures (e.g. the "armx" files).
52*8fb009dcSAndroid Build Coastguard Worker	Dst string `json:"dst,omitempty"`
53*8fb009dcSAndroid Build Coastguard Worker	// Args is a list of extra parameters to pass to the script.
54*8fb009dcSAndroid Build Coastguard Worker	Args []string `json:"args,omitempty"`
55*8fb009dcSAndroid Build Coastguard Worker}
56*8fb009dcSAndroid Build Coastguard Worker
57*8fb009dcSAndroid Build Coastguard Worker// Pregenerate converts an input target to an output target. It returns the
58*8fb009dcSAndroid Build Coastguard Worker// result alongside a list of tasks that must be run to build the referenced
59*8fb009dcSAndroid Build Coastguard Worker// files.
60*8fb009dcSAndroid Build Coastguard Workerfunc (in *InputTarget) Pregenerate(name string) (out build.Target, tasks []Task, err error) {
61*8fb009dcSAndroid Build Coastguard Worker	// Expand wildcards.
62*8fb009dcSAndroid Build Coastguard Worker	out.Srcs, err = glob(in.Srcs)
63*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
64*8fb009dcSAndroid Build Coastguard Worker		return
65*8fb009dcSAndroid Build Coastguard Worker	}
66*8fb009dcSAndroid Build Coastguard Worker	out.Hdrs, err = glob(in.Hdrs)
67*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
68*8fb009dcSAndroid Build Coastguard Worker		return
69*8fb009dcSAndroid Build Coastguard Worker	}
70*8fb009dcSAndroid Build Coastguard Worker	out.InternalHdrs, err = glob(in.InternalHdrs)
71*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
72*8fb009dcSAndroid Build Coastguard Worker		return
73*8fb009dcSAndroid Build Coastguard Worker	}
74*8fb009dcSAndroid Build Coastguard Worker	out.Asm, err = glob(in.Asm)
75*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
76*8fb009dcSAndroid Build Coastguard Worker		return
77*8fb009dcSAndroid Build Coastguard Worker	}
78*8fb009dcSAndroid Build Coastguard Worker	out.Nasm, err = glob(in.Nasm)
79*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
80*8fb009dcSAndroid Build Coastguard Worker		return
81*8fb009dcSAndroid Build Coastguard Worker	}
82*8fb009dcSAndroid Build Coastguard Worker	out.Data, err = glob(in.Data)
83*8fb009dcSAndroid Build Coastguard Worker	if err != nil {
84*8fb009dcSAndroid Build Coastguard Worker		return
85*8fb009dcSAndroid Build Coastguard Worker	}
86*8fb009dcSAndroid Build Coastguard Worker
87*8fb009dcSAndroid Build Coastguard Worker	addTask := func(list *[]string, t Task) {
88*8fb009dcSAndroid Build Coastguard Worker		tasks = append(tasks, t)
89*8fb009dcSAndroid Build Coastguard Worker		*list = append(*list, t.Destination())
90*8fb009dcSAndroid Build Coastguard Worker	}
91*8fb009dcSAndroid Build Coastguard Worker
92*8fb009dcSAndroid Build Coastguard Worker	if len(in.ErrData) != 0 {
93*8fb009dcSAndroid Build Coastguard Worker		var inputs []string
94*8fb009dcSAndroid Build Coastguard Worker		inputs, err = glob(in.ErrData)
95*8fb009dcSAndroid Build Coastguard Worker		if err != nil {
96*8fb009dcSAndroid Build Coastguard Worker			return
97*8fb009dcSAndroid Build Coastguard Worker		}
98*8fb009dcSAndroid Build Coastguard Worker		addTask(&out.Srcs, &ErrDataTask{TargetName: name, Inputs: inputs})
99*8fb009dcSAndroid Build Coastguard Worker	}
100*8fb009dcSAndroid Build Coastguard Worker
101*8fb009dcSAndroid Build Coastguard Worker	addPerlasmTask := func(list *[]string, p *PerlasmSource, fileSuffix string, args []string) {
102*8fb009dcSAndroid Build Coastguard Worker		dst := p.Dst
103*8fb009dcSAndroid Build Coastguard Worker		if len(p.Dst) == 0 {
104*8fb009dcSAndroid Build Coastguard Worker			dst = strings.TrimSuffix(path.Base(p.Src), ".pl")
105*8fb009dcSAndroid Build Coastguard Worker		}
106*8fb009dcSAndroid Build Coastguard Worker		dst = path.Join("gen", name, dst+fileSuffix)
107*8fb009dcSAndroid Build Coastguard Worker		args = append(slices.Clone(args), p.Args...)
108*8fb009dcSAndroid Build Coastguard Worker		addTask(list, &PerlasmTask{Src: p.Src, Dst: dst, Args: args})
109*8fb009dcSAndroid Build Coastguard Worker	}
110*8fb009dcSAndroid Build Coastguard Worker
111*8fb009dcSAndroid Build Coastguard Worker	for _, p := range in.PerlasmAarch64 {
112*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-apple.S", []string{"ios64"})
113*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-linux.S", []string{"linux64"})
114*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-win.S", []string{"win64"})
115*8fb009dcSAndroid Build Coastguard Worker	}
116*8fb009dcSAndroid Build Coastguard Worker	for _, p := range in.PerlasmArm {
117*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-linux.S", []string{"linux32"})
118*8fb009dcSAndroid Build Coastguard Worker	}
119*8fb009dcSAndroid Build Coastguard Worker	for _, p := range in.PerlasmX86 {
120*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-apple.S", []string{"macosx", "-fPIC"})
121*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-linux.S", []string{"elf", "-fPIC"})
122*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Nasm, &p, "-win.asm", []string{"win32n", "-fPIC"})
123*8fb009dcSAndroid Build Coastguard Worker	}
124*8fb009dcSAndroid Build Coastguard Worker	for _, p := range in.PerlasmX86_64 {
125*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-apple.S", []string{"macosx"})
126*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Asm, &p, "-linux.S", []string{"elf"})
127*8fb009dcSAndroid Build Coastguard Worker		addPerlasmTask(&out.Nasm, &p, "-win.asm", []string{"nasm"})
128*8fb009dcSAndroid Build Coastguard Worker	}
129*8fb009dcSAndroid Build Coastguard Worker
130*8fb009dcSAndroid Build Coastguard Worker	// Re-sort the modified fields.
131*8fb009dcSAndroid Build Coastguard Worker	slices.Sort(out.Srcs)
132*8fb009dcSAndroid Build Coastguard Worker	slices.Sort(out.Asm)
133*8fb009dcSAndroid Build Coastguard Worker	slices.Sort(out.Nasm)
134*8fb009dcSAndroid Build Coastguard Worker
135*8fb009dcSAndroid Build Coastguard Worker	return
136*8fb009dcSAndroid Build Coastguard Worker}
137*8fb009dcSAndroid Build Coastguard Worker
138*8fb009dcSAndroid Build Coastguard Workerfunc glob(paths []string) ([]string, error) {
139*8fb009dcSAndroid Build Coastguard Worker	var ret []string
140*8fb009dcSAndroid Build Coastguard Worker	for _, path := range paths {
141*8fb009dcSAndroid Build Coastguard Worker		if !strings.ContainsRune(path, '*') {
142*8fb009dcSAndroid Build Coastguard Worker			ret = append(ret, path)
143*8fb009dcSAndroid Build Coastguard Worker			continue
144*8fb009dcSAndroid Build Coastguard Worker		}
145*8fb009dcSAndroid Build Coastguard Worker		matches, err := filepath.Glob(path)
146*8fb009dcSAndroid Build Coastguard Worker		if err != nil {
147*8fb009dcSAndroid Build Coastguard Worker			return nil, err
148*8fb009dcSAndroid Build Coastguard Worker		}
149*8fb009dcSAndroid Build Coastguard Worker		if len(matches) == 0 {
150*8fb009dcSAndroid Build Coastguard Worker			return nil, fmt.Errorf("glob matched no files: %q", path)
151*8fb009dcSAndroid Build Coastguard Worker		}
152*8fb009dcSAndroid Build Coastguard Worker		// Switch from Windows to POSIX paths.
153*8fb009dcSAndroid Build Coastguard Worker		for _, match := range matches {
154*8fb009dcSAndroid Build Coastguard Worker			ret = append(ret, strings.ReplaceAll(match, "\\", "/"))
155*8fb009dcSAndroid Build Coastguard Worker		}
156*8fb009dcSAndroid Build Coastguard Worker	}
157*8fb009dcSAndroid Build Coastguard Worker	slices.Sort(ret)
158*8fb009dcSAndroid Build Coastguard Worker	return ret, nil
159*8fb009dcSAndroid Build Coastguard Worker}
160*8fb009dcSAndroid Build Coastguard Worker
161*8fb009dcSAndroid Build Coastguard Workerfunc sortedKeys[K cmp.Ordered, V any](m map[K]V) []K {
162*8fb009dcSAndroid Build Coastguard Worker	keys := make([]K, 0, len(m))
163*8fb009dcSAndroid Build Coastguard Worker	for k := range m {
164*8fb009dcSAndroid Build Coastguard Worker		keys = append(keys, k)
165*8fb009dcSAndroid Build Coastguard Worker	}
166*8fb009dcSAndroid Build Coastguard Worker	slices.Sort(keys)
167*8fb009dcSAndroid Build Coastguard Worker	return keys
168*8fb009dcSAndroid Build Coastguard Worker}
169*8fb009dcSAndroid Build Coastguard Worker
170*8fb009dcSAndroid Build Coastguard Workerfunc writeHeader(b *bytes.Buffer, comment string) {
171*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s Copyright (c) 2024, Google Inc.\n", comment)
172*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s\n", comment)
173*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s Permission to use, copy, modify, and/or distribute this software for any\n", comment)
174*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s purpose with or without fee is hereby granted, provided that the above\n", comment)
175*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s copyright notice and this permission notice appear in all copies.\n", comment)
176*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s\n", comment)
177*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n", comment)
178*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n", comment)
179*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n", comment)
180*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n", comment)
181*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n", comment)
182*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\n", comment)
183*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n", comment)
184*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s\n", comment)
185*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "%s Generated by go ./util/pregenerate. Do not edit manually.\n", comment)
186*8fb009dcSAndroid Build Coastguard Worker}
187*8fb009dcSAndroid Build Coastguard Worker
188*8fb009dcSAndroid Build Coastguard Workerfunc buildVariablesTask(targets map[string]build.Target, dst, comment string, writeVariable func(b *bytes.Buffer, name string, val []string)) Task {
189*8fb009dcSAndroid Build Coastguard Worker	return NewSimpleTask(dst, func() ([]byte, error) {
190*8fb009dcSAndroid Build Coastguard Worker		var b bytes.Buffer
191*8fb009dcSAndroid Build Coastguard Worker		writeHeader(&b, comment)
192*8fb009dcSAndroid Build Coastguard Worker
193*8fb009dcSAndroid Build Coastguard Worker		for _, name := range sortedKeys(targets) {
194*8fb009dcSAndroid Build Coastguard Worker			target := targets[name]
195*8fb009dcSAndroid Build Coastguard Worker			if len(target.Srcs) != 0 {
196*8fb009dcSAndroid Build Coastguard Worker				writeVariable(&b, name+"_sources", target.Srcs)
197*8fb009dcSAndroid Build Coastguard Worker			}
198*8fb009dcSAndroid Build Coastguard Worker			if len(target.Hdrs) != 0 {
199*8fb009dcSAndroid Build Coastguard Worker				writeVariable(&b, name+"_headers", target.Hdrs)
200*8fb009dcSAndroid Build Coastguard Worker			}
201*8fb009dcSAndroid Build Coastguard Worker			if len(target.InternalHdrs) != 0 {
202*8fb009dcSAndroid Build Coastguard Worker				writeVariable(&b, name+"_internal_headers", target.InternalHdrs)
203*8fb009dcSAndroid Build Coastguard Worker			}
204*8fb009dcSAndroid Build Coastguard Worker			if len(target.Asm) != 0 {
205*8fb009dcSAndroid Build Coastguard Worker				writeVariable(&b, name+"_sources_asm", target.Asm)
206*8fb009dcSAndroid Build Coastguard Worker			}
207*8fb009dcSAndroid Build Coastguard Worker			if len(target.Nasm) != 0 {
208*8fb009dcSAndroid Build Coastguard Worker				writeVariable(&b, name+"_sources_nasm", target.Nasm)
209*8fb009dcSAndroid Build Coastguard Worker			}
210*8fb009dcSAndroid Build Coastguard Worker			if len(target.Data) != 0 {
211*8fb009dcSAndroid Build Coastguard Worker				writeVariable(&b, name+"_data", target.Data)
212*8fb009dcSAndroid Build Coastguard Worker			}
213*8fb009dcSAndroid Build Coastguard Worker		}
214*8fb009dcSAndroid Build Coastguard Worker
215*8fb009dcSAndroid Build Coastguard Worker		return b.Bytes(), nil
216*8fb009dcSAndroid Build Coastguard Worker	})
217*8fb009dcSAndroid Build Coastguard Worker}
218*8fb009dcSAndroid Build Coastguard Worker
219*8fb009dcSAndroid Build Coastguard Workerfunc writeBazelVariable(b *bytes.Buffer, name string, val []string) {
220*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "\n%s = [\n", name)
221*8fb009dcSAndroid Build Coastguard Worker	for _, v := range val {
222*8fb009dcSAndroid Build Coastguard Worker		fmt.Fprintf(b, "    %q,\n", v)
223*8fb009dcSAndroid Build Coastguard Worker	}
224*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "]\n")
225*8fb009dcSAndroid Build Coastguard Worker}
226*8fb009dcSAndroid Build Coastguard Worker
227*8fb009dcSAndroid Build Coastguard Workerfunc writeCMakeVariable(b *bytes.Buffer, name string, val []string) {
228*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "\nset(\n")
229*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "  %s\n\n", strings.ToUpper(name))
230*8fb009dcSAndroid Build Coastguard Worker	for _, v := range val {
231*8fb009dcSAndroid Build Coastguard Worker		fmt.Fprintf(b, "  %s\n", v)
232*8fb009dcSAndroid Build Coastguard Worker	}
233*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, ")\n")
234*8fb009dcSAndroid Build Coastguard Worker}
235*8fb009dcSAndroid Build Coastguard Worker
236*8fb009dcSAndroid Build Coastguard Workerfunc writeMakeVariable(b *bytes.Buffer, name string, val []string) {
237*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "\n%s := \\\n", name)
238*8fb009dcSAndroid Build Coastguard Worker	for i, v := range val {
239*8fb009dcSAndroid Build Coastguard Worker		if i == len(val)-1 {
240*8fb009dcSAndroid Build Coastguard Worker			fmt.Fprintf(b, "  %s\n", v)
241*8fb009dcSAndroid Build Coastguard Worker		} else {
242*8fb009dcSAndroid Build Coastguard Worker			fmt.Fprintf(b, "  %s \\\n", v)
243*8fb009dcSAndroid Build Coastguard Worker		}
244*8fb009dcSAndroid Build Coastguard Worker	}
245*8fb009dcSAndroid Build Coastguard Worker}
246*8fb009dcSAndroid Build Coastguard Worker
247*8fb009dcSAndroid Build Coastguard Workerfunc writeGNVariable(b *bytes.Buffer, name string, val []string) {
248*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "\n%s = [\n", name)
249*8fb009dcSAndroid Build Coastguard Worker	for _, v := range val {
250*8fb009dcSAndroid Build Coastguard Worker		fmt.Fprintf(b, "  %q,\n", v)
251*8fb009dcSAndroid Build Coastguard Worker	}
252*8fb009dcSAndroid Build Coastguard Worker	fmt.Fprintf(b, "]\n")
253*8fb009dcSAndroid Build Coastguard Worker}
254*8fb009dcSAndroid Build Coastguard Worker
255*8fb009dcSAndroid Build Coastguard Workerfunc jsonTask(targets map[string]build.Target, dst string) Task {
256*8fb009dcSAndroid Build Coastguard Worker	return NewSimpleTask(dst, func() ([]byte, error) {
257*8fb009dcSAndroid Build Coastguard Worker		return json.MarshalIndent(targets, "", "  ")
258*8fb009dcSAndroid Build Coastguard Worker	})
259*8fb009dcSAndroid Build Coastguard Worker}
260*8fb009dcSAndroid Build Coastguard Worker
261*8fb009dcSAndroid Build Coastguard Workerfunc soongTask(targets map[string]build.Target, dst string) Task {
262*8fb009dcSAndroid Build Coastguard Worker	return NewSimpleTask(dst, func() ([]byte, error) {
263*8fb009dcSAndroid Build Coastguard Worker		var b bytes.Buffer
264*8fb009dcSAndroid Build Coastguard Worker		writeHeader(&b, "//")
265*8fb009dcSAndroid Build Coastguard Worker
266*8fb009dcSAndroid Build Coastguard Worker		writeAttribute := func(indent, name string, val []string) {
267*8fb009dcSAndroid Build Coastguard Worker			fmt.Fprintf(&b, "%s%s: [\n", indent, name)
268*8fb009dcSAndroid Build Coastguard Worker			for _, v := range val {
269*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "%s    %q,\n", indent, v)
270*8fb009dcSAndroid Build Coastguard Worker			}
271*8fb009dcSAndroid Build Coastguard Worker			fmt.Fprintf(&b, "%s],\n", indent)
272*8fb009dcSAndroid Build Coastguard Worker
273*8fb009dcSAndroid Build Coastguard Worker		}
274*8fb009dcSAndroid Build Coastguard Worker
275*8fb009dcSAndroid Build Coastguard Worker		for _, name := range sortedKeys(targets) {
276*8fb009dcSAndroid Build Coastguard Worker			target := targets[name]
277*8fb009dcSAndroid Build Coastguard Worker			fmt.Fprintf(&b, "\ncc_defaults {\n")
278*8fb009dcSAndroid Build Coastguard Worker			fmt.Fprintf(&b, "    name: %q\n", "boringssl_"+name+"_sources")
279*8fb009dcSAndroid Build Coastguard Worker			if len(target.Srcs) != 0 {
280*8fb009dcSAndroid Build Coastguard Worker				writeAttribute("    ", "srcs", target.Srcs)
281*8fb009dcSAndroid Build Coastguard Worker			}
282*8fb009dcSAndroid Build Coastguard Worker			if len(target.Data) != 0 {
283*8fb009dcSAndroid Build Coastguard Worker				writeAttribute("    ", "data", target.Data)
284*8fb009dcSAndroid Build Coastguard Worker			}
285*8fb009dcSAndroid Build Coastguard Worker			if len(target.Asm) != 0 {
286*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "    target: {\n")
287*8fb009dcSAndroid Build Coastguard Worker				// Only emit asm for Linux. On Windows, BoringSSL requires NASM, which is
288*8fb009dcSAndroid Build Coastguard Worker				// not available in AOSP. On Darwin, the assembly works fine, but it
289*8fb009dcSAndroid Build Coastguard Worker				// conflicts with Android's FIPS build. See b/294399371.
290*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "        linux: {\n")
291*8fb009dcSAndroid Build Coastguard Worker				writeAttribute("            ", "srcs", target.Asm)
292*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "        },\n")
293*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "        darwin: {\n")
294*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "            cflags: [\"-DOPENSSL_NO_ASM\"],\n")
295*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "        },\n")
296*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "        windows: {\n")
297*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "            cflags: [\"-DOPENSSL_NO_ASM\"],\n")
298*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "        },\n")
299*8fb009dcSAndroid Build Coastguard Worker				fmt.Fprintf(&b, "    },\n")
300*8fb009dcSAndroid Build Coastguard Worker			}
301*8fb009dcSAndroid Build Coastguard Worker			fmt.Fprintf(&b, "},\n")
302*8fb009dcSAndroid Build Coastguard Worker		}
303*8fb009dcSAndroid Build Coastguard Worker
304*8fb009dcSAndroid Build Coastguard Worker		return b.Bytes(), nil
305*8fb009dcSAndroid Build Coastguard Worker	})
306*8fb009dcSAndroid Build Coastguard Worker}
307*8fb009dcSAndroid Build Coastguard Worker
308*8fb009dcSAndroid Build Coastguard Workerfunc MakeBuildFiles(targets map[string]build.Target) []Task {
309*8fb009dcSAndroid Build Coastguard Worker	// TODO(crbug.com/boringssl/542): Generate the build files for the other
310*8fb009dcSAndroid Build Coastguard Worker	// types as well.
311*8fb009dcSAndroid Build Coastguard Worker	return []Task{
312*8fb009dcSAndroid Build Coastguard Worker		buildVariablesTask(targets, "gen/sources.bzl", "#", writeBazelVariable),
313*8fb009dcSAndroid Build Coastguard Worker		buildVariablesTask(targets, "gen/sources.cmake", "#", writeCMakeVariable),
314*8fb009dcSAndroid Build Coastguard Worker		jsonTask(targets, "gen/sources.json"),
315*8fb009dcSAndroid Build Coastguard Worker	}
316*8fb009dcSAndroid Build Coastguard Worker}
317