``` # TODO: ensure the input files are valid cpp s...
# development
a
Copy code
# TODO: ensure the input files are valid cpp sources files (how?)
class CppSources(datatype('CppSources', [
    'root_dir',
    'file_paths',
]), CppFileProvider):

  def __hash__(self):
    hasher = sha1()
    hasher.update(self.root_dir)
    for p in self.file_paths:
      hasher.update(p)

    return hash(hasher.digest())

  def as_cpp_files(self):
    return CppFiles(self.root_dir, self.file_paths)


class CppSourceSnapshot(datatype('CppSourceSnapshot', [
    'relative_to',
    'snapshot',
])):

  def get_relative_file_paths(self):
    rel_paths = []

    abs_paths = [f.stat.path for f in self.snapshot.files]

    for p in abs_paths:
      relative_to_orig_root = os.path.relpath(p, start=self.relative_to)
      rel_paths.append(relative_to_orig_root)

    return rel_paths


@rule(CppSourceSnapshot, [Select(CppSources)])
def collect_cpp_sources(cpp_sources):
  snapshot = yield Get(Snapshot, PathGlobs, cpp_sources.as_path_globs())
  yield CppSourceSnapshot(relative_to=cpp_sources.root_dir, snapshot=snapshot)


# TODO: validate that these are actually compiled cpp object files (how?)
class CppObjects(datatype('CppObjects', [
    'root_dir',
    'file_paths',
])):

  def __hash__(self):
    hasher = sha1()
    hasher.update(self.root_dir)
    for p in self.file_paths:
      hasher.update(p)

    return hash(hasher.digest())

  def as_cpp_files(self):
    return CppFiles(self.root_dir, self.file_paths)


class CppObjectsRequest(datatype('CppObjectsRequest', [
    'sources',
    'dir_path',
])): pass


@rule(CppObjects, [Select(Compiler), Select(CppObjectsRequest)])
def compile_cpp_sources_to_objects(compiler, cpp_objects_request):
  src_snapshot = yield Get(CppSourceSnapshot, CppSources, cpp_objects_request.sources)
  src_rel_paths = src_snapshot.get_relative_file_paths()

  outdir = cpp_objects_request.dir_path

  expected_object_file_paths = [
    re.sub(r'\.cpp\Z', '.o', cpp_src) for cpp_src in src_rel_paths
  ]

  compiler.compile_cpp(outdir, src_snapshot.relative_to, src_rel_paths)

  yield CppObjects(outdir, expected_object_file_paths)