def _get_xcode_clang_path_and_clang_libs()

in tools/clangrttool/clangrttool.py [0:0]


  def _get_xcode_clang_path_and_clang_libs(self, objdump_output):
    """Returns the path to the clang directory inside of Xcode.

    Each version of Xcode comes with clang packaged under a versioned directory
    that is unknown in advanced. In order to copy the runtime libraries, we need
    to figure out the path inside of the Xcode.app bundle that contains clang
    runtime. The path is written into the Mach-O header by the clang linker as
    a RPATH commmand:

      Load command 24
            cmd LC_RPATH
        cmdsize 136
          path /Applications/Xcode.app/.../lib/clang/X.Y.Z/lib/darwin (offset
          12)

    This method uses a simple heuristic to find the Xcode path amongst all RPATH
    entries on the given header. While not ideal, this approach lets us support
    any version of Xcode, installed into any location on the system.

    Args:
      header: A Mach-O header object to parse.

    Returns:
      A tuple with the first element as a string representing the path to the
      clang's lib directory, or `None` if one cannot be found and the second
      element as a set of library names.
    """
    found_rpath = None
    libs = set()
    for index, line in enumerate(objdump_output):
      if line.endswith(" LC_RPATH"):
        rpath_line = objdump_output[index + 2].strip()
        rpath_segments = rpath_line.split(" ")
        if len(rpath_segments) != 4:
          raise ClangRuntimeToolError("Unexpected objdump format.")
        rpath = rpath_segments[1]
        if not rpath.startswith("@") and "lib/clang" in rpath:
          found_rpath = rpath
      elif line.endswith(" LC_LOAD_DYLIB"):
        library_line = objdump_output[index + 2].strip()
        library_segments = library_line.split(" ")
        if len(library_segments) != 4:
          raise ClangRuntimeToolError("Unexpected objdump format.")
        library = library_segments[1]
        if library.startswith("@rpath/libclang_rt"):
          libs.add(library[len("@rpath/"):])

    return rpath, libs