• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2015, Google Inc.
2#
3# Permission to use, copy, modify, and/or distribute this software for any
4# purpose with or without fee is hereby granted, provided that the above
5# copyright notice and this permission notice appear in all copies.
6#
7# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15"""Enumerates source files for consumption by various build systems."""
16
17import optparse
18import os
19import subprocess
20import sys
21import json
22
23
24# OS_ARCH_COMBOS maps from OS and platform to the OpenSSL assembly "style" for
25# that platform and the extension used by asm files.
26OS_ARCH_COMBOS = [
27    ('ios', 'arm', 'ios32', [], 'S'),
28    ('ios', 'aarch64', 'ios64', [], 'S'),
29    ('linux', 'arm', 'linux32', [], 'S'),
30    ('linux', 'aarch64', 'linux64', [], 'S'),
31    ('linux', 'ppc64le', 'linux64le', [], 'S'),
32    ('linux', 'x86', 'elf', ['-fPIC', '-DOPENSSL_IA32_SSE2'], 'S'),
33    ('linux', 'x86_64', 'elf', [], 'S'),
34    ('mac', 'x86', 'macosx', ['-fPIC', '-DOPENSSL_IA32_SSE2'], 'S'),
35    ('mac', 'x86_64', 'macosx', [], 'S'),
36    ('win', 'x86', 'win32n', ['-DOPENSSL_IA32_SSE2'], 'asm'),
37    ('win', 'x86_64', 'nasm', [], 'asm'),
38]
39
40# NON_PERL_FILES enumerates assembly files that are not processed by the
41# perlasm system.
42NON_PERL_FILES = {
43    ('linux', 'arm'): [
44        'src/crypto/curve25519/asm/x25519-asm-arm.S',
45        'src/crypto/poly1305/poly1305_arm_asm.S',
46    ],
47    ('linux', 'x86_64'): [
48        'src/crypto/hrss/asm/poly_rq_mul.S',
49    ],
50}
51
52PREFIX = None
53EMBED_TEST_DATA = True
54
55
56def PathOf(x):
57  return x if not PREFIX else os.path.join(PREFIX, x)
58
59
60class Android(object):
61
62  def __init__(self):
63    self.header = \
64"""# Copyright (C) 2015 The Android Open Source Project
65#
66# Licensed under the Apache License, Version 2.0 (the "License");
67# you may not use this file except in compliance with the License.
68# You may obtain a copy of the License at
69#
70#      http://www.apache.org/licenses/LICENSE-2.0
71#
72# Unless required by applicable law or agreed to in writing, software
73# distributed under the License is distributed on an "AS IS" BASIS,
74# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75# See the License for the specific language governing permissions and
76# limitations under the License.
77
78# This file is created by generate_build_files.py. Do not edit manually.
79
80"""
81
82  def PrintVariableSection(self, out, name, files):
83    out.write('%s := \\\n' % name)
84    for f in sorted(files):
85      out.write('  %s\\\n' % f)
86    out.write('\n')
87
88  def WriteFiles(self, files, asm_outputs):
89    # New Android.bp format
90    with open('sources.bp', 'w+') as blueprint:
91      blueprint.write(self.header.replace('#', '//'))
92
93      blueprint.write('cc_defaults {\n')
94      blueprint.write('    name: "libcrypto_sources",\n')
95      blueprint.write('    srcs: [\n')
96      for f in sorted(files['crypto']):
97        blueprint.write('        "%s",\n' % f)
98      blueprint.write('    ],\n')
99      blueprint.write('    target: {\n')
100
101      for ((osname, arch), asm_files) in asm_outputs:
102        if osname != 'linux' or arch == 'ppc64le':
103          continue
104        if arch == 'aarch64':
105          arch = 'arm64'
106
107        blueprint.write('        linux_%s: {\n' % arch)
108        blueprint.write('            srcs: [\n')
109        for f in sorted(asm_files):
110          blueprint.write('                "%s",\n' % f)
111        blueprint.write('            ],\n')
112        blueprint.write('        },\n')
113
114      blueprint.write('    },\n')
115      blueprint.write('}\n\n')
116
117      blueprint.write('cc_defaults {\n')
118      blueprint.write('    name: "libssl_sources",\n')
119      blueprint.write('    srcs: [\n')
120      for f in sorted(files['ssl']):
121        blueprint.write('        "%s",\n' % f)
122      blueprint.write('    ],\n')
123      blueprint.write('}\n\n')
124
125      blueprint.write('cc_defaults {\n')
126      blueprint.write('    name: "bssl_sources",\n')
127      blueprint.write('    srcs: [\n')
128      for f in sorted(files['tool']):
129        blueprint.write('        "%s",\n' % f)
130      blueprint.write('    ],\n')
131      blueprint.write('}\n\n')
132
133      blueprint.write('cc_defaults {\n')
134      blueprint.write('    name: "boringssl_test_support_sources",\n')
135      blueprint.write('    srcs: [\n')
136      for f in sorted(files['test_support']):
137        blueprint.write('        "%s",\n' % f)
138      blueprint.write('    ],\n')
139      blueprint.write('}\n\n')
140
141      blueprint.write('cc_defaults {\n')
142      blueprint.write('    name: "boringssl_crypto_test_sources",\n')
143      blueprint.write('    srcs: [\n')
144      for f in sorted(files['crypto_test']):
145        blueprint.write('        "%s",\n' % f)
146      blueprint.write('    ],\n')
147      blueprint.write('}\n\n')
148
149      blueprint.write('cc_defaults {\n')
150      blueprint.write('    name: "boringssl_ssl_test_sources",\n')
151      blueprint.write('    srcs: [\n')
152      for f in sorted(files['ssl_test']):
153        blueprint.write('        "%s",\n' % f)
154      blueprint.write('    ],\n')
155      blueprint.write('}\n\n')
156
157    # Legacy Android.mk format, only used by Trusty in new branches
158    with open('sources.mk', 'w+') as makefile:
159      makefile.write(self.header)
160
161      self.PrintVariableSection(makefile, 'crypto_sources', files['crypto'])
162
163      for ((osname, arch), asm_files) in asm_outputs:
164        if osname != 'linux':
165          continue
166        self.PrintVariableSection(
167            makefile, '%s_%s_sources' % (osname, arch), asm_files)
168
169
170class Bazel(object):
171  """Bazel outputs files suitable for including in Bazel files."""
172
173  def __init__(self):
174    self.firstSection = True
175    self.header = \
176"""# This file is created by generate_build_files.py. Do not edit manually.
177
178"""
179
180  def PrintVariableSection(self, out, name, files):
181    if not self.firstSection:
182      out.write('\n')
183    self.firstSection = False
184
185    out.write('%s = [\n' % name)
186    for f in sorted(files):
187      out.write('    "%s",\n' % PathOf(f))
188    out.write(']\n')
189
190  def WriteFiles(self, files, asm_outputs):
191    with open('BUILD.generated.bzl', 'w+') as out:
192      out.write(self.header)
193
194      self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers'])
195      self.PrintVariableSection(out, 'fips_fragments', files['fips_fragments'])
196      self.PrintVariableSection(
197          out, 'ssl_internal_headers', files['ssl_internal_headers'])
198      self.PrintVariableSection(out, 'ssl_sources', files['ssl'])
199      self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers'])
200      self.PrintVariableSection(
201          out, 'crypto_internal_headers', files['crypto_internal_headers'])
202      self.PrintVariableSection(out, 'crypto_sources', files['crypto'])
203      self.PrintVariableSection(out, 'tool_sources', files['tool'])
204      self.PrintVariableSection(out, 'tool_headers', files['tool_headers'])
205
206      for ((osname, arch), asm_files) in asm_outputs:
207        self.PrintVariableSection(
208            out, 'crypto_sources_%s_%s' % (osname, arch), asm_files)
209
210    with open('BUILD.generated_tests.bzl', 'w+') as out:
211      out.write(self.header)
212
213      out.write('test_support_sources = [\n')
214      for filename in sorted(files['test_support'] +
215                             files['test_support_headers'] +
216                             files['crypto_internal_headers'] +
217                             files['ssl_internal_headers']):
218        if os.path.basename(filename) == 'malloc.cc':
219          continue
220        out.write('    "%s",\n' % PathOf(filename))
221
222      out.write(']\n')
223
224      self.PrintVariableSection(out, 'crypto_test_sources',
225                                files['crypto_test'])
226      self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test'])
227      self.PrintVariableSection(out, 'crypto_test_data',
228                                files['crypto_test_data'])
229
230
231class Eureka(object):
232
233  def __init__(self):
234    self.header = \
235"""# Copyright (C) 2017 The Android Open Source Project
236#
237# Licensed under the Apache License, Version 2.0 (the "License");
238# you may not use this file except in compliance with the License.
239# You may obtain a copy of the License at
240#
241#      http://www.apache.org/licenses/LICENSE-2.0
242#
243# Unless required by applicable law or agreed to in writing, software
244# distributed under the License is distributed on an "AS IS" BASIS,
245# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
246# See the License for the specific language governing permissions and
247# limitations under the License.
248
249# This file is created by generate_build_files.py. Do not edit manually.
250
251"""
252
253  def PrintVariableSection(self, out, name, files):
254    out.write('%s := \\\n' % name)
255    for f in sorted(files):
256      out.write('  %s\\\n' % f)
257    out.write('\n')
258
259  def WriteFiles(self, files, asm_outputs):
260    # Legacy Android.mk format
261    with open('eureka.mk', 'w+') as makefile:
262      makefile.write(self.header)
263
264      self.PrintVariableSection(makefile, 'crypto_sources', files['crypto'])
265      self.PrintVariableSection(makefile, 'ssl_sources', files['ssl'])
266      self.PrintVariableSection(makefile, 'tool_sources', files['tool'])
267
268      for ((osname, arch), asm_files) in asm_outputs:
269        if osname != 'linux':
270          continue
271        self.PrintVariableSection(
272            makefile, '%s_%s_sources' % (osname, arch), asm_files)
273
274
275class GN(object):
276
277  def __init__(self):
278    self.firstSection = True
279    self.header = \
280"""# Copyright (c) 2016 The Chromium Authors. All rights reserved.
281# Use of this source code is governed by a BSD-style license that can be
282# found in the LICENSE file.
283
284# This file is created by generate_build_files.py. Do not edit manually.
285
286"""
287
288  def PrintVariableSection(self, out, name, files):
289    if not self.firstSection:
290      out.write('\n')
291    self.firstSection = False
292
293    out.write('%s = [\n' % name)
294    for f in sorted(files):
295      out.write('  "%s",\n' % f)
296    out.write(']\n')
297
298  def WriteFiles(self, files, asm_outputs):
299    with open('BUILD.generated.gni', 'w+') as out:
300      out.write(self.header)
301
302      self.PrintVariableSection(out, 'crypto_sources',
303                                files['crypto'] +
304                                files['crypto_internal_headers'])
305      self.PrintVariableSection(out, 'crypto_headers',
306                                files['crypto_headers'])
307      self.PrintVariableSection(out, 'ssl_sources',
308                                files['ssl'] + files['ssl_internal_headers'])
309      self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers'])
310
311      for ((osname, arch), asm_files) in asm_outputs:
312        self.PrintVariableSection(
313            out, 'crypto_sources_%s_%s' % (osname, arch), asm_files)
314
315      fuzzers = [os.path.splitext(os.path.basename(fuzzer))[0]
316                 for fuzzer in files['fuzz']]
317      self.PrintVariableSection(out, 'fuzzers', fuzzers)
318
319    with open('BUILD.generated_tests.gni', 'w+') as out:
320      self.firstSection = True
321      out.write(self.header)
322
323      self.PrintVariableSection(out, 'test_support_sources',
324                                files['test_support'] +
325                                files['test_support_headers'])
326      self.PrintVariableSection(out, 'crypto_test_sources',
327                                files['crypto_test'])
328      self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test'])
329
330
331class GYP(object):
332
333  def __init__(self):
334    self.header = \
335"""# Copyright (c) 2016 The Chromium Authors. All rights reserved.
336# Use of this source code is governed by a BSD-style license that can be
337# found in the LICENSE file.
338
339# This file is created by generate_build_files.py. Do not edit manually.
340
341"""
342
343  def PrintVariableSection(self, out, name, files):
344    out.write('    \'%s\': [\n' % name)
345    for f in sorted(files):
346      out.write('      \'%s\',\n' % f)
347    out.write('    ],\n')
348
349  def WriteFiles(self, files, asm_outputs):
350    with open('boringssl.gypi', 'w+') as gypi:
351      gypi.write(self.header + '{\n  \'variables\': {\n')
352
353      self.PrintVariableSection(gypi, 'boringssl_ssl_sources',
354                                files['ssl'] + files['ssl_headers'] +
355                                files['ssl_internal_headers'])
356      self.PrintVariableSection(gypi, 'boringssl_crypto_sources',
357                                files['crypto'] + files['crypto_headers'] +
358                                files['crypto_internal_headers'])
359
360      for ((osname, arch), asm_files) in asm_outputs:
361        self.PrintVariableSection(gypi, 'boringssl_%s_%s_sources' %
362                                  (osname, arch), asm_files)
363
364      gypi.write('  }\n}\n')
365
366
367def FindCMakeFiles(directory):
368  """Returns list of all CMakeLists.txt files recursively in directory."""
369  cmakefiles = []
370
371  for (path, _, filenames) in os.walk(directory):
372    for filename in filenames:
373      if filename == 'CMakeLists.txt':
374        cmakefiles.append(os.path.join(path, filename))
375
376  return cmakefiles
377
378def OnlyFIPSFragments(path, dent, is_dir):
379  return is_dir or (path.startswith(
380      os.path.join('src', 'crypto', 'fipsmodule', '')) and
381      NoTests(path, dent, is_dir))
382
383def NoTestsNorFIPSFragments(path, dent, is_dir):
384  return (NoTests(path, dent, is_dir) and
385      (is_dir or not OnlyFIPSFragments(path, dent, is_dir)))
386
387def NoTests(path, dent, is_dir):
388  """Filter function that can be passed to FindCFiles in order to remove test
389  sources."""
390  if is_dir:
391    return dent != 'test'
392  return 'test.' not in dent
393
394
395def OnlyTests(path, dent, is_dir):
396  """Filter function that can be passed to FindCFiles in order to remove
397  non-test sources."""
398  if is_dir:
399    return dent != 'test'
400  return '_test.' in dent
401
402
403def AllFiles(path, dent, is_dir):
404  """Filter function that can be passed to FindCFiles in order to include all
405  sources."""
406  return True
407
408
409def NoTestRunnerFiles(path, dent, is_dir):
410  """Filter function that can be passed to FindCFiles or FindHeaderFiles in
411  order to exclude test runner files."""
412  # NOTE(martinkr): This prevents .h/.cc files in src/ssl/test/runner, which
413  # are in their own subpackage, from being included in boringssl/BUILD files.
414  return not is_dir or dent != 'runner'
415
416
417def NotGTestSupport(path, dent, is_dir):
418  return 'gtest' not in dent and 'abi_test' not in dent
419
420
421def SSLHeaderFiles(path, dent, is_dir):
422  return dent in ['ssl.h', 'tls1.h', 'ssl23.h', 'ssl3.h', 'dtls1.h', 'srtp.h']
423
424
425def FindCFiles(directory, filter_func):
426  """Recurses through directory and returns a list of paths to all the C source
427  files that pass filter_func."""
428  cfiles = []
429
430  for (path, dirnames, filenames) in os.walk(directory):
431    for filename in filenames:
432      if not filename.endswith('.c') and not filename.endswith('.cc'):
433        continue
434      if not filter_func(path, filename, False):
435        continue
436      cfiles.append(os.path.join(path, filename))
437
438    for (i, dirname) in enumerate(dirnames):
439      if not filter_func(path, dirname, True):
440        del dirnames[i]
441
442  return cfiles
443
444
445def FindHeaderFiles(directory, filter_func):
446  """Recurses through directory and returns a list of paths to all the header files that pass filter_func."""
447  hfiles = []
448
449  for (path, dirnames, filenames) in os.walk(directory):
450    for filename in filenames:
451      if not filename.endswith('.h'):
452        continue
453      if not filter_func(path, filename, False):
454        continue
455      hfiles.append(os.path.join(path, filename))
456
457      for (i, dirname) in enumerate(dirnames):
458        if not filter_func(path, dirname, True):
459          del dirnames[i]
460
461  return hfiles
462
463
464def ExtractPerlAsmFromCMakeFile(cmakefile):
465  """Parses the contents of the CMakeLists.txt file passed as an argument and
466  returns a list of all the perlasm() directives found in the file."""
467  perlasms = []
468  with open(cmakefile) as f:
469    for line in f:
470      line = line.strip()
471      if not line.startswith('perlasm('):
472        continue
473      if not line.endswith(')'):
474        raise ValueError('Bad perlasm line in %s' % cmakefile)
475      # Remove "perlasm(" from start and ")" from end
476      params = line[8:-1].split()
477      if len(params) < 2:
478        raise ValueError('Bad perlasm line in %s' % cmakefile)
479      perlasms.append({
480          'extra_args': params[2:],
481          'input': os.path.join(os.path.dirname(cmakefile), params[1]),
482          'output': os.path.join(os.path.dirname(cmakefile), params[0]),
483      })
484
485  return perlasms
486
487
488def ReadPerlAsmOperations():
489  """Returns a list of all perlasm() directives found in CMake config files in
490  src/."""
491  perlasms = []
492  cmakefiles = FindCMakeFiles('src')
493
494  for cmakefile in cmakefiles:
495    perlasms.extend(ExtractPerlAsmFromCMakeFile(cmakefile))
496
497  return perlasms
498
499
500def PerlAsm(output_filename, input_filename, perlasm_style, extra_args):
501  """Runs the a perlasm script and puts the output into output_filename."""
502  base_dir = os.path.dirname(output_filename)
503  if not os.path.isdir(base_dir):
504    os.makedirs(base_dir)
505  subprocess.check_call(
506      ['perl', input_filename, perlasm_style] + extra_args + [output_filename])
507
508
509def ArchForAsmFilename(filename):
510  """Returns the architectures that a given asm file should be compiled for
511  based on substrings in the filename."""
512
513  if 'x86_64' in filename or 'avx2' in filename:
514    return ['x86_64']
515  elif ('x86' in filename and 'x86_64' not in filename) or '586' in filename:
516    return ['x86']
517  elif 'armx' in filename:
518    return ['arm', 'aarch64']
519  elif 'armv8' in filename:
520    return ['aarch64']
521  elif 'arm' in filename:
522    return ['arm']
523  elif 'ppc' in filename:
524    return ['ppc64le']
525  else:
526    raise ValueError('Unknown arch for asm filename: ' + filename)
527
528
529def WriteAsmFiles(perlasms):
530  """Generates asm files from perlasm directives for each supported OS x
531  platform combination."""
532  asmfiles = {}
533
534  for osarch in OS_ARCH_COMBOS:
535    (osname, arch, perlasm_style, extra_args, asm_ext) = osarch
536    key = (osname, arch)
537    outDir = '%s-%s' % key
538
539    for perlasm in perlasms:
540      filename = os.path.basename(perlasm['input'])
541      output = perlasm['output']
542      if not output.startswith('src'):
543        raise ValueError('output missing src: %s' % output)
544      output = os.path.join(outDir, output[4:])
545      if output.endswith('-armx.${ASM_EXT}'):
546        output = output.replace('-armx',
547                                '-armx64' if arch == 'aarch64' else '-armx32')
548      output = output.replace('${ASM_EXT}', asm_ext)
549
550      if arch in ArchForAsmFilename(filename):
551        PerlAsm(output, perlasm['input'], perlasm_style,
552                perlasm['extra_args'] + extra_args)
553        asmfiles.setdefault(key, []).append(output)
554
555  for (key, non_perl_asm_files) in NON_PERL_FILES.iteritems():
556    asmfiles.setdefault(key, []).extend(non_perl_asm_files)
557
558  return asmfiles
559
560
561def ExtractVariablesFromCMakeFile(cmakefile):
562  """Parses the contents of the CMakeLists.txt file passed as an argument and
563  returns a dictionary of exported source lists."""
564  variables = {}
565  in_set_command = False
566  set_command = []
567  with open(cmakefile) as f:
568    for line in f:
569      if '#' in line:
570        line = line[:line.index('#')]
571      line = line.strip()
572
573      if not in_set_command:
574        if line.startswith('set('):
575          in_set_command = True
576          set_command = []
577      elif line == ')':
578        in_set_command = False
579        if not set_command:
580          raise ValueError('Empty set command')
581        variables[set_command[0]] = set_command[1:]
582      else:
583        set_command.extend([c for c in line.split(' ') if c])
584
585  if in_set_command:
586    raise ValueError('Unfinished set command')
587  return variables
588
589
590def main(platforms):
591  cmake = ExtractVariablesFromCMakeFile(os.path.join('src', 'sources.cmake'))
592  crypto_c_files = (FindCFiles(os.path.join('src', 'crypto'), NoTestsNorFIPSFragments) +
593                    FindCFiles(os.path.join('src', 'third_party', 'fiat'), NoTestsNorFIPSFragments))
594  fips_fragments = FindCFiles(os.path.join('src', 'crypto', 'fipsmodule'), OnlyFIPSFragments)
595  ssl_source_files = FindCFiles(os.path.join('src', 'ssl'), NoTests)
596  tool_c_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
597  tool_h_files = FindHeaderFiles(os.path.join('src', 'tool'), AllFiles)
598
599  # third_party/fiat/p256.c lives in third_party/fiat, but it is a FIPS
600  # fragment, not a normal source file.
601  p256 = os.path.join('src', 'third_party', 'fiat', 'p256.c')
602  fips_fragments.append(p256)
603  crypto_c_files.remove(p256)
604
605  # Generate err_data.c
606  with open('err_data.c', 'w+') as err_data:
607    subprocess.check_call(['go', 'run', 'err_data_generate.go'],
608                          cwd=os.path.join('src', 'crypto', 'err'),
609                          stdout=err_data)
610  crypto_c_files.append('err_data.c')
611
612  test_support_c_files = FindCFiles(os.path.join('src', 'crypto', 'test'),
613                                    NotGTestSupport)
614  test_support_h_files = (
615      FindHeaderFiles(os.path.join('src', 'crypto', 'test'), AllFiles) +
616      FindHeaderFiles(os.path.join('src', 'ssl', 'test'), NoTestRunnerFiles))
617
618  crypto_test_files = []
619  if EMBED_TEST_DATA:
620    # Generate crypto_test_data.cc
621    with open('crypto_test_data.cc', 'w+') as out:
622      subprocess.check_call(
623          ['go', 'run', 'util/embed_test_data.go'] + cmake['CRYPTO_TEST_DATA'],
624          cwd='src',
625          stdout=out)
626    crypto_test_files += ['crypto_test_data.cc']
627
628  crypto_test_files += FindCFiles(os.path.join('src', 'crypto'), OnlyTests)
629  crypto_test_files += [
630      'src/crypto/test/abi_test.cc',
631      'src/crypto/test/file_test_gtest.cc',
632      'src/crypto/test/gtest_main.cc',
633  ]
634
635  ssl_test_files = FindCFiles(os.path.join('src', 'ssl'), OnlyTests)
636  ssl_test_files += [
637      'src/crypto/test/abi_test.cc',
638      'src/crypto/test/gtest_main.cc',
639  ]
640
641  fuzz_c_files = FindCFiles(os.path.join('src', 'fuzz'), NoTests)
642
643  ssl_h_files = (
644      FindHeaderFiles(
645          os.path.join('src', 'include', 'openssl'),
646          SSLHeaderFiles))
647
648  def NotSSLHeaderFiles(path, filename, is_dir):
649    return not SSLHeaderFiles(path, filename, is_dir)
650  crypto_h_files = (
651      FindHeaderFiles(
652          os.path.join('src', 'include', 'openssl'),
653          NotSSLHeaderFiles))
654
655  ssl_internal_h_files = FindHeaderFiles(os.path.join('src', 'ssl'), NoTests)
656  crypto_internal_h_files = (
657      FindHeaderFiles(os.path.join('src', 'crypto'), NoTests) +
658      FindHeaderFiles(os.path.join('src', 'third_party', 'fiat'), NoTests))
659
660  files = {
661      'crypto': crypto_c_files,
662      'crypto_headers': crypto_h_files,
663      'crypto_internal_headers': crypto_internal_h_files,
664      'crypto_test': sorted(crypto_test_files),
665      'crypto_test_data': sorted('src/' + x for x in cmake['CRYPTO_TEST_DATA']),
666      'fips_fragments': fips_fragments,
667      'fuzz': fuzz_c_files,
668      'ssl': ssl_source_files,
669      'ssl_headers': ssl_h_files,
670      'ssl_internal_headers': ssl_internal_h_files,
671      'ssl_test': sorted(ssl_test_files),
672      'tool': tool_c_files,
673      'tool_headers': tool_h_files,
674      'test_support': test_support_c_files,
675      'test_support_headers': test_support_h_files,
676  }
677
678  asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).iteritems())
679
680  for platform in platforms:
681    platform.WriteFiles(files, asm_outputs)
682
683  return 0
684
685
686if __name__ == '__main__':
687  parser = optparse.OptionParser(usage='Usage: %prog [--prefix=<path>]'
688      ' [android|bazel|eureka|gn|gyp]')
689  parser.add_option('--prefix', dest='prefix',
690      help='For Bazel, prepend argument to all source files')
691  parser.add_option(
692      '--embed_test_data', type='choice', dest='embed_test_data',
693      action='store', default="true", choices=["true", "false"],
694      help='For Bazel, don\'t embed data files in crypto_test_data.cc')
695  options, args = parser.parse_args(sys.argv[1:])
696  PREFIX = options.prefix
697  EMBED_TEST_DATA = (options.embed_test_data == "true")
698
699  if not args:
700    parser.print_help()
701    sys.exit(1)
702
703  platforms = []
704  for s in args:
705    if s == 'android':
706      platforms.append(Android())
707    elif s == 'bazel':
708      platforms.append(Bazel())
709    elif s == 'eureka':
710      platforms.append(Eureka())
711    elif s == 'gn':
712      platforms.append(GN())
713    elif s == 'gyp':
714      platforms.append(GYP())
715    else:
716      parser.print_help()
717      sys.exit(1)
718
719  sys.exit(main(platforms))
720