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