1# coding=utf8 2 3# Copyright (c) 2015, Google Inc. 4# 5# Permission to use, copy, modify, and/or distribute this software for any 6# purpose with or without fee is hereby granted, provided that the above 7# copyright notice and this permission notice appear in all copies. 8# 9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 12# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 14# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 15# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 17"""Enumerates source files for consumption by various build systems.""" 18 19import optparse 20import os 21import subprocess 22import sys 23import json 24 25 26PREFIX = None 27EMBED_TEST_DATA = False 28 29 30def PathOf(x): 31 return x if not PREFIX else os.path.join(PREFIX, x) 32 33 34LICENSE_TEMPLATE = """Copyright (c) 2015, Google Inc. 35 36Permission to use, copy, modify, and/or distribute this software for any 37purpose with or without fee is hereby granted, provided that the above 38copyright notice and this permission notice appear in all copies. 39 40THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 41WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 42MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 43SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 44WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 45OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 46CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.""".split("\n") 47 48def LicenseHeader(comment): 49 lines = [] 50 for line in LICENSE_TEMPLATE: 51 if not line: 52 lines.append(comment) 53 else: 54 lines.append("%s %s" % (comment, line)) 55 lines.append("") 56 return "\n".join(lines) 57 58 59class Android(object): 60 61 def __init__(self): 62 self.header = LicenseHeader("#") + """ 63# This file is created by generate_build_files.py. Do not edit manually. 64""" 65 66 def PrintVariableSection(self, out, name, files): 67 out.write('%s := \\\n' % name) 68 for f in sorted(files): 69 out.write(' %s\\\n' % f) 70 out.write('\n') 71 72 def WriteFiles(self, files): 73 # New Android.bp format 74 with open('sources.bp', 'w+') as blueprint: 75 blueprint.write(self.header.replace('#', '//')) 76 77 # Separate out BCM files to allow different compilation rules (specific to Android FIPS) 78 bcm_c_files = files['bcm_crypto'] 79 non_bcm_c_files = [file for file in files['crypto'] if file not in bcm_c_files] 80 non_bcm_asm = self.FilterBcmAsm(files['crypto_asm'], False) 81 bcm_asm = self.FilterBcmAsm(files['crypto_asm'], True) 82 83 self.PrintDefaults(blueprint, 'libcrypto_sources', non_bcm_c_files, asm_files=non_bcm_asm) 84 self.PrintDefaults(blueprint, 'libcrypto_bcm_sources', bcm_c_files, asm_files=bcm_asm) 85 self.PrintDefaults(blueprint, 'libssl_sources', files['ssl']) 86 self.PrintDefaults(blueprint, 'bssl_sources', files['tool']) 87 self.PrintDefaults(blueprint, 'boringssl_test_support_sources', files['test_support']) 88 self.PrintDefaults(blueprint, 'boringssl_crypto_test_sources', files['crypto_test'], data=files['crypto_test_data']) 89 self.PrintDefaults(blueprint, 'boringssl_ssl_test_sources', files['ssl_test']) 90 self.PrintDefaults(blueprint, 'libpki_sources', files['pki']) 91 92 # Legacy Android.mk format, only used by Trusty in new branches 93 with open('sources.mk', 'w+') as makefile: 94 makefile.write(self.header) 95 makefile.write('\n') 96 self.PrintVariableSection(makefile, 'crypto_sources', files['crypto']) 97 self.PrintVariableSection(makefile, 'crypto_sources_asm', 98 files['crypto_asm']) 99 100 def PrintDefaults(self, blueprint, name, files, asm_files=[], data=[]): 101 """Print a cc_defaults section from a list of C files and optionally assembly outputs""" 102 if asm_files: 103 blueprint.write('\n') 104 blueprint.write('%s_asm = [\n' % name) 105 for f in sorted(asm_files): 106 blueprint.write(' "%s",\n' % f) 107 blueprint.write(']\n') 108 109 blueprint.write('\n') 110 blueprint.write('cc_defaults {\n') 111 blueprint.write(' name: "%s",\n' % name) 112 blueprint.write(' srcs: [\n') 113 for f in sorted(files): 114 blueprint.write(' "%s",\n' % f) 115 blueprint.write(' ],\n') 116 if data: 117 blueprint.write(' data: [\n') 118 for f in sorted(data): 119 blueprint.write(' "%s",\n' % f) 120 blueprint.write(' ],\n') 121 122 if asm_files: 123 blueprint.write(' target: {\n') 124 # Only emit asm for Linux. On Windows, BoringSSL requires NASM, which is 125 # not available in AOSP. On Darwin, the assembly works fine, but it 126 # conflicts with Android's FIPS build. See b/294399371. 127 blueprint.write(' linux: {\n') 128 blueprint.write(' srcs: %s_asm,\n' % name) 129 blueprint.write(' },\n') 130 blueprint.write(' darwin: {\n') 131 blueprint.write(' cflags: ["-DOPENSSL_NO_ASM"],\n') 132 blueprint.write(' },\n') 133 blueprint.write(' windows: {\n') 134 blueprint.write(' cflags: ["-DOPENSSL_NO_ASM"],\n') 135 blueprint.write(' },\n') 136 blueprint.write(' },\n') 137 138 blueprint.write('}\n') 139 140 def FilterBcmAsm(self, asm, want_bcm): 141 """Filter a list of assembly outputs based on whether they belong in BCM 142 143 Args: 144 asm: Assembly file list to filter 145 want_bcm: If true then include BCM files, otherwise do not 146 147 Returns: 148 A copy of |asm| with files filtered according to |want_bcm| 149 """ 150 # TODO(https://crbug.com/boringssl/542): Rather than filtering by filename, 151 # use the variable listed in the CMake perlasm line, available in 152 # ExtractPerlAsmFromCMakeFile. 153 return filter(lambda p: ("/crypto/fipsmodule/" in p) == want_bcm, asm) 154 155 156class AndroidCMake(object): 157 158 def __init__(self): 159 self.header = LicenseHeader("#") + """ 160# This file is created by generate_build_files.py. Do not edit manually. 161# To specify a custom path prefix, set BORINGSSL_ROOT before including this 162# file, or use list(TRANSFORM ... PREPEND) from CMake 3.12. 163 164""" 165 166 def PrintVariableSection(self, out, name, files): 167 out.write('set(%s\n' % name) 168 for f in sorted(files): 169 # Ideally adding the prefix would be the caller's job, but 170 # list(TRANSFORM ... PREPEND) is only available starting CMake 3.12. When 171 # sources.cmake is the source of truth, we can ask Android to either write 172 # a CMake function or update to 3.12. 173 out.write(' ${BORINGSSL_ROOT}%s\n' % f) 174 out.write(')\n') 175 176 def WriteFiles(self, files): 177 # The Android emulator uses a custom CMake buildsystem. 178 # 179 # TODO(crbug.com/boringssl/542): Move our various source lists into 180 # sources.cmake and have Android consume that directly. 181 with open('android-sources.cmake', 'w+') as out: 182 out.write(self.header) 183 184 self.PrintVariableSection(out, 'crypto_sources', files['crypto']) 185 self.PrintVariableSection(out, 'crypto_sources_asm', files['crypto_asm']) 186 self.PrintVariableSection(out, 'crypto_sources_nasm', 187 files['crypto_nasm']) 188 self.PrintVariableSection(out, 'ssl_sources', files['ssl']) 189 self.PrintVariableSection(out, 'tool_sources', files['tool']) 190 self.PrintVariableSection(out, 'test_support_sources', 191 files['test_support']) 192 self.PrintVariableSection(out, 'crypto_test_sources', 193 files['crypto_test']) 194 self.PrintVariableSection(out, 'crypto_test_data', 195 files['crypto_test_data']) 196 self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test']) 197 198 199class Bazel(object): 200 """Bazel outputs files suitable for including in Bazel files.""" 201 202 def __init__(self): 203 self.firstSection = True 204 self.header = \ 205"""# This file is created by generate_build_files.py. Do not edit manually. 206 207""" 208 209 def PrintVariableSection(self, out, name, files): 210 if not self.firstSection: 211 out.write('\n') 212 self.firstSection = False 213 214 out.write('%s = [\n' % name) 215 for f in sorted(files): 216 out.write(' "%s",\n' % PathOf(f)) 217 out.write(']\n') 218 219 def WriteFiles(self, files): 220 with open('BUILD.generated.bzl', 'w+') as out: 221 out.write(self.header) 222 223 self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers']) 224 self.PrintVariableSection(out, 'fips_fragments', files['fips_fragments']) 225 self.PrintVariableSection( 226 out, 'ssl_internal_headers', files['ssl_internal_headers']) 227 self.PrintVariableSection(out, 'ssl_sources', files['ssl']) 228 self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers']) 229 self.PrintVariableSection( 230 out, 'crypto_internal_headers', files['crypto_internal_headers']) 231 self.PrintVariableSection(out, 'crypto_sources', files['crypto']) 232 self.PrintVariableSection(out, 'crypto_sources_asm', files['crypto_asm']) 233 self.PrintVariableSection(out, 'crypto_sources_nasm', files['crypto_nasm']) 234 self.PrintVariableSection(out, 'pki_headers', files['pki_headers']) 235 self.PrintVariableSection( 236 out, 'pki_internal_headers', files['pki_internal_headers']) 237 self.PrintVariableSection(out, 'pki_sources', files['pki']) 238 self.PrintVariableSection(out, 'rust_bssl_sys', files['rust_bssl_sys']) 239 self.PrintVariableSection(out, 'rust_bssl_crypto', files['rust_bssl_crypto']) 240 self.PrintVariableSection(out, 'tool_sources', files['tool']) 241 self.PrintVariableSection(out, 'tool_headers', files['tool_headers']) 242 243 with open('BUILD.generated_tests.bzl', 'w+') as out: 244 out.write(self.header) 245 246 out.write('test_support_sources = [\n') 247 for filename in sorted(files['test_support'] + 248 files['test_support_headers'] + 249 files['crypto_internal_headers'] + 250 files['pki_internal_headers'] + 251 files['ssl_internal_headers']): 252 out.write(' "%s",\n' % PathOf(filename)) 253 254 out.write(']\n') 255 256 self.PrintVariableSection(out, 'crypto_test_sources', 257 files['crypto_test']) 258 self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test']) 259 self.PrintVariableSection(out, 'pki_test_sources', 260 files['pki_test']) 261 self.PrintVariableSection(out, 'crypto_test_data', 262 files['crypto_test_data']) 263 self.PrintVariableSection(out, 'pki_test_data', 264 files['pki_test_data']) 265 self.PrintVariableSection(out, 'urandom_test_sources', 266 files['urandom_test']) 267 268 269class Eureka(object): 270 271 def __init__(self): 272 self.header = LicenseHeader("#") + """ 273# This file is created by generate_build_files.py. Do not edit manually. 274 275""" 276 277 def PrintVariableSection(self, out, name, files): 278 out.write('%s := \\\n' % name) 279 for f in sorted(files): 280 out.write(' %s\\\n' % f) 281 out.write('\n') 282 283 def WriteFiles(self, files): 284 # Legacy Android.mk format 285 with open('eureka.mk', 'w+') as makefile: 286 makefile.write(self.header) 287 288 self.PrintVariableSection(makefile, 'crypto_sources', files['crypto']) 289 self.PrintVariableSection(makefile, 'crypto_sources_asm', 290 files['crypto_asm']) 291 self.PrintVariableSection(makefile, 'crypto_sources_nasm', 292 files['crypto_nasm']) 293 self.PrintVariableSection(makefile, 'ssl_sources', files['ssl']) 294 self.PrintVariableSection(makefile, 'tool_sources', files['tool']) 295 296 297class GN(object): 298 299 def __init__(self): 300 self.firstSection = True 301 self.header = LicenseHeader("#") + """ 302# This file is created by generate_build_files.py. Do not edit manually. 303 304""" 305 306 def PrintVariableSection(self, out, name, files): 307 if not self.firstSection: 308 out.write('\n') 309 self.firstSection = False 310 311 if len(files) == 0: 312 out.write('%s = []\n' % name) 313 elif len(files) == 1: 314 out.write('%s = [ "%s" ]\n' % (name, files[0])) 315 else: 316 out.write('%s = [\n' % name) 317 for f in sorted(files): 318 out.write(' "%s",\n' % f) 319 out.write(']\n') 320 321 def WriteFiles(self, files): 322 with open('BUILD.generated.gni', 'w+') as out: 323 out.write(self.header) 324 325 self.PrintVariableSection(out, 'crypto_sources', 326 files['crypto'] + 327 files['crypto_internal_headers']) 328 self.PrintVariableSection(out, 'crypto_sources_asm', files['crypto_asm']) 329 self.PrintVariableSection(out, 'crypto_sources_nasm', 330 files['crypto_nasm']) 331 self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers']) 332 self.PrintVariableSection(out, 'rust_bssl_sys', files['rust_bssl_sys']) 333 self.PrintVariableSection(out, 'rust_bssl_crypto', 334 files['rust_bssl_crypto']) 335 self.PrintVariableSection(out, 'ssl_sources', 336 files['ssl'] + files['ssl_internal_headers']) 337 self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers']) 338 self.PrintVariableSection(out, 'pki_sources', files['pki']) 339 self.PrintVariableSection(out, 'pki_internal_headers', 340 files['pki_internal_headers']) 341 self.PrintVariableSection(out, 'pki_headers', files['pki_headers']) 342 self.PrintVariableSection(out, 'tool_sources', 343 files['tool'] + files['tool_headers']) 344 345 fuzzers = [os.path.splitext(os.path.basename(fuzzer))[0] 346 for fuzzer in files['fuzz']] 347 self.PrintVariableSection(out, 'fuzzers', fuzzers) 348 349 with open('BUILD.generated_tests.gni', 'w+') as out: 350 self.firstSection = True 351 out.write(self.header) 352 353 self.PrintVariableSection(out, 'test_support_sources', 354 files['test_support'] + 355 files['test_support_headers']) 356 self.PrintVariableSection(out, 'crypto_test_sources', 357 files['crypto_test']) 358 self.PrintVariableSection(out, 'crypto_test_data', 359 files['crypto_test_data']) 360 self.PrintVariableSection(out, 'pki_test_data', 361 files['pki_test_data']) 362 self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test']) 363 self.PrintVariableSection(out, 'pki_test_sources', files['pki_test']) 364 365 366class GYP(object): 367 368 def __init__(self): 369 self.header = LicenseHeader("#") + """ 370# This file is created by generate_build_files.py. Do not edit manually. 371 372""" 373 374 def PrintVariableSection(self, out, name, files): 375 out.write(' \'%s\': [\n' % name) 376 for f in sorted(files): 377 out.write(' \'%s\',\n' % f) 378 out.write(' ],\n') 379 380 def WriteFiles(self, files): 381 with open('boringssl.gypi', 'w+') as gypi: 382 gypi.write(self.header + '{\n \'variables\': {\n') 383 384 self.PrintVariableSection(gypi, 'boringssl_ssl_sources', 385 files['ssl'] + files['ssl_headers'] + 386 files['ssl_internal_headers']) 387 self.PrintVariableSection(gypi, 'boringssl_crypto_sources', 388 files['crypto'] + files['crypto_headers'] + 389 files['crypto_internal_headers']) 390 self.PrintVariableSection(gypi, 'boringssl_crypto_asm_sources', 391 files['crypto_asm']) 392 self.PrintVariableSection(gypi, 'boringssl_crypto_nasm_sources', 393 files['crypto_nasm']) 394 395 gypi.write(' }\n}\n') 396 397class CMake(object): 398 399 def __init__(self): 400 self.header = LicenseHeader("#") + R''' 401# This file is created by generate_build_files.py. Do not edit manually. 402 403cmake_minimum_required(VERSION 3.12) 404 405project(BoringSSL LANGUAGES C CXX) 406 407set(CMAKE_CXX_STANDARD 14) 408set(CMAKE_CXX_STANDARD_REQUIRED ON) 409set(CMAKE_C_STANDARD 11) 410set(CMAKE_C_STANDARD_REQUIRED ON) 411if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 412 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fno-common -fno-exceptions -fno-rtti") 413 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fno-common") 414endif() 415 416# pthread_rwlock_t requires a feature flag on glibc. 417if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 418 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=700") 419endif() 420 421if(WIN32) 422 add_definitions(-D_HAS_EXCEPTIONS=0) 423 add_definitions(-DWIN32_LEAN_AND_MEAN) 424 add_definitions(-DNOMINMAX) 425 # Allow use of fopen. 426 add_definitions(-D_CRT_SECURE_NO_WARNINGS) 427endif() 428 429add_definitions(-DBORINGSSL_IMPLEMENTATION) 430 431if(OPENSSL_NO_ASM) 432 add_definitions(-DOPENSSL_NO_ASM) 433else() 434 # On x86 and x86_64 Windows, we use the NASM output. 435 if(WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64|amd64|x86|i[3-6]86") 436 enable_language(ASM_NASM) 437 set(OPENSSL_NASM TRUE) 438 set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8") 439 else() 440 enable_language(ASM) 441 set(OPENSSL_ASM TRUE) 442 # Work around https://gitlab.kitware.com/cmake/cmake/-/issues/20771 in older 443 # CMake versions. 444 if(APPLE AND CMAKE_VERSION VERSION_LESS 3.19) 445 if(CMAKE_OSX_SYSROOT) 446 set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot \"${CMAKE_OSX_SYSROOT}\"") 447 endif() 448 foreach(arch ${CMAKE_OSX_ARCHITECTURES}) 449 set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch ${arch}") 450 endforeach() 451 endif() 452 if(NOT WIN32) 453 set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack") 454 endif() 455 # Clang's integerated assembler does not support debug symbols. 456 if(NOT CMAKE_ASM_COMPILER_ID MATCHES "Clang") 457 set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-g") 458 endif() 459 endif() 460endif() 461 462if(BUILD_SHARED_LIBS) 463 add_definitions(-DBORINGSSL_SHARED_LIBRARY) 464 # Enable position-independent code globally. This is needed because 465 # some library targets are OBJECT libraries. 466 set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) 467endif() 468 469''' 470 471 def PrintLibrary(self, out, name, files, libs=[]): 472 out.write('add_library(\n') 473 out.write(' %s\n\n' % name) 474 475 for f in sorted(files): 476 out.write(' %s\n' % PathOf(f)) 477 478 out.write(')\n\n') 479 if libs: 480 out.write('target_link_libraries(%s %s)\n\n' % (name, ' '.join(libs))) 481 482 def PrintExe(self, out, name, files, libs): 483 out.write('add_executable(\n') 484 out.write(' %s\n\n' % name) 485 486 for f in sorted(files): 487 out.write(' %s\n' % PathOf(f)) 488 489 out.write(')\n\n') 490 out.write('target_link_libraries(%s %s)\n\n' % (name, ' '.join(libs))) 491 492 def PrintVariable(self, out, name, files): 493 out.write('set(\n') 494 out.write(' %s\n\n' % name) 495 for f in sorted(files): 496 out.write(' %s\n' % PathOf(f)) 497 out.write(')\n\n') 498 499 def WriteFiles(self, files): 500 with open('CMakeLists.txt', 'w+') as cmake: 501 cmake.write(self.header) 502 503 self.PrintVariable(cmake, 'CRYPTO_SOURCES_ASM', files['crypto_asm']) 504 self.PrintVariable(cmake, 'CRYPTO_SOURCES_NASM', files['crypto_nasm']) 505 506 cmake.write( 507R'''if(OPENSSL_ASM) 508 list(APPEND CRYPTO_SOURCES_ASM_USED ${CRYPTO_SOURCES_ASM}) 509endif() 510if(OPENSSL_NASM) 511 list(APPEND CRYPTO_SOURCES_ASM_USED ${CRYPTO_SOURCES_NASM}) 512endif() 513 514''') 515 516 self.PrintLibrary(cmake, 'crypto', 517 files['crypto'] + ['${CRYPTO_SOURCES_ASM_USED}']) 518 cmake.write('target_include_directories(crypto PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/include>)\n\n') 519 self.PrintLibrary(cmake, 'ssl', files['ssl'], ['crypto']) 520 self.PrintExe(cmake, 'bssl', files['tool'], ['ssl', 'crypto']) 521 522 cmake.write( 523R'''if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android") 524 find_package(Threads REQUIRED) 525 target_link_libraries(crypto Threads::Threads) 526endif() 527 528if(WIN32) 529 target_link_libraries(crypto ws2_32) 530endif() 531 532''') 533 534class JSON(object): 535 def WriteFiles(self, files): 536 with open('sources.json', 'w+') as f: 537 json.dump(files, f, sort_keys=True, indent=2) 538 539def NoTestsNorFIPSFragments(path, dent, is_dir): 540 return (NoTests(path, dent, is_dir) and 541 (is_dir or not OnlyFIPSFragments(path, dent, is_dir))) 542 543def NoTests(path, dent, is_dir): 544 """Filter function that can be passed to FindCFiles in order to remove test 545 sources.""" 546 if is_dir: 547 return dent != 'test' 548 return 'test.' not in dent 549 550 551def AllFiles(path, dent, is_dir): 552 """Filter function that can be passed to FindCFiles in order to include all 553 sources.""" 554 return True 555 556 557def NoTestRunnerFiles(path, dent, is_dir): 558 """Filter function that can be passed to FindCFiles or FindHeaderFiles in 559 order to exclude test runner files.""" 560 # NOTE(martinkr): This prevents .h/.cc files in src/ssl/test/runner, which 561 # are in their own subpackage, from being included in boringssl/BUILD files. 562 return not is_dir or dent != 'runner' 563 564 565def FindCFiles(directory, filter_func): 566 """Recurses through directory and returns a list of paths to all the C source 567 files that pass filter_func.""" 568 cfiles = [] 569 570 for (path, dirnames, filenames) in os.walk(directory): 571 for filename in filenames: 572 if not filename.endswith('.c') and not filename.endswith('.cc'): 573 continue 574 if not filter_func(path, filename, False): 575 continue 576 cfiles.append(os.path.join(path, filename)) 577 578 for (i, dirname) in enumerate(dirnames): 579 if not filter_func(path, dirname, True): 580 del dirnames[i] 581 582 cfiles.sort() 583 return cfiles 584 585 586def FindRustFiles(directory): 587 """Recurses through directory and returns a list of paths to all the Rust source 588 files.""" 589 rust_files = [] 590 591 for (path, dirnames, filenames) in os.walk(directory): 592 for filename in filenames: 593 if not filename.endswith('.rs'): 594 continue 595 rust_files.append(os.path.join(path, filename)) 596 597 rust_files.sort() 598 return rust_files 599 600 601def FindHeaderFiles(directory, filter_func): 602 """Recurses through directory and returns a list of paths to all the header files that pass filter_func.""" 603 hfiles = [] 604 605 for (path, dirnames, filenames) in os.walk(directory): 606 for filename in filenames: 607 if not filename.endswith('.h'): 608 continue 609 if not filter_func(path, filename, False): 610 continue 611 hfiles.append(os.path.join(path, filename)) 612 613 for (i, dirname) in enumerate(dirnames): 614 if not filter_func(path, dirname, True): 615 del dirnames[i] 616 617 hfiles.sort() 618 return hfiles 619 620 621def PrefixWithSrc(files): 622 return ['src/' + x for x in files] 623 624 625def main(platforms): 626 with open(os.path.join('src', 'gen', 'sources.json')) as f: 627 sources = json.load(f) 628 629 bssl_sys_files = FindRustFiles(os.path.join('src', 'rust', 'bssl-sys', 'src')) 630 bssl_crypto_files = FindRustFiles(os.path.join('src', 'rust', 'bssl-crypto', 'src')) 631 632 fuzz_c_files = FindCFiles(os.path.join('src', 'fuzz'), NoTests) 633 634 # TODO(crbug.com/boringssl/542): generate_build_files.py historically reported 635 # all the assembly files as part of libcrypto. Merge them for now, but we 636 # should split them out later. 637 crypto = sorted(sources['bcm']['srcs'] + sources['crypto']['srcs']) 638 crypto_asm = sorted(sources['bcm']['asm'] + sources['crypto']['asm'] + 639 sources['test_support']['asm']) 640 crypto_nasm = sorted(sources['bcm']['nasm'] + sources['crypto']['nasm'] + 641 sources['test_support']['nasm']) 642 643 if EMBED_TEST_DATA: 644 with open('crypto_test_data.cc', 'w+') as out: 645 subprocess.check_call( 646 ['go', 'run', 'util/embed_test_data.go'] + sources['crypto_test']['data'], 647 cwd='src', 648 stdout=out) 649 650 files = { 651 'bcm_crypto': PrefixWithSrc(sources['bcm']['srcs']), 652 'crypto': PrefixWithSrc(crypto), 653 'crypto_asm': PrefixWithSrc(crypto_asm), 654 'crypto_nasm': PrefixWithSrc(crypto_nasm), 655 'crypto_headers': PrefixWithSrc(sources['crypto']['hdrs']), 656 'crypto_internal_headers': 657 PrefixWithSrc(sources['crypto']['internal_hdrs']), 658 'crypto_test': PrefixWithSrc(sources['crypto_test']['srcs']), 659 'crypto_test_data': PrefixWithSrc(sources['crypto_test']['data']), 660 'fips_fragments': PrefixWithSrc(sources['bcm']['internal_hdrs']), 661 'fuzz': fuzz_c_files, 662 'pki': PrefixWithSrc(sources['pki']['srcs']), 663 'pki_headers': PrefixWithSrc(sources['pki']['hdrs']), 664 'pki_internal_headers': PrefixWithSrc(sources['pki']['internal_hdrs']), 665 'pki_test': PrefixWithSrc(sources['pki_test']['srcs']), 666 'pki_test_data': PrefixWithSrc(sources['pki_test']['data']), 667 'rust_bssl_crypto': bssl_crypto_files, 668 'rust_bssl_sys': bssl_sys_files, 669 'ssl': PrefixWithSrc(sources['ssl']['srcs']), 670 'ssl_headers': PrefixWithSrc(sources['ssl']['hdrs']), 671 'ssl_internal_headers': PrefixWithSrc(sources['ssl']['internal_hdrs']), 672 'ssl_test': PrefixWithSrc(sources['ssl_test']['srcs']), 673 'tool': PrefixWithSrc(sources['bssl']['srcs']), 674 'tool_headers': PrefixWithSrc(sources['bssl']['internal_hdrs']), 675 'test_support': PrefixWithSrc(sources['test_support']['srcs']), 676 'test_support_headers': 677 PrefixWithSrc(sources['test_support']['internal_hdrs']), 678 'urandom_test': PrefixWithSrc(sources['urandom_test']['srcs']), 679 } 680 681 for platform in platforms: 682 platform.WriteFiles(files) 683 684 return 0 685 686ALL_PLATFORMS = { 687 'android': Android, 688 'android-cmake': AndroidCMake, 689 'bazel': Bazel, 690 'cmake': CMake, 691 'eureka': Eureka, 692 'gn': GN, 693 'gyp': GYP, 694 'json': JSON, 695} 696 697if __name__ == '__main__': 698 parser = optparse.OptionParser( 699 usage='Usage: %%prog [--prefix=<path>] [all|%s]' % 700 '|'.join(sorted(ALL_PLATFORMS.keys()))) 701 parser.add_option('--prefix', dest='prefix', 702 help='For Bazel, prepend argument to all source files') 703 parser.add_option( 704 '--embed_test_data', dest='embed_test_data', action='store_true', 705 help='Generates the legacy crypto_test_data.cc file. To use, build with' + 706 ' -DBORINGSSL_CUSTOM_GET_TEST_DATA and add this file to ' + 707 'crypto_test.') 708 options, args = parser.parse_args(sys.argv[1:]) 709 PREFIX = options.prefix 710 EMBED_TEST_DATA = options.embed_test_data 711 712 if not args: 713 parser.print_help() 714 sys.exit(1) 715 716 if 'all' in args: 717 platforms = [platform() for platform in ALL_PLATFORMS.values()] 718 else: 719 platforms = [] 720 for s in args: 721 platform = ALL_PLATFORMS.get(s) 722 if platform is None: 723 parser.print_help() 724 sys.exit(1) 725 platforms.append(platform()) 726 727 sys.exit(main(platforms)) 728