import intf_libs = cuda-cudart%libs{cudart}

define [see_through] import: group

name = $string.replace($project, 'lib', '')

source redist.build

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)
  enabled  = [bool] ($cc.target.cpu-$cc.target.class == $plat_key)
  archive{$name-$plat_key-$package_ver}: $src_base/manifest.json: include = $enabled
  extract{$name}: archive{$name-$plat_key-$package_ver}: include = $enabled
}

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

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 'hxx' \
    --target-extension-type '=hxx' \
    --target-extension-type 'h=hxx' \
    --target-extension-type 'hpp=hxx' \
    --format lines \
    -- echo $regex.merge($f, '(.+)', '\1\n')

  diag import $>

  for f : $filter($>, hxx)
  {
    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=cxx.link] \
    libs{$n}: 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}
      }
    }

    # Opaque runtime resource files (e.g. TensorRT's builder-resource data
    # blobs) -- installed verbatim alongside the shared lib, never linked.
    for r: [json_array] ($v["resources"])
    {
      res = [path] $out_base/$r
      <file{$res}>: extract{$name}: include = $enabled
      if $enabled
      {
        file{$res}: install = $directory([dir_path] $r)/
      }
      libs{$n}: file{$res}: include = $enabled
    }

    libs{$n}: $intf_libs: include = $enabled
    if $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 ships these pre-built with no RPATH/RUNPATH at all, relying on
  # the caller to set LD_LIBRARY_PATH, confirmed by running the pristine,
  # unmodified archive contents directly. Set a relocatable rpath, using
  # $ORIGIN rather than an absolute path, so the exe stays relocatable and
  # finds its sibling shared libs without any env setup, whether run from
  # the build tree or an install tree (bin/ and lib/ are always siblings in
  # both).
  if ($cc.target.class == 'linux')
  {
    echo patchelf $relative($path($>), $src_root)
    patchelf --set-rpath '$ORIGIN/../lib' $path($>)
  }
}}

lib/liba{**}: install = false

exe{*}: install = bin/

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