Return a list of compiled object files for this library. By default, this builds all the source files returned by `self.get_files()`, with the `cflags` returned by `self.get_cflags()`.
(self, build_dir)
| 484 | create_ninja_file(input_files, ninja_file, libname, cflags, asflags=asflags, customize_build_flags=self.customize_build_cmd) |
| 485 | |
| 486 | def build_objects(self, build_dir): |
| 487 | """Return a list of compiled object files for this library. |
| 488 | |
| 489 | By default, this builds all the source files returned by `self.get_files()`, |
| 490 | with the `cflags` returned by `self.get_cflags()`. |
| 491 | """ |
| 492 | batch_inputs = get_env_bool('EMCC_BATCH_BUILD', '1') |
| 493 | self.build_dir = build_dir |
| 494 | batches = {} |
| 495 | commands = [] |
| 496 | objects = set() |
| 497 | objects_lowercase = set() |
| 498 | cflags = self.get_cflags() |
| 499 | for src in self.get_files(): |
| 500 | ext = utils.suffix(src) |
| 501 | if ext in {'.s', '.S', '.c'}: |
| 502 | cmd = shared.EMCC |
| 503 | else: |
| 504 | cmd = shared.EMXX |
| 505 | cmd = [cmd, '-c'] |
| 506 | if ext == '.s': |
| 507 | # .s files are processed directly by the assembler. In this case we can't pass |
| 508 | # pre-processor flags such as `-I` and `-D` but we still want core flags such as |
| 509 | # `-sMEMORY64`. |
| 510 | cmd += get_base_cflags(self.build_dir, preprocess=False) |
| 511 | else: |
| 512 | cmd += cflags |
| 513 | cmd = self.customize_build_cmd(cmd, src) |
| 514 | |
| 515 | object_basename = utils.unsuffixed_basename(src) |
| 516 | o = os.path.join(build_dir, object_basename + '.o') |
| 517 | if o.lower() in objects_lowercase: |
| 518 | # If we have seen a file with the same name before, we need a separate |
| 519 | # command to compile this file with a custom unique output object |
| 520 | # filename, as batch compile doesn't allow such customization. |
| 521 | # |
| 522 | # This is needed to handle, for example, _exit.o and _Exit.o. |
| 523 | object_uuid = 0 |
| 524 | # Find a unique basename |
| 525 | while o.lower() in objects_lowercase: |
| 526 | object_uuid += 1 |
| 527 | o = os.path.join(build_dir, f'{object_basename}__{object_uuid}.o') |
| 528 | commands.append(cmd + [src, '-o', o]) |
| 529 | elif batch_inputs: |
| 530 | # Use relative paths to reduce the length of the command line. |
| 531 | # This allows to avoid switching to a response file as often. |
| 532 | src = os.path.relpath(src, build_dir) |
| 533 | src = utils.normalize_path(src) |
| 534 | batches.setdefault(tuple(cmd), []).append(src) |
| 535 | else: |
| 536 | commands.append(cmd + [src, '-o', o]) |
| 537 | objects.add(o) |
| 538 | objects_lowercase.add(o.lower()) |
| 539 | |
| 540 | if batch_inputs: |
| 541 | # Choose a chunk size that is large enough to avoid too many subprocesses |
| 542 | # but not too large to avoid task starvation. |
| 543 | # For now the heuristic is to split inputs by 2x number of cores. |
no test coverage detected