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}

libul{core}: $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).
#
libul{core}: source/util/cxx{timer}: \
  include = ($cxx.target.system == 'linux' || $cxx.target.system == 'android')

libul{opt}: source/opt/{h cxx}{** -pch_source_opt} $impl_libs $intf_libs

lib{SPIRV-Tools}: $pub/{$pub_hdrs} libul{core} $impl_libs $intf_libs

# Opt/link/lint/reduce/diff and the CLI tools use non-public core symbols
# (and link/lint/reduce/diff non-public optimizer symbols). Upstream links
# those targets against SPIRV-Tools-static (see SPIRV_TOOLS_FULL_VISIBILITY)
# and builds them as STATIC (SPIRV_TOOLS_LIBRARY_TYPE) position-independent
# code. The shared core only provides the public API (SPIRV-Tools-shared).
# So the static extra libraries link the static core (and optimizer)
# library while the shared ones contain their own copy of the core (and
# optimizer) code.
#
lib{SPIRV-Tools-opt}: libul{opt} $impl_libs $intf_libs
liba{SPIRV-Tools-opt}: lib{SPIRV-Tools}
libs{SPIRV-Tools-opt}: libul{core}

# Upstream only marks the Optimizer class for export, not the Create*Pass()
# functions or Optimizer::PassToken, so export the optimizer's symbols
# automatically from the Windows DLL.
#
libs{SPIRV-Tools-opt}: def{SPIRV-Tools-opt}: \
  include = ($cxx.target.system == 'win32-msvc')
def{SPIRV-Tools-opt}: libul{opt}

lib{SPIRV-Tools-link}: source/link/{h cxx}{**} $impl_libs $intf_libs
liba{SPIRV-Tools-link}: liba{SPIRV-Tools-opt}
libs{SPIRV-Tools-link}: libul{opt core}

lib{SPIRV-Tools-lint}: source/lint/{h cxx}{**} $impl_libs $intf_libs
liba{SPIRV-Tools-lint}: liba{SPIRV-Tools-opt}
libs{SPIRV-Tools-lint}: libul{opt core}

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

lib{SPIRV-Tools-diff}: source/diff/{h cxx}{**} $impl_libs $intf_libs
liba{SPIRV-Tools-diff}: liba{SPIRV-Tools-opt}
libs{SPIRV-Tools-diff}: libul{opt core}

./: lib{SPIRV-Tools 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"

if ($cxx.target.system == 'mingw32')
  libs{SPIRV-Tools-opt}: cxx.loptions += -Wl,--export-all-symbols

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

  # GCC 14 -O3 false positive: the shrinking vector::resize(1) in
  # LCSSARewriter::GetDefiningBlocks() is analyzed as growing.
  #
  obj{source/opt/loop_utils}: cxx.coptions += -Wno-array-bounds
}

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 libraries export the public API (upstream SPIRV_TOOLS_SHAREDLIB).
#
objs{*}: 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 SPIRV-Tools-opt SPIRV-Tools-link SPIRV-Tools-lint \
    SPIRV-Tools-reduce SPIRV-Tools-diff}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc"
  cxx.export.libs = $intf_libs
}

liba{SPIRV-Tools-opt}: cxx.export.libs += liba{SPIRV-Tools}

liba{SPIRV-Tools-link SPIRV-Tools-lint SPIRV-Tools-reduce SPIRV-Tools-diff}: \
  cxx.export.libs += liba{SPIRV-Tools-opt}

libs{SPIRV-Tools SPIRV-Tools-opt SPIRV-Tools-link SPIRV-Tools-lint \
     SPIRV-Tools-reduce SPIRV-Tools-diff}: \
  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 SPIRV-Tools-opt SPIRV-Tools-link SPIRV-Tools-lint \
      SPIRV-Tools-reduce SPIRV-Tools-diff}: \
    bin.lib.version = "-$version.project_id"
else
  lib{SPIRV-Tools SPIRV-Tools-opt SPIRV-Tools-link SPIRV-Tools-lint \
      SPIRV-Tools-reduce SPIRV-Tools-diff}: \
    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
