Add 'third_party/abseil_cpp/' from commit '768eb2ca28'
git-subtree-dir: third_party/abseil_cpp git-subtree-mainline:ffb2ae54begit-subtree-split:768eb2ca28
This commit is contained in:
commit
fc8dc48020
1276 changed files with 208196 additions and 0 deletions
229
third_party/abseil_cpp/absl/abseil.podspec.gen.py
vendored
Executable file
229
third_party/abseil_cpp/absl/abseil.podspec.gen.py
vendored
Executable file
|
|
@ -0,0 +1,229 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""This script generates abseil.podspec from all BUILD.bazel files.
|
||||
|
||||
This is expected to run on abseil git repository with Bazel 1.0 on Linux.
|
||||
It recursively analyzes BUILD.bazel files using query command of Bazel to
|
||||
dump its build rules in XML format. From these rules, it constructs podspec
|
||||
structure.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import xml.etree.ElementTree
|
||||
|
||||
# Template of root podspec.
|
||||
SPEC_TEMPLATE = """
|
||||
# This file has been automatically generated from a script.
|
||||
# Please make modifications to `abseil.podspec.gen.py` instead.
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'abseil'
|
||||
s.version = '${version}'
|
||||
s.summary = 'Abseil Common Libraries (C++) from Google'
|
||||
s.homepage = 'https://abseil.io'
|
||||
s.license = 'Apache License, Version 2.0'
|
||||
s.authors = { 'Abseil Team' => 'abseil-io@googlegroups.com' }
|
||||
s.source = {
|
||||
:git => 'https://github.com/abseil/abseil-cpp.git',
|
||||
:tag => '${tag}',
|
||||
}
|
||||
s.module_name = 'absl'
|
||||
s.header_mappings_dir = 'absl'
|
||||
s.header_dir = 'absl'
|
||||
s.libraries = 'c++'
|
||||
s.compiler_flags = '-Wno-everything'
|
||||
s.pod_target_xcconfig = {
|
||||
'USER_HEADER_SEARCH_PATHS' => '$(inherited) "$(PODS_TARGET_SRCROOT)"',
|
||||
'USE_HEADERMAP' => 'NO',
|
||||
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
|
||||
}
|
||||
s.ios.deployment_target = '7.0'
|
||||
s.osx.deployment_target = '10.9'
|
||||
s.tvos.deployment_target = '9.0'
|
||||
s.watchos.deployment_target = '2.0'
|
||||
"""
|
||||
|
||||
# Rule object representing the rule of Bazel BUILD.
|
||||
Rule = collections.namedtuple(
|
||||
"Rule", "type name package srcs hdrs textual_hdrs deps visibility testonly")
|
||||
|
||||
|
||||
def get_elem_value(elem, name):
|
||||
"""Returns the value of XML element with the given name."""
|
||||
for child in elem:
|
||||
if child.attrib.get("name") != name:
|
||||
continue
|
||||
if child.tag == "string":
|
||||
return child.attrib.get("value")
|
||||
if child.tag == "boolean":
|
||||
return child.attrib.get("value") == "true"
|
||||
if child.tag == "list":
|
||||
return [nested_child.attrib.get("value") for nested_child in child]
|
||||
raise "Cannot recognize tag: " + child.tag
|
||||
return None
|
||||
|
||||
|
||||
def normalize_paths(paths):
|
||||
"""Returns the list of normalized path."""
|
||||
# e.g. ["//absl/strings:dir/header.h"] -> ["absl/strings/dir/header.h"]
|
||||
return [path.lstrip("/").replace(":", "/") for path in paths]
|
||||
|
||||
|
||||
def parse_rule(elem, package):
|
||||
"""Returns a rule from bazel XML rule."""
|
||||
return Rule(
|
||||
type=elem.attrib["class"],
|
||||
name=get_elem_value(elem, "name"),
|
||||
package=package,
|
||||
srcs=normalize_paths(get_elem_value(elem, "srcs") or []),
|
||||
hdrs=normalize_paths(get_elem_value(elem, "hdrs") or []),
|
||||
textual_hdrs=normalize_paths(get_elem_value(elem, "textual_hdrs") or []),
|
||||
deps=get_elem_value(elem, "deps") or [],
|
||||
visibility=get_elem_value(elem, "visibility") or [],
|
||||
testonly=get_elem_value(elem, "testonly") or False)
|
||||
|
||||
|
||||
def read_build(package):
|
||||
"""Runs bazel query on given package file and returns all cc rules."""
|
||||
result = subprocess.check_output(
|
||||
["bazel", "query", package + ":all", "--output", "xml"])
|
||||
root = xml.etree.ElementTree.fromstring(result)
|
||||
return [
|
||||
parse_rule(elem, package)
|
||||
for elem in root
|
||||
if elem.tag == "rule" and elem.attrib["class"].startswith("cc_")
|
||||
]
|
||||
|
||||
|
||||
def collect_rules(root_path):
|
||||
"""Collects and returns all rules from root path recursively."""
|
||||
rules = []
|
||||
for cur, _, _ in os.walk(root_path):
|
||||
build_path = os.path.join(cur, "BUILD.bazel")
|
||||
if os.path.exists(build_path):
|
||||
rules.extend(read_build("//" + cur))
|
||||
return rules
|
||||
|
||||
|
||||
def relevant_rule(rule):
|
||||
"""Returns true if a given rule is relevant when generating a podspec."""
|
||||
return (
|
||||
# cc_library only (ignore cc_test, cc_binary)
|
||||
rule.type == "cc_library" and
|
||||
# ignore empty rule
|
||||
(rule.hdrs + rule.textual_hdrs + rule.srcs) and
|
||||
# ignore test-only rule
|
||||
not rule.testonly)
|
||||
|
||||
|
||||
def get_spec_var(depth):
|
||||
"""Returns the name of variable for spec with given depth."""
|
||||
return "s" if depth == 0 else "s{}".format(depth)
|
||||
|
||||
|
||||
def get_spec_name(label):
|
||||
"""Converts the label of bazel rule to the name of podspec."""
|
||||
assert label.startswith("//absl/"), "{} doesn't start with //absl/".format(
|
||||
label)
|
||||
# e.g. //absl/apple/banana -> abseil/apple/banana
|
||||
return "abseil/" + label[7:]
|
||||
|
||||
|
||||
def write_podspec(f, rules, args):
|
||||
"""Writes a podspec from given rules and args."""
|
||||
rule_dir = build_rule_directory(rules)["abseil"]
|
||||
# Write root part with given arguments
|
||||
spec = re.sub(r"\$\{(\w+)\}", lambda x: args[x.group(1)],
|
||||
SPEC_TEMPLATE).lstrip()
|
||||
f.write(spec)
|
||||
# Write all target rules
|
||||
write_podspec_map(f, rule_dir, 0)
|
||||
f.write("end\n")
|
||||
|
||||
|
||||
def build_rule_directory(rules):
|
||||
"""Builds a tree-style rule directory from given rules."""
|
||||
rule_dir = {}
|
||||
for rule in rules:
|
||||
cur = rule_dir
|
||||
for frag in get_spec_name(rule.package).split("/"):
|
||||
cur = cur.setdefault(frag, {})
|
||||
cur[rule.name] = rule
|
||||
return rule_dir
|
||||
|
||||
|
||||
def write_podspec_map(f, cur_map, depth):
|
||||
"""Writes podspec from rule map recursively."""
|
||||
for key, value in sorted(cur_map.items()):
|
||||
indent = " " * (depth + 1)
|
||||
f.write("{indent}{var0}.subspec '{key}' do |{var1}|\n".format(
|
||||
indent=indent,
|
||||
key=key,
|
||||
var0=get_spec_var(depth),
|
||||
var1=get_spec_var(depth + 1)))
|
||||
if isinstance(value, dict):
|
||||
write_podspec_map(f, value, depth + 1)
|
||||
else:
|
||||
write_podspec_rule(f, value, depth + 1)
|
||||
f.write("{indent}end\n".format(indent=indent))
|
||||
|
||||
|
||||
def write_podspec_rule(f, rule, depth):
|
||||
"""Writes podspec from given rule."""
|
||||
indent = " " * (depth + 1)
|
||||
spec_var = get_spec_var(depth)
|
||||
# Puts all files in hdrs, textual_hdrs, and srcs into source_files.
|
||||
# Since CocoaPods treats header_files a bit differently from bazel,
|
||||
# this won't generate a header_files field so that all source_files
|
||||
# are considered as header files.
|
||||
srcs = sorted(set(rule.hdrs + rule.textual_hdrs + rule.srcs))
|
||||
write_indented_list(
|
||||
f, "{indent}{var}.source_files = ".format(indent=indent, var=spec_var),
|
||||
srcs)
|
||||
# Writes dependencies of this rule.
|
||||
for dep in sorted(rule.deps):
|
||||
name = get_spec_name(dep.replace(":", "/"))
|
||||
f.write("{indent}{var}.dependency '{dep}'\n".format(
|
||||
indent=indent, var=spec_var, dep=name))
|
||||
|
||||
|
||||
def write_indented_list(f, leading, values):
|
||||
"""Writes leading values in an indented style."""
|
||||
f.write(leading)
|
||||
f.write((",\n" + " " * len(leading)).join("'{}'".format(v) for v in values))
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def generate(args):
|
||||
"""Generates a podspec file from all BUILD files under absl directory."""
|
||||
rules = filter(relevant_rule, collect_rules("absl"))
|
||||
with open(args.output, "wt") as f:
|
||||
write_podspec(f, rules, vars(args))
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generates abseil.podspec from BUILD.bazel")
|
||||
parser.add_argument(
|
||||
"-v", "--version", help="The version of podspec", required=True)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--tag",
|
||||
default=None,
|
||||
help="The name of git tag (default: version)")
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
default="abseil.podspec",
|
||||
help="The name of output file (default: abseil.podspec)")
|
||||
args = parser.parse_args()
|
||||
if args.tag is None:
|
||||
args.tag = args.version
|
||||
generate(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue