cmake_minimum_required(VERSION 3.22)
project(SAKOptimization LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
get_filename_component(SAK_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
foreach(product tube bus)
  foreach(variant reference candidate)
    foreach(instrument plain profile)
      set(target ${product}_${variant}_${instrument})
      set(root ${CMAKE_CURRENT_BINARY_DIR}/generated/${variant})
      add_library(${target} SHARED bridge.cpp)
      target_include_directories(${target} PRIVATE ${root}/${product} ${root}/shared ${CMAKE_CURRENT_SOURCE_DIR})
      if(product STREQUAL "tube")
        target_sources(${target} PRIVATE ${root}/tube/DSP/Amplifier.cpp)
        target_compile_definitions(${target} PRIVATE SAK_TUBE=1)
      endif()
      if(instrument STREQUAL "profile")
        target_compile_definitions(${target} PRIVATE SAK_PROFILE=1)
      endif()
      if(MSVC)
        target_compile_options(${target} PRIVATE /O2 /fp:precise /FIProfile.h)
      else()
        target_compile_options(${target} PRIVATE -O3 -fno-fast-math -include Profile.h)
      endif()
    endforeach()
  endforeach()
endforeach()

foreach(product tube bus)
  set(target ${product}_relaxed_plain)
  set(root ${CMAKE_CURRENT_BINARY_DIR}/generated/relaxed)
  add_library(${target} SHARED EXCLUDE_FROM_ALL bridge.cpp)
  target_include_directories(${target} PRIVATE ${root}/${product} ${root}/shared ${CMAKE_CURRENT_SOURCE_DIR})
  if(product STREQUAL "tube")
    target_sources(${target} PRIVATE ${root}/tube/DSP/Amplifier.cpp)
    target_compile_definitions(${target} PRIVATE SAK_TUBE=1)
  endif()
  if(MSVC)
    target_compile_options(${target} PRIVATE /O2 /fp:precise /FIProfile.h)
  endif()
endforeach()

# Reproduce external-model accuracy misses against the frozen implementation.
foreach(pair "reference_core_checks|core_validation" "reference_tube_checks|tube_reference_validation")
  string(REPLACE "|" ";" fields "${pair}")
  list(GET fields 0 target)
  list(GET fields 1 source)
  add_executable(${target} EXCLUDE_FROM_ALL "${SAK_ROOT}/SAK-TUBE/SAK-TUBE/Tests/${source}.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/reference/tube/DSP/Amplifier.cpp")
  target_include_directories(${target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/reference/tube")
  if(MSVC)
    target_compile_options(${target} PRIVATE /O2 /fp:precise)
  endif()
endforeach()

# Experimental tolerances never affect a product build.
foreach(exponent 6 5 4)
  foreach(instrument plain profile)
    set(target bus_tol_1e${exponent}_${instrument})
    add_library(${target} SHARED bridge.cpp)
    target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated/candidate/bus
      ${CMAKE_CURRENT_BINARY_DIR}/generated/candidate/shared ${CMAKE_CURRENT_SOURCE_DIR})
    target_compile_definitions(${target} PRIVATE SAK_VCA_RELATIVE_TOLERANCE=1e-${exponent})
    if(instrument STREQUAL "profile")
      target_compile_definitions(${target} PRIVATE SAK_PROFILE=1)
    endif()
    if(MSVC)
      target_compile_options(${target} PRIVATE /O2 /fp:precise /FIProfile.h)
    else()
      target_compile_options(${target} PRIVATE -O3 -fno-fast-math -include Profile.h)
    endif()
  endforeach()
endforeach()
