import intf_libs += liboneapi-compilers-common%libs{compilers-common}

# inter-dependencies

libs{ifort}: $intf_libs
{
  cc.export.libs += $intf_libs
}

define [see_through] import: group

define f90: file
f90{*}: extension = f90

define mod: file
mod{*}: extension = mod

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

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)"

for plat: [json_object] ($manifest_json["$project"])
{
  plat_key   = $member_name($plat)
  plat_val   = $member_value($plat)
  enabled    = [bool] ($cc.target.cpu-$cc.target.class == $plat_key)
  devel_id   = [string] ($plat_val["devel_id"])

  json{$devel_id...}:   json{$name-manifest}: include = (!$empty($devel_id))
  archive{$name-intel.oneapi.$(name).devel-$package_ver...}: json{$devel_id...}: include = (!$empty($devel_id) && $enabled)
}

extract{$name-devel}: archive{$name-intel.oneapi.$(name).devel-$package_ver...}

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

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

  files = [paths]
  for g : $filter($<, group)
  {
    if test -d $o/$name($g)/share/doc/compiler/licensing
    {
      find "$o/$name($g)/share/doc/compiler/licensing" -type f -name "*" \
        | set -n f [paths]
      files += $f
    }
  }

  depdb dyndep \
    --dyn-target \
    --target-cwd "$o" \
    --target-what 'imported legals' \
    --target-default-type 'legal' \
    --target-extension-type '=legal' \
    --format lines \
    --file $d \
    -- \
      echo $regex.merge($files, '(.+)', '\1\n') >$d

  diag import $>

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

import{$name-cfgs}: extract{$name-devel}: update = match

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

  depdb dyndep \
    --dyn-target \
    --target-cwd "$o" \
    --target-what 'imported configs' \
    --target-default-type 'cfg' \
    --target-extension-type 'cfg=cfg' \
    --format lines \
    --file $d \
    -- \
      echo $name-devel/bin/ifx.cfg >$d

  diag import $>

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

import{$name-includes}: extract{$name-devel}: update = match

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

  files = [paths]
  for g : $filter($<, group)
  {
    if test -d $o/$name($g)/opt/compiler/include
    {
      find "$o/$name($g)/opt/compiler/include" -type f \
        | sed -n -e 's/^(.+\.(h|f90|mod))$/\1/p' \
        | set -n f [paths]
      files += $f
    }
  }

  depdb dyndep \
    --dyn-target \
    --target-cwd "$o" \
    --target-what 'imported includes' \
    --target-extension-type 'h=h' \
    --target-extension-type 'f90=f90' \
    --target-extension-type 'mod=mod' \
    --format lines \
    --file $d \
    -- \
      echo $regex.merge($files, '(.+)', '\1\n') >$d

  diag import $>

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

pub_hdrs = [strings] \
  "-I$out_base/$name-devel/opt/compiler/include" \
  "-I$out_base/$name-devel/opt/compiler/include/intel64"

./: 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 = $member_value($m)

    ./: libs{$n}:
    {
      include = $enabled
      clean = false
    }

    # The "bundles" are either paired DLL + import lib (Windows),
    # or shared-only (implicitly loaded, just needs to respect RPATH).
    # Also explicitly append the extract-targets as inner-most prerequisites
    # to make sure they are always unpacked first.
    #
    [rule_hint=cxx.link] \
    libs{$n}: import{$name-legals} import{$name-includes}: \
                extract{$name-devel}:
    {
      include = $enabled
      update  = match
    }

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

    # Windows: paired DLL + import lib bundles.
    #
    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-devel}: include = $enabled
      libs{$n}: libs{$dll}: include = $enabled
      if $enabled
      {
        libs{$n}:
        {
          cc.export.libs =+ libs{$dll}
        }
      }
    }

    # Shared libs / runtime DLLs (no import lib).
    #
    loptions = [strings]
    for x: [json_array] ($v["loptions"])
      loptions += $x

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

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

    # Export options.
    #
    libs{$n}:
    {
      cc.type              = cc
      cc.export.poptions   = $pub_hdrs
      cc.pkgconfig.include = include/ifort/ include/ifort/intel64/
    }

    # For pre-releases use the complete version to make sure they cannot
    # be used in place of another pre-release or the final version. See
    # the version module for details on the version.* variable values.
    #
    if $version.pre_release
      lib{$name}: bin.lib.version = "-$version.project_id"
    else
      lib{$name}: bin.lib.version = "-$version.major.$version.minor"
  }

  # Compiler executables declared in package.json.
  #
  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-cfgs}: extract{$name-devel}: include = $enabled

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

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

# No registered rule matches a pre-built exe that has no source prerequisites
# and does not yet exist on disk. This ad-hoc regex pattern rule provides an
# explicit perform(update)/perform(clean) entry point for all path-qualified
# exe targets so build2 can attach the operation to them.
#
exe{~'/(.+)/'}: $name-devel/fsdir{bin} extract{$name-devel}
{{
  diag import $> $<
  touch $path($>)
}}

# ifx.cfg is read at startup from the same directory as ifx.
cfg{*}: install = bin/

# Recreate the upstream include/ hierarchy under, e.g., /usr/include/.
# Path qualification is required here to anchor the install at
# opt/compiler/include/ rather than the full out-relative path.
#
$name-devel/opt/compiler/include/{h}{*}:
{
  install         = include/ifort/
  install.subdirs = true
}

$name-devel/opt/compiler/include/f90{*}:
{
  install         = include/ifort/
  install.subdirs = true
}

$name-devel/opt/compiler/include/intel64/mod{*}:
{
  install         = include/ifort/intel64/
  install.subdirs = true
}
