%YAML 1.2
--- |
  # GRPC CocoaPods podspec
  # This file has been automatically generated from a template file. Please make modifications to
  # `templates/gRPC-Core.podspec.template` instead. This file can be regenerated from the template by
  # running `tools/buildgen/generate_projects.sh`.

  # Copyright 2015, Google Inc.
  # All rights reserved.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions are
  # met:
  #
  #     * Redistributions of source code must retain the above copyright
  # notice, this list of conditions and the following disclaimer.
  #     * Redistributions in binary form must reproduce the above
  # copyright notice, this list of conditions and the following disclaimer
  # in the documentation and/or other materials provided with the
  # distribution.
  #     * Neither the name of Google Inc. nor the names of its
  # contributors may be used to endorse or promote products derived from
  # this software without specific prior written permission.
  #
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  <%!
  def grpc_private_files(libs):
    out = []
    for lib in libs:
      if lib.name in ("grpc", "gpr"):
        out += lib.get('headers', [])
        out += lib.get('src', [])
    return out;

  def grpc_public_headers(libs):
    out = []
    for lib in libs:
      if lib.name in ("grpc", "gpr"):
        out += lib.get('public_headers', [])
    return out

  def grpc_private_headers(libs):
    out = []
    for lib in libs:
      if lib.name in ("grpc", "gpr"):
        out += lib.get('headers', [])
    return out

  def ruby_multiline_list(files, indent):
    return (',\n' + indent*' ').join('\'%s\'' % f for f in files)
  %>
  Pod::Spec.new do |s|
    s.name     = 'gRPC-Core'
    version = '0.14.0'
    s.version  = version
    s.summary  = 'Core cross-platform gRPC library, written in C'
    s.homepage = 'http://www.grpc.io'
    s.license  = 'New BSD'
    s.authors  = { 'The gRPC contributors' => 'grpc-packages@google.com' }

    s.source = {
      :git => 'https://github.com/grpc/grpc.git',
      :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}",
      # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
      :submodules => true,
    }

    s.ios.deployment_target = '7.1'
    s.osx.deployment_target = '10.9'
    s.requires_arc = false

    name = 'grpc'

    # When creating a dynamic framework, name it grpc.framework instead of gRPC-Core.framework.
    # This lets users write their includes like `#include <grpc/grpc.h>` as opposed to `#include
    # <gRPC-Core/grpc.h>`.
    s.module_name = name

    # When creating a dynamic framework, copy the headers under `include/grpc/` into the root of
    # the `Headers/` directory of the framework (i.e., not under `Headers/include/grpc`).
    #
    # TODO(jcanizales): Debug why this doesn't work on macOS.
    s.header_mappings_dir = 'include/grpc'

    # The above has an undesired effect when creating a static library: It forces users to write
    # includes like `#include <gRPC-Core/grpc.h>`. `s.header_dir` adds a path prefix to that, and
    # because Cocoapods lets omit the pod name when including headers of static libraries, the
    # following lets users write `#include <grpc/grpc.h>`.
    s.header_dir = name

    # The module map created automatically by Cocoapods doesn't work for C libraries like gRPC-Core.
    s.module_map = 'include/grpc/module.modulemap'

    # To compile the library, we need the user headers search path (quoted includes) to point to the
    # root of the repo, and the system headers search path (angled includes) to point to `include/`.
    # Cocoapods effectively clones the repo under `<Podfile dir>/Pods/gRPC-Core/`, and sets a build
    # variable called `$(PODS_ROOT)` to `<Podfile dir>/Pods/`, so we use that.
    #
    # Relying on the file structure under $(PODS_ROOT) isn't officially supported in Cocoapods, as it
    # is taken as an implementation detail. We've asked for an alternative, and have been told that
    # what we're doing should keep working: https://github.com/CocoaPods/CocoaPods/issues/4386
    #
    # The `src_root` value of `$(PODS_ROOT)/gRPC-Core` assumes Cocoapods is installing this pod from
    # its remote repo. For local development of this library, enabled by using `:path` in the Podfile,
    # that assumption is wrong. In such case, the following settings need to be reset with the
    # appropriate value of `src_root`. This can be accomplished in the `pre_install` hook of the
    # Podfile; see `src/objective-c/tests/Podfile` for an example.
    src_root = '$(PODS_ROOT)/gRPC-Core'
    s.pod_target_xcconfig = {
      'GRPC_SRC_ROOT' => src_root,
      'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
      'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
      # If we don't set these two settings, `include/grpc/support/time.h` and
      # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
      # build.
      'USE_HEADERMAP' => 'NO',
      'ALWAYS_SEARCH_USER_PATHS' => 'NO',
    }

    # Like many other C libraries, gRPC-Core has its public headers under `include/<libname>/` and its
    # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't
    # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in
    # practice). Because we need our `header_mappings_dir` to be `include/grpc/` for the reason
    # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one
    # for public headers and the other for implementation. Each gets its own `header_mappings_dir`,
    # making the linter happy.
    #
    # The list of source files is generated by a template: `templates/gRPC-Core.podspec.template`. It
    # can be regenerated from the template by running `tools/buildgen/generate_projects.sh`.
    s.subspec 'Interface' do |ss|
      ss.header_mappings_dir = 'include/grpc'

      ss.source_files = ${ruby_multiline_list(grpc_public_headers(libs), 22)}
    end
    s.subspec 'Implementation' do |ss|
      ss.header_mappings_dir = '.'
      ss.libraries = 'z'
      ss.dependency "#{s.name}/Interface", version
      ss.dependency 'BoringSSL', '~> 4.0'

      # To save you from scrolling, this is the last part of the podspec.
      ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)}

      ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)}
    end
  end
