import intf_libs = \
  cuda-cccl%lib{cccl} \
  cuda-nvcc%lib{nvcc}

define [see_through] import: group

name = $string.replace($project, 'cuda-', '')

source redist.build

json{$name-manifest}: $src_root/manifest manifest.json

manifest_json = [json_object] $json.load($src_base/manifest.json)
package_ver   = "$(version.major).$(version.minor).$(version.patch)"

pub_hdrs = [strings]
for d: [json_array] ($manifest_json["includeDirs"])
{
  dir = [string] $d
  pub_hdrs += "-I$out_base/$dir"
}

for plat: [json_object] ($manifest_json["platforms"])
{
  plat_key = $member_name($plat)
  plat_val = $member_value($plat)
  enabled  = [bool] ($cc.target.cpu-$cc.target.class == $plat_key)
  platform = [string] ($plat_val["platform"])
  archive{$name-$platform-$package_ver}: json{$name-manifest} manifest.json: include = $enabled
  extract{$name}: archive{$name-$platform-$package_ver}: include = $enabled
}

import{$name-headers}: extract{$name}: update = match
import{$name-legals}:  extract{$name}: update = match

import{$name-legals}:
{{
  o = $directory($>[0])
  d = $o/$name($>[0]).files

  legal = [path] "$out_base/LICENSE"

  depdb dyndep \
    --dyn-target \
    --target-cwd "$o" \
    --target-what 'imported files' \
    --target-default-type 'legal' \
    --format lines \
    --file $d \
    -- \
      echo $legal >$d

  diag import $>

  for t : $filter_out($>, group)
  {
    touch $path($t)
  }
}}

import{$name-headers}:
{{
  o = $directory($>[0])
  d = $o/$name($>[0]).files

  find "$out_base/include/" -type f -name "*" \
    | set -n f [paths]

  depdb dyndep \
    --dyn-target \
    --target-cwd "$o" \
    --target-what 'headers' \
    --target-default-type 'h' \
    --target-extension-type '=h' \
    --format lines \
    -- echo $regex.merge($f, '(.+)', '\1\n')

  diag import $>

  for f : $filter($>, h)
  {
    touch $path($f)
  }
}}

./: json{package}
json = [json_object] $json.load($src_base/package.json)
for plat: [json_object] ($json["platforms"])
{
  plat_key = $member_name($plat)
  enabled  = [bool] ($cc.target.cpu-$cc.target.class == $plat_key)
  plat_val = [json_object] $member_value($plat)

  for m: [json_object] ($plat_val["libs"])
  {
    n = $member_name($m)
    v = [json_object] ($member_value($m))

    ./: libs{$n}:
    {
      include = $enabled
      clean   = false
    }
    [rule_hint=c.link] \
    libs{$n}: import{$name-legals} import{$name-headers}: \
              extract{$name}:
    {
      include = $enabled
      update  = match
    }

    for b: [json_array] ($v["linked"])
    {
      dll  = [path] $out_base/($b["dll"])
      libi = [paths]
      for x: [json_array] ($b["libs"])
        libi += [paths] $out_base/$x

      <libs{$dll} libi{$libi}>: extract{$name}: include = $enabled
      libs{$n}: libs{$dll}: include = $enabled
      if $enabled
      {
        libs{$n}:
        {
          cc.export.libs =+ libs{$dll}
        }
      }
    }

    for s: [json_array] ($v["shared"])
    {
      so = [path] $out_base/$s
      <libs{$so}>: extract{$name}: include = $enabled
      libs{$n}: libs{$so}: include = $enabled
      if $enabled
      {
        if ($cc.target.class != 'windows')
        {
          libs{$n}:
          {
            cc.export.libs =+ libs{$so}
          }
        }
      }
    }

    for a: [json_array] ($v["archives"])
    {
      ar = [path] $out_base/$a
      <liba{$ar}>: extract{$name}: include = $enabled
      libs{$n}: liba{$ar}: include = $enabled
      if $enabled
      {
        libs{$n}: cc.export.libs += liba{$ar}
      }
    }

    for d2: [json_array] ($v["depends"])
    {
      dep = [name] $d2
      libs{$n}: libs{$dep}: include = $enabled
      if $enabled
      {
        libs{$n}: cc.export.libs += libs{$dep}
      }
    }

    libs{$n}: $intf_libs: include = ($n == 'cudart' && $enabled)
    if ($n == 'cudart' && $enabled)
    {
      libs{$n}: cc.export.libs += $intf_libs
    }
    libs{$n}:
    {
      cc.type            = cc
      cc.export.poptions = $pub_hdrs
    }
  }

  for m: [json_object] ($plat_val["exes"])
  {
    v = [json_object] ($member_value($m))
    p = [string] ($v["path"])

    ./: exe{$(p)...}: include = $enabled
    exe{$(p)...}: import{$name-headers}: extract{$name}: include = $enabled

    exe{$(p)...}:
    {
      install.subdirs = true
    }

    for d2: [json_array] ($v["depends"])
    {
      dep = [name] $d2
      exe{$(p)...}: libs{$dep}:
      {
        include = $enabled
        clean = false
      }
    }
  }
}

exe{~'/(.+)/'}:
{{
  diag import $> $<
  touch $path($>)

  # NVIDIA's cuda-nvcc/libnvvm executables link only against system libs
  # (confirmed via ldd/readelf against the real built binaries), so no
  # patchelf/rpath fix needed here, unlike nvidia-tensorrt's trtexec.
}}

lib/liba{**}: install = false

include/h{**}:
{
  install         = include/$project/
  install.subdirs = true
}
