intf_libs = # Interface dependencies.
impl_libs = # Implementation dependencies.
import impl_libs += libspirv-headers%lib{spirv-headers}

# Public headers.
#
pub = [dir_path] ../include/

include $pub

pub_hdrs = $($pub/ pub_hdrs)

# Generated grammar tables and language headers (checked in, regenerated by
# the packager from SPIRV-Headers). build-version.inc is produced at build
# time from CHANGES.
#
define inc: hxx
inc{*}: extension = inc

# Upstream software version from CHANGES (v2026.3 at this SDK tag) plus
# the package snapshot version.
#
gen/inc{build-version}: gen/in{build-version}

# Private headers and sources. Exclude optional/fuzz/wasm/PCH/mimalloc.
# Headers stay in the graph even when the matching .cpp is platform-only
# (timer.h is included from source/opt/pass_manager.cpp on every host).
#
core_hdrs = source/{h}{** \
  -opt/** -link/** -lint/** -reduce/** -diff/** -fuzz/** -wasm/** \
  -pch_source}

core_srcs = source/{cxx}{** \
  -opt/** -link/** -lint/** -reduce/** -diff/** -fuzz/** -wasm/** \
  -pch_source -mimalloc -util/timer}

lib{SPIRV-Tools}: $pub/{$pub_hdrs} $core_hdrs $core_srcs \
  gen/{h}{DebugInfo OpenCLDebugInfo100} \
  gen/inc{core_tables_body core_tables_header generators} \
  gen/inc{build-version} \
  $impl_libs $intf_libs

# Timer support matches upstream CMake (Linux and Android).
#
lib{SPIRV-Tools}: source/util/cxx{timer}: \
  include = ($cxx.target.system == 'linux' || $cxx.target.system == 'android')

# Opt/link/lint/reduce/diff and the CLI tools use non-public core symbols.
# Upstream links those targets against SPIRV-Tools-static (see
# SPIRV_TOOLS_FULL_VISIBILITY) and builds them as STATIC
# (SPIRV_TOOLS_LIBRARY_TYPE). The shared core only exports the public API.
#
liba{SPIRV-Tools-opt}: source/opt/{h cxx}{** -pch_source_opt} \
  liba{SPIRV-Tools} $impl_libs $intf_libs

liba{SPIRV-Tools-link}: source/link/{h cxx}{**} \
  liba{SPIRV-Tools-opt} $impl_libs $intf_libs

liba{SPIRV-Tools-lint}: source/lint/{h cxx}{**} \
  liba{SPIRV-Tools-opt} $impl_libs $intf_libs

liba{SPIRV-Tools-reduce}: source/reduce/{h cxx}{** -pch_source_reduce} \
  liba{SPIRV-Tools-opt} $impl_libs $intf_libs

liba{SPIRV-Tools-diff}: source/diff/{h cxx}{**} \
  liba{SPIRV-Tools-opt} $impl_libs $intf_libs

./: lib{SPIRV-Tools} \
    liba{SPIRV-Tools-opt SPIRV-Tools-link SPIRV-Tools-lint \
         SPIRV-Tools-reduce SPIRV-Tools-diff}

# Build options.
#
# -I src/ makes #include "source/..." work (upstream includes from the
# repository root). -I src/gen finds generated .inc/.h. -I include/ is
# the public <spirv-tools/...> prefix.
#
out_pfx_inc = [dir_path] $out_root/include/
src_pfx_inc = [dir_path] $src_root/include/
out_pfx_src = [dir_path] $out_root/src/
src_pfx_src = [dir_path] $src_root/src/
out_pfx_gen = [dir_path] $out_root/src/gen/
src_pfx_gen = [dir_path] $src_root/src/gen/

cxx.poptions =+ "-I$out_pfx_src" "-I$src_pfx_src" \
                "-I$out_pfx_gen" "-I$src_pfx_gen" \
                "-I$out_pfx_inc" "-I$src_pfx_inc"

cxx.poptions += -DSPIRV_COLOR_TERMINAL

if ($cxx.target.class == 'windows')
{
  cxx.poptions += -DSPIRV_WINDOWS -D_CRT_SECURE_NO_WARNINGS
}

if ($cxx.target.system == 'linux' || $cxx.target.system == 'android')
  cxx.poptions += -DSPIRV_TIMER_ENABLED

if ($cxx.class != 'msvc')
  cxx.coptions += -fno-exceptions -fno-rtti

if ($cxx.id == 'gcc')
{
  # GCC -O2/-O3 false positive in GroupIdsAndMatchByMappedId.
  #
  obj{source/diff/diff}: cxx.coptions += -Wno-maybe-uninitialized
}

if ($cxx.class == 'gcc')
{
  # Upstream aggregate-initializes several structs (text.cpp,
  # text_handler.cpp, binary.cpp, opt/set_spec_constant_default_value_pass.cpp)
  # without listing a trailing member. Harmless, fires under -Wextra.
  #
  cxx.coptions += -Wno-missing-field-initializers
}

if ($cxx.class == 'msvc')
{
  # std::unique_ptr member of a dllexport class (libspirv.hpp). Upstream
  # CMake passes /wd4251.
  #
  cxx.coptions += /wd4251
}

# Shared core library: public API only (upstream SPIRV_TOOLS_SHAREDLIB).
#
libs{SPIRV-Tools}: cxx.poptions += -DSPIRV_TOOLS_IMPLEMENTATION -DSPIRV_TOOLS_SHAREDLIB

if ($cxx.target.system == 'linux')
  cxx.libs += -lrt

#obja{*}: cxx.poptions += -DSPIRV_TOOLS_STATIC_BUILD
#objs{*}: cxx.poptions += -DSPIRV_TOOLS_SHARED_BUILD

# Export options.
#
lib{SPIRV-Tools}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc"
  cxx.export.libs = $intf_libs
}

liba{SPIRV-Tools-opt}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc"
  cxx.export.libs = $intf_libs liba{SPIRV-Tools}
}

liba{SPIRV-Tools-link}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc"
  cxx.export.libs = $intf_libs liba{SPIRV-Tools-opt}
}

liba{SPIRV-Tools-lint}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc"
  cxx.export.libs = $intf_libs liba{SPIRV-Tools-opt}
}

liba{SPIRV-Tools-reduce}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc"
  cxx.export.libs = $intf_libs liba{SPIRV-Tools-opt}
}

liba{SPIRV-Tools-diff}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc"
  cxx.export.libs = $intf_libs liba{SPIRV-Tools-opt}
}

libs{SPIRV-Tools}: cxx.export.poptions += -DSPIRV_TOOLS_SHAREDLIB

#liba{SPIRV-Tools}: cxx.export.poptions += -DSPIRV_TOOLS_STATIC
#libs{SPIRV-Tools}: cxx.export.poptions += -DSPIRV_TOOLS_SHARED

# 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{SPIRV-Tools}: bin.lib.version = "-$version.project_id"
else
  lib{SPIRV-Tools}: bin.lib.version = "-$version.major.$version.minor"

# Don't install private headers.
#
{hxx ixx txx h}{*}: install = false
source/{hxx ixx txx h}{*}: install = false
gen/{h}{*}: install = false
