-- 049ac45508e335c6f010f2d28d71016b9fa65b4e by Derek Mauro <dmauro@google.com>: Fix librt detection PiperOrigin-RevId: 280207723 -- 6382c3a9fb2643af9dc031f92ca846c4a78e249c by Andy Getzendanner <durandal@google.com>: Fix Conan builds Import of https://github.com/abseil/abseil-cpp/pull/400 PiperOrigin-RevId: 280025424 -- aebcd52b1686ac82663a8d0193b60d0122a43372 by Samuel Benzaquen <sbenza@google.com>: Enable the assertion in the iterator's operator== and operator!= PiperOrigin-RevId: 279998951 -- 5b61d909e2159ac6fd45e0e456818db1e725ecd1 by Derek Mauro <dmauro@google.com>: Add best effort support for compiling much of Abseil with MinGW. This involves disabling ABSL_ATTRIBUTE_WEAK and adding link flags. A change to CCTZ is still necessary. Tests were not run yet, but most of them now build. PiperOrigin-RevId: 279966541 -- 4336f8b10cff906e2defdd7d1d449cde4907da5d by Abseil Team <absl-team@google.com>: Add comments and relax memory orders in base_internal::CallOnceImpl. Add a comment to document the memory order guarantee if base_internal::SpinLockWait() is called and returns kOnceDone. Add a comment for the load/store sequence in base_internal::CallOnceImpl based on Mike Burrows' explanation. The atomic load of 'control' in the #ifndef NDEBUG block does not need std::memory_order_acquire. It can use std::memory_order_relaxed. The atomic compare_exchange_strong of 'control' does not need std::memory_order_acquire in the success case. It can use std::memory_order_relaxed. PiperOrigin-RevId: 279814155 -- 407de3a5e9af957cded54a136ca0468bde620d4d by Abseil Team <absl-team@google.com>: Added a script to generate abseil.podspec from all BUILD.bazel files automatically. PiperOrigin-RevId: 279811441 -- 26139497d4a363d6c7bc989c554da593e8819a07 by Derek Mauro <dmauro@google.com>: Add missing copyright and Apache License to //absl/functional/BUILD.bazel PiperOrigin-RevId: 279795227 -- 98ed625b02af6e5834edf52a920d8ca2dab4cd90 by Matt Kulukundis <kfm@google.com>: Switch the implementation of hashtablez to *only* work on platforms that have a PER_THREAD_TLS. The old case is very slow (global mutex) and nobody collects data from that configuration anyway. PiperOrigin-RevId: 279775149 -- 07225900ef672c005c38f467ad3f92f38d0922b3 by Derek Mauro <dmauro@google.com>: Remove the minumum glibc version check PiperOrigin-RevId: 279750412 -- ec09956a951b4f52228ecc81968b8db7ae19ed15 by Derek Mauro <dmauro@google.com>: CMake only: link with -lrt to support older glibc versions PiperOrigin-RevId: 279741661 -- 97b113fb2e8246f6152c36330ba13793b37154b6 by Xiaoyi Zhang <zhangxy@google.com>: Internal change. PiperOrigin-RevId: 279390188 -- ca8f72f2721546cc9b01bd01b2ea144962e6e0c5 by Andy Getzendanner <durandal@google.com>: Expose PutTwoDigits for internal use within Abseil. PiperOrigin-RevId: 279374239 -- 14c6384cc03bbdfdefd2e4b635f104af5dd7e026 by Derek Mauro <dmauro@google.com>: Remove log_severity sources from the base target. They are already compiled as part of a separate library. PiperOrigin-RevId: 279372619 -- 3c5d926c718f8bf394e3bee87b6ba8d94601e0d3 by Abseil Team <absl-team@google.com>: s/indepdent/independent/g in SimpleAtof's documentation. PiperOrigin-RevId: 279350836 -- de2c44be8a8edf9efa1fe2007cba3564f3e5b0b8 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 279346990 -- 2ba078341423fcf6d0ba5ca1831f86570a26e615 by Samuel Benzaquen <sbenza@google.com>: Add hash support for std::wstring, std::u16string and std::u32string. PiperOrigin-RevId: 279320672 -- 3272d3ffcfa55283a04f90e5868701912da95ef7 by Andy Soffer <asoffer@google.com>: Removing a bunch of __restricts that amount to no performance differences. One of these is the cause of https://github.com/abseil/abseil-cpp/issues/396. In particular, in one of the Vector128Store functions, restricts on two pointers that were indeed aliased seems to be the root cause of the issues. Closes #396 PiperOrigin-RevId: 279318999 -- 342f338ab31cc24344d5de8f28cf455bbb629a17 by Jorg Brown <jorg@google.com>: Support uint128 in SimpleAtoi PiperOrigin-RevId: 279234038 -- 81cb0a04cf2dc4515d303679fc60968712191571 by Derek Mauro <dmauro@google.com>: Change the check for futex availability to support older Linux systems PiperOrigin-RevId: 279147079 -- cb4ca4aa4c8d2d710a5d483c56c4ce4f979e14b1 by Abseil Team <absl-team@google.com>: Add IWYU pragma: export for int128 .inc files. PiperOrigin-RevId: 279107098 -- b8df86ef610c366729f07326c726f3e34817b4dd by Abseil Team <absl-team@google.com>: An optimization for Waiter::Post() in the SEM waiter mode. Like the FUTEX waiter mode, Waiter::Post() only needs to call Poke() if it incremented the atomic variable from 0. PiperOrigin-RevId: 279086133 GitOrigin-RevId: 049ac45508e335c6f010f2d28d71016b9fa65b4e Change-Id: I4c1a4073fff62cb6a1fcb1c104aa7d62dad588c2
		
			
				
	
	
		
			247 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/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'
 | 
						|
"""
 | 
						|
 | 
						|
# Limited platforms that abseil supports.
 | 
						|
# This is mainly because of sigaltstack unavailable on watchOS.
 | 
						|
LIMITED_SUPPORT_PLATFORMS = [
 | 
						|
    "ios.deployment_target = '7.0'",
 | 
						|
    "osx.deployment_target = '10.9'",
 | 
						|
]
 | 
						|
 | 
						|
# Custom specification per rule.
 | 
						|
CUSTOM_SPEC_MAP = {
 | 
						|
    "//absl/debugging:failure_signal_handler": LIMITED_SUPPORT_PLATFORMS,
 | 
						|
}
 | 
						|
 | 
						|
# 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))
 | 
						|
  # Writes custom specification.
 | 
						|
  custom_spec = CUSTOM_SPEC_MAP.get(rule.package + ":" + rule.name)
 | 
						|
  if custom_spec:
 | 
						|
    for spec in custom_spec:
 | 
						|
      f.write("{indent}{var}.{spec}\n".format(
 | 
						|
          indent=indent, var=spec_var, spec=spec))
 | 
						|
 | 
						|
 | 
						|
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()
 |