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 ('linux', 'arm', 'linux32', [], 'S'), 28 ('linux', 'aarch64', 'linux64', [], 'S'), 29 ('linux', 'ppc64le', 'ppc64le', [], 'S'), 30 ('linux', 'x86', 'elf', ['-fPIC', '-DOPENSSL_IA32_SSE2'], 'S'), 31 ('linux', 'x86_64', 'elf', [], 'S'), 32 ('mac', 'x86', 'macosx', ['-fPIC', '-DOPENSSL_IA32_SSE2'], 'S'), 33 ('mac', 'x86_64', 'macosx', [], 'S'), 34 ('win', 'x86', 'win32n', ['-DOPENSSL_IA32_SSE2'], 'asm'), 35 ('win', 'x86_64', 'nasm', [], 'asm'), 36] 37 38# NON_PERL_FILES enumerates assembly files that are not processed by the 39# perlasm system. 40NON_PERL_FILES = { 41 ('linux', 'arm'): [ 42 'src/crypto/curve25519/asm/x25519-asm-arm.S', 43 'src/crypto/poly1305/poly1305_arm_asm.S', 44 ], 45 ('linux', 'x86_64'): [ 46 'src/crypto/curve25519/asm/x25519-asm-x86_64.S', 47 ], 48 ('mac', 'x86_64'): [ 49 'src/crypto/curve25519/asm/x25519-asm-x86_64.S', 50 ], 51} 52 53PREFIX = None 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(' android_%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 if arch == 'x86' or arch == 'x86_64': 115 blueprint.write(' linux_%s: {\n' % arch) 116 blueprint.write(' srcs: [\n') 117 for f in sorted(asm_files): 118 blueprint.write(' "%s",\n' % f) 119 blueprint.write(' ],\n') 120 blueprint.write(' },\n') 121 122 blueprint.write(' },\n') 123 blueprint.write('}\n\n') 124 125 blueprint.write('cc_defaults {\n') 126 blueprint.write(' name: "libssl_sources",\n') 127 blueprint.write(' srcs: [\n') 128 for f in sorted(files['ssl']): 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: "bssl_sources",\n') 135 blueprint.write(' srcs: [\n') 136 for f in sorted(files['tool']): 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_test_support_sources",\n') 143 blueprint.write(' srcs: [\n') 144 for f in sorted(files['test_support']): 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_crypto_test_sources",\n') 151 blueprint.write(' srcs: [\n') 152 for f in sorted(files['crypto_test']): 153 blueprint.write(' "%s",\n' % f) 154 blueprint.write(' ],\n') 155 blueprint.write('}\n\n') 156 157 blueprint.write('cc_defaults {\n') 158 blueprint.write(' name: "boringssl_ssl_test_sources",\n') 159 blueprint.write(' srcs: [\n') 160 for f in sorted(files['ssl_test']): 161 blueprint.write(' "%s",\n' % f) 162 blueprint.write(' ],\n') 163 blueprint.write('}\n\n') 164 165 blueprint.write('cc_defaults {\n') 166 blueprint.write(' name: "boringssl_tests_sources",\n') 167 blueprint.write(' srcs: [\n') 168 for f in sorted(files['test']): 169 blueprint.write(' "%s",\n' % f) 170 blueprint.write(' ],\n') 171 blueprint.write('}\n') 172 173 # Legacy Android.mk format, only used by Trusty in new branches 174 with open('sources.mk', 'w+') as makefile: 175 makefile.write(self.header) 176 177 self.PrintVariableSection(makefile, 'crypto_sources', files['crypto']) 178 179 for ((osname, arch), asm_files) in asm_outputs: 180 if osname != 'linux': 181 continue 182 self.PrintVariableSection( 183 makefile, '%s_%s_sources' % (osname, arch), asm_files) 184 185 186class Bazel(object): 187 """Bazel outputs files suitable for including in Bazel files.""" 188 189 def __init__(self): 190 self.firstSection = True 191 self.header = \ 192"""# This file is created by generate_build_files.py. Do not edit manually. 193 194""" 195 196 def PrintVariableSection(self, out, name, files): 197 if not self.firstSection: 198 out.write('\n') 199 self.firstSection = False 200 201 out.write('%s = [\n' % name) 202 for f in sorted(files): 203 out.write(' "%s",\n' % PathOf(f)) 204 out.write(']\n') 205 206 def WriteFiles(self, files, asm_outputs): 207 with open('BUILD.generated.bzl', 'w+') as out: 208 out.write(self.header) 209 210 self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers']) 211 self.PrintVariableSection( 212 out, 'ssl_internal_headers', files['ssl_internal_headers']) 213 self.PrintVariableSection(out, 'ssl_sources', files['ssl']) 214 self.PrintVariableSection(out, 'ssl_c_sources', files['ssl_c']) 215 self.PrintVariableSection(out, 'ssl_cc_sources', files['ssl_cc']) 216 self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers']) 217 self.PrintVariableSection( 218 out, 'crypto_internal_headers', files['crypto_internal_headers']) 219 self.PrintVariableSection(out, 'crypto_sources', files['crypto']) 220 self.PrintVariableSection(out, 'tool_sources', files['tool']) 221 self.PrintVariableSection(out, 'tool_headers', files['tool_headers']) 222 223 for ((osname, arch), asm_files) in asm_outputs: 224 self.PrintVariableSection( 225 out, 'crypto_sources_%s_%s' % (osname, arch), asm_files) 226 227 with open('BUILD.generated_tests.bzl', 'w+') as out: 228 out.write(self.header) 229 230 out.write('test_support_sources = [\n') 231 for filename in sorted(files['test_support'] + 232 files['test_support_headers'] + 233 files['crypto_internal_headers'] + 234 files['ssl_internal_headers']): 235 if os.path.basename(filename) == 'malloc.cc': 236 continue 237 out.write(' "%s",\n' % PathOf(filename)) 238 239 out.write(']\n\n') 240 241 self.PrintVariableSection(out, 'crypto_test_sources', 242 files['crypto_test']) 243 self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test']) 244 245 out.write('def create_tests(copts, crypto, ssl):\n') 246 name_counts = {} 247 for test in files['tests']: 248 name = os.path.basename(test[0]) 249 name_counts[name] = name_counts.get(name, 0) + 1 250 251 first = True 252 for test in files['tests']: 253 name = os.path.basename(test[0]) 254 if name_counts[name] > 1: 255 if '/' in test[1]: 256 name += '_' + os.path.splitext(os.path.basename(test[1]))[0] 257 else: 258 name += '_' + test[1].replace('-', '_') 259 260 if not first: 261 out.write('\n') 262 first = False 263 264 src_prefix = 'src/' + test[0] 265 for src in files['test']: 266 if src.startswith(src_prefix): 267 src = src 268 break 269 else: 270 raise ValueError("Can't find source for %s" % test[0]) 271 272 out.write(' native.cc_test(\n') 273 out.write(' name = "%s",\n' % name) 274 out.write(' size = "small",\n') 275 out.write(' srcs = ["%s"] + test_support_sources,\n' % 276 PathOf(src)) 277 278 data_files = [] 279 if len(test) > 1: 280 281 out.write(' args = [\n') 282 for arg in test[1:]: 283 if '/' in arg: 284 out.write(' "$(location %s)",\n' % 285 PathOf(os.path.join('src', arg))) 286 data_files.append('src/%s' % arg) 287 else: 288 out.write(' "%s",\n' % arg) 289 out.write(' ],\n') 290 291 out.write(' copts = copts + ["-DBORINGSSL_SHARED_LIBRARY"],\n') 292 293 if len(data_files) > 0: 294 out.write(' data = [\n') 295 for filename in data_files: 296 out.write(' "%s",\n' % PathOf(filename)) 297 out.write(' ],\n') 298 299 if 'ssl/' in test[0]: 300 out.write(' deps = [\n') 301 out.write(' crypto,\n') 302 out.write(' ssl,\n') 303 out.write(' ],\n') 304 else: 305 out.write(' deps = [crypto],\n') 306 out.write(' )\n') 307 308 309class GN(object): 310 311 def __init__(self): 312 self.firstSection = True 313 self.header = \ 314"""# Copyright (c) 2016 The Chromium Authors. All rights reserved. 315# Use of this source code is governed by a BSD-style license that can be 316# found in the LICENSE file. 317 318# This file is created by generate_build_files.py. Do not edit manually. 319 320""" 321 322 def PrintVariableSection(self, out, name, files): 323 if not self.firstSection: 324 out.write('\n') 325 self.firstSection = False 326 327 out.write('%s = [\n' % name) 328 for f in sorted(files): 329 out.write(' "%s",\n' % f) 330 out.write(']\n') 331 332 def WriteFiles(self, files, asm_outputs): 333 with open('BUILD.generated.gni', 'w+') as out: 334 out.write(self.header) 335 336 self.PrintVariableSection(out, 'crypto_sources', 337 files['crypto'] + files['crypto_headers'] + 338 files['crypto_internal_headers']) 339 self.PrintVariableSection(out, 'ssl_sources', 340 files['ssl'] + files['ssl_headers'] + 341 files['ssl_internal_headers']) 342 343 for ((osname, arch), asm_files) in asm_outputs: 344 self.PrintVariableSection( 345 out, 'crypto_sources_%s_%s' % (osname, arch), asm_files) 346 347 fuzzers = [os.path.splitext(os.path.basename(fuzzer))[0] 348 for fuzzer in files['fuzz']] 349 self.PrintVariableSection(out, 'fuzzers', fuzzers) 350 351 with open('BUILD.generated_tests.gni', 'w+') as out: 352 self.firstSection = True 353 out.write(self.header) 354 355 self.PrintVariableSection(out, 'test_support_sources', 356 files['test_support'] + 357 files['test_support_headers']) 358 self.PrintVariableSection(out, 'crypto_test_sources', 359 files['crypto_test']) 360 self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test']) 361 out.write('\n') 362 363 out.write('template("create_tests") {\n') 364 365 all_tests = [] 366 for test in sorted(files['test']): 367 test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0] 368 all_tests.append(test_name) 369 370 out.write(' executable("%s") {\n' % test_name) 371 out.write(' sources = [\n') 372 out.write(' "%s",\n' % test) 373 out.write(' ]\n') 374 out.write(' sources += test_support_sources\n') 375 out.write(' if (defined(invoker.configs_exclude)) {\n') 376 out.write(' configs -= invoker.configs_exclude\n') 377 out.write(' }\n') 378 out.write(' configs += invoker.configs\n') 379 out.write(' deps = invoker.deps\n') 380 out.write(' }\n') 381 out.write('\n') 382 383 out.write(' group(target_name) {\n') 384 out.write(' deps = [\n') 385 for test_name in sorted(all_tests): 386 out.write(' ":%s",\n' % test_name) 387 out.write(' ]\n') 388 out.write(' }\n') 389 out.write('}\n') 390 391 392class GYP(object): 393 394 def __init__(self): 395 self.header = \ 396"""# Copyright (c) 2016 The Chromium Authors. All rights reserved. 397# Use of this source code is governed by a BSD-style license that can be 398# found in the LICENSE file. 399 400# This file is created by generate_build_files.py. Do not edit manually. 401 402""" 403 404 def PrintVariableSection(self, out, name, files): 405 out.write(' \'%s\': [\n' % name) 406 for f in sorted(files): 407 out.write(' \'%s\',\n' % f) 408 out.write(' ],\n') 409 410 def WriteFiles(self, files, asm_outputs): 411 with open('boringssl.gypi', 'w+') as gypi: 412 gypi.write(self.header + '{\n \'variables\': {\n') 413 414 self.PrintVariableSection(gypi, 'boringssl_ssl_sources', 415 files['ssl'] + files['ssl_headers'] + 416 files['ssl_internal_headers']) 417 self.PrintVariableSection(gypi, 'boringssl_crypto_sources', 418 files['crypto'] + files['crypto_headers'] + 419 files['crypto_internal_headers']) 420 421 for ((osname, arch), asm_files) in asm_outputs: 422 self.PrintVariableSection(gypi, 'boringssl_%s_%s_sources' % 423 (osname, arch), asm_files) 424 425 gypi.write(' }\n}\n') 426 427 428def FindCMakeFiles(directory): 429 """Returns list of all CMakeLists.txt files recursively in directory.""" 430 cmakefiles = [] 431 432 for (path, _, filenames) in os.walk(directory): 433 for filename in filenames: 434 if filename == 'CMakeLists.txt': 435 cmakefiles.append(os.path.join(path, filename)) 436 437 return cmakefiles 438 439 440def NoTests(dent, is_dir): 441 """Filter function that can be passed to FindCFiles in order to remove test 442 sources.""" 443 if is_dir: 444 return dent != 'test' 445 return 'test.' not in dent and not dent.startswith('example_') 446 447 448def OnlyTests(dent, is_dir): 449 """Filter function that can be passed to FindCFiles in order to remove 450 non-test sources.""" 451 if is_dir: 452 return dent != 'test' 453 return '_test.' in dent or dent.startswith('example_') 454 455 456def AllFiles(dent, is_dir): 457 """Filter function that can be passed to FindCFiles in order to include all 458 sources.""" 459 return True 460 461 462def NotGTestMain(dent, is_dir): 463 return dent != 'gtest_main.cc' 464 465 466def SSLHeaderFiles(dent, is_dir): 467 return dent in ['ssl.h', 'tls1.h', 'ssl23.h', 'ssl3.h', 'dtls1.h'] 468 469 470def FindCFiles(directory, filter_func): 471 """Recurses through directory and returns a list of paths to all the C source 472 files that pass filter_func.""" 473 cfiles = [] 474 475 for (path, dirnames, filenames) in os.walk(directory): 476 for filename in filenames: 477 if not filename.endswith('.c') and not filename.endswith('.cc'): 478 continue 479 if not filter_func(filename, False): 480 continue 481 cfiles.append(os.path.join(path, filename)) 482 483 for (i, dirname) in enumerate(dirnames): 484 if not filter_func(dirname, True): 485 del dirnames[i] 486 487 return cfiles 488 489 490def FindHeaderFiles(directory, filter_func): 491 """Recurses through directory and returns a list of paths to all the header files that pass filter_func.""" 492 hfiles = [] 493 494 for (path, dirnames, filenames) in os.walk(directory): 495 for filename in filenames: 496 if not filename.endswith('.h'): 497 continue 498 if not filter_func(filename, False): 499 continue 500 hfiles.append(os.path.join(path, filename)) 501 502 for (i, dirname) in enumerate(dirnames): 503 if not filter_func(dirname, True): 504 del dirnames[i] 505 506 return hfiles 507 508 509def ExtractPerlAsmFromCMakeFile(cmakefile): 510 """Parses the contents of the CMakeLists.txt file passed as an argument and 511 returns a list of all the perlasm() directives found in the file.""" 512 perlasms = [] 513 with open(cmakefile) as f: 514 for line in f: 515 line = line.strip() 516 if not line.startswith('perlasm('): 517 continue 518 if not line.endswith(')'): 519 raise ValueError('Bad perlasm line in %s' % cmakefile) 520 # Remove "perlasm(" from start and ")" from end 521 params = line[8:-1].split() 522 if len(params) < 2: 523 raise ValueError('Bad perlasm line in %s' % cmakefile) 524 perlasms.append({ 525 'extra_args': params[2:], 526 'input': os.path.join(os.path.dirname(cmakefile), params[1]), 527 'output': os.path.join(os.path.dirname(cmakefile), params[0]), 528 }) 529 530 return perlasms 531 532 533def ReadPerlAsmOperations(): 534 """Returns a list of all perlasm() directives found in CMake config files in 535 src/.""" 536 perlasms = [] 537 cmakefiles = FindCMakeFiles('src') 538 539 for cmakefile in cmakefiles: 540 perlasms.extend(ExtractPerlAsmFromCMakeFile(cmakefile)) 541 542 return perlasms 543 544 545def PerlAsm(output_filename, input_filename, perlasm_style, extra_args): 546 """Runs the a perlasm script and puts the output into output_filename.""" 547 base_dir = os.path.dirname(output_filename) 548 if not os.path.isdir(base_dir): 549 os.makedirs(base_dir) 550 subprocess.check_call( 551 ['perl', input_filename, perlasm_style] + extra_args + [output_filename]) 552 553 554def ArchForAsmFilename(filename): 555 """Returns the architectures that a given asm file should be compiled for 556 based on substrings in the filename.""" 557 558 if 'x86_64' in filename or 'avx2' in filename: 559 return ['x86_64'] 560 elif ('x86' in filename and 'x86_64' not in filename) or '586' in filename: 561 return ['x86'] 562 elif 'armx' in filename: 563 return ['arm', 'aarch64'] 564 elif 'armv8' in filename: 565 return ['aarch64'] 566 elif 'arm' in filename: 567 return ['arm'] 568 elif 'ppc' in filename: 569 return ['ppc64le'] 570 else: 571 raise ValueError('Unknown arch for asm filename: ' + filename) 572 573 574def WriteAsmFiles(perlasms): 575 """Generates asm files from perlasm directives for each supported OS x 576 platform combination.""" 577 asmfiles = {} 578 579 for osarch in OS_ARCH_COMBOS: 580 (osname, arch, perlasm_style, extra_args, asm_ext) = osarch 581 key = (osname, arch) 582 outDir = '%s-%s' % key 583 584 for perlasm in perlasms: 585 filename = os.path.basename(perlasm['input']) 586 output = perlasm['output'] 587 if not output.startswith('src'): 588 raise ValueError('output missing src: %s' % output) 589 output = os.path.join(outDir, output[4:]) 590 if output.endswith('-armx.${ASM_EXT}'): 591 output = output.replace('-armx', 592 '-armx64' if arch == 'aarch64' else '-armx32') 593 output = output.replace('${ASM_EXT}', asm_ext) 594 595 if arch in ArchForAsmFilename(filename): 596 PerlAsm(output, perlasm['input'], perlasm_style, 597 perlasm['extra_args'] + extra_args) 598 asmfiles.setdefault(key, []).append(output) 599 600 for (key, non_perl_asm_files) in NON_PERL_FILES.iteritems(): 601 asmfiles.setdefault(key, []).extend(non_perl_asm_files) 602 603 return asmfiles 604 605 606def IsGTest(path): 607 with open(path) as f: 608 return "#include <gtest/gtest.h>" in f.read() 609 610 611def main(platforms): 612 crypto_c_files = FindCFiles(os.path.join('src', 'crypto'), NoTests) 613 ssl_source_files = FindCFiles(os.path.join('src', 'ssl'), NoTests) 614 tool_c_files = FindCFiles(os.path.join('src', 'tool'), NoTests) 615 tool_h_files = FindHeaderFiles(os.path.join('src', 'tool'), AllFiles) 616 617 # Generate err_data.c 618 with open('err_data.c', 'w+') as err_data: 619 subprocess.check_call(['go', 'run', 'err_data_generate.go'], 620 cwd=os.path.join('src', 'crypto', 'err'), 621 stdout=err_data) 622 crypto_c_files.append('err_data.c') 623 624 test_support_c_files = FindCFiles(os.path.join('src', 'crypto', 'test'), 625 NotGTestMain) 626 test_support_h_files = ( 627 FindHeaderFiles(os.path.join('src', 'crypto', 'test'), AllFiles) + 628 FindHeaderFiles(os.path.join('src', 'ssl', 'test'), AllFiles)) 629 630 test_c_files = [] 631 crypto_test_files = ['src/crypto/test/gtest_main.cc'] 632 # TODO(davidben): Remove this loop once all tests are converted. 633 for path in FindCFiles(os.path.join('src', 'crypto'), OnlyTests): 634 if IsGTest(path): 635 crypto_test_files.append(path) 636 else: 637 test_c_files.append(path) 638 639 ssl_test_files = FindCFiles(os.path.join('src', 'ssl'), OnlyTests) 640 ssl_test_files.append('src/crypto/test/gtest_main.cc') 641 642 fuzz_c_files = FindCFiles(os.path.join('src', 'fuzz'), NoTests) 643 644 ssl_h_files = ( 645 FindHeaderFiles( 646 os.path.join('src', 'include', 'openssl'), 647 SSLHeaderFiles)) 648 649 def NotSSLHeaderFiles(filename, is_dir): 650 return not SSLHeaderFiles(filename, is_dir) 651 crypto_h_files = ( 652 FindHeaderFiles( 653 os.path.join('src', 'include', 'openssl'), 654 NotSSLHeaderFiles)) 655 656 ssl_internal_h_files = FindHeaderFiles(os.path.join('src', 'ssl'), NoTests) 657 crypto_internal_h_files = FindHeaderFiles( 658 os.path.join('src', 'crypto'), NoTests) 659 660 with open('src/util/all_tests.json', 'r') as f: 661 tests = json.load(f) 662 # For now, GTest-based tests are specified manually. 663 tests = [test for test in tests if test[0] not in ['crypto/crypto_test', 664 'decrepit/decrepit_test', 665 'ssl/ssl_test']] 666 test_binaries = set([test[0] for test in tests]) 667 test_sources = set([ 668 test.replace('.cc', '').replace('.c', '').replace( 669 'src/', 670 '') 671 for test in test_c_files]) 672 if test_binaries != test_sources: 673 print 'Test sources and configured tests do not match' 674 a = test_binaries.difference(test_sources) 675 if len(a) > 0: 676 print 'These tests are configured without sources: ' + str(a) 677 b = test_sources.difference(test_binaries) 678 if len(b) > 0: 679 print 'These test sources are not configured: ' + str(b) 680 681 files = { 682 'crypto': crypto_c_files, 683 'crypto_headers': crypto_h_files, 684 'crypto_internal_headers': crypto_internal_h_files, 685 'crypto_test': sorted(crypto_test_files), 686 'fuzz': fuzz_c_files, 687 'ssl': ssl_source_files, 688 'ssl_c': [s for s in ssl_source_files if s.endswith('.c')], 689 'ssl_cc': [s for s in ssl_source_files if s.endswith('.cc')], 690 'ssl_headers': ssl_h_files, 691 'ssl_internal_headers': ssl_internal_h_files, 692 'ssl_test': sorted(ssl_test_files), 693 'tool': tool_c_files, 694 'tool_headers': tool_h_files, 695 'test': test_c_files, 696 'test_support': test_support_c_files, 697 'test_support_headers': test_support_h_files, 698 'tests': tests, 699 } 700 701 asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).iteritems()) 702 703 for platform in platforms: 704 platform.WriteFiles(files, asm_outputs) 705 706 return 0 707 708 709if __name__ == '__main__': 710 parser = optparse.OptionParser(usage='Usage: %prog [--prefix=<path>]' 711 ' [android|bazel|gn|gyp]') 712 parser.add_option('--prefix', dest='prefix', 713 help='For Bazel, prepend argument to all source files') 714 options, args = parser.parse_args(sys.argv[1:]) 715 PREFIX = options.prefix 716 717 if not args: 718 parser.print_help() 719 sys.exit(1) 720 721 platforms = [] 722 for s in args: 723 if s == 'android': 724 platforms.append(Android()) 725 elif s == 'bazel': 726 platforms.append(Bazel()) 727 elif s == 'gn': 728 platforms.append(GN()) 729 elif s == 'gyp': 730 platforms.append(GYP()) 731 else: 732 parser.print_help() 733 sys.exit(1) 734 735 sys.exit(main(platforms)) 736