impl_libs =

windows = ($cxx.target.class == 'windows')
macos   = ($cxx.target.class == 'macos')

# Note: MacOS is not supported by MKL, but the system framework 'Accelerate'
#       implements LAPACK & BLAS. See '# Libraries'.
#
if! $macos
  import intf_libs = liboneapi-mkl%libs{mkl-lp64 mkl}

# Headers and source files.
#
./: lib{SimTKcommon}: SimTKcommon/hxx{**} \
                      SimTKcommon/cxx{** -tests/**} \
                      $impl_libs $intf_libs

./: lib{SimTKmath}: SimTKmath/hxx{**}                           \
                    SimTKmath/Optimizers/src/IpOpt/hxx{*.hpp}   \
                    SimTKmath/{cxx c}{** -tests/** -**/tests/**}

# Note: Exclude the Visualizer executable code (but do include the Visualizer
#       library code).
#
./: lib{SimTKsimbody}: Simbody/hxx{** -Visualizer/simbody-visualizer/**} \
                       Simbody/cxx{** -Visualizer/simbody-visualizer/** -tests/**}

# Libraries
#
sys_libs =
if! $windows
{
  if $macos
    sys_libs += -framework Accelerate # LAPACK & BLAS
  else
    sys_libs += -pthread -lrt

  sys_libs += -ldl -lm
}

lib{SimTKcommon}:  cxx.libs += $sys_libs
lib{SimTKmath}:    lib{SimTKcommon}
lib{SimTKsimbody}: lib{SimTKcommon SimTKmath}

# SimTKcommon/ source subdirectories.
#
common_dirs = BigMatrix         \
              Geometry          \
              Mechanics         \
              Polynomial        \
              Random            \
              Scalar            \
              Simulation        \
              SmallMatrix

# SimTKmath/ source subdirectories.
#
math_dirs = LinearAlgebra       \
            Integrators         \
            Optimizers          \
            Geometry

# Simbody/ source subdirectories.
#
# Note that we will only be pulling in the Visualizer library headers, not the
# application headers in the simbody-visualizer/ subdirectory.
#
simbody_dirs = Visualizer

# Build options: SimTKcommon
#
common_includes = "-I$src_base/SimTKcommon/include"
for d: $common_dirs
  common_includes += "-I$src_base/SimTKcommon/$d/include"

SimTKcommon/obj{*}:                                                             \
  cxx.poptions += $common_includes                                              \
                  -DSimTK_SimTKCOMMON_AUTHORS=\"Michael.Sherman_Peter.Eastman\" \
                  -DSimTK_SimTKCOMMON_COPYRIGHT_YEARS=\"2005-10\"               \
                  -DSimTK_SimTKCOMMON_LIBRARY_NAME=SimTKcommon                  \
                  -DSimTK_SimTKCOMMON_MAJOR_VERSION="$version.major"            \
                  -DSimTK_SimTKCOMMON_MINOR_VERSION="$version.minor"            \
                  -DSimTK_SimTKCOMMON_PATCH_VERSION="$version.patch"

SimTKcommon/objs{*}: cxx.poptions += -DSimTK_SimTKCOMMON_BUILDING_SHARED_LIBRARY        \
                                     -DSimTKcommon_EXPORTS

SimTKcommon/obja{*}: cxx.poptions += -DSimTK_SimTKCOMMON_BUILDING_STATIC_LIBRARY

# Build options
#
# See README-DEV for note about warnings in the upstream build. In a nutshell:
# don't pass -Wall otherwise you won't be able to read the build output and it
# doesn't look like upstream pays much attention to warnings anyway.

# Build options: SimTKmath
#
math_includes = "-I$src_base/SimTKmath/include"
for d: $math_dirs
  math_includes += "-I$src_base/SimTKmath/$d/include"

SimTKmath/obj{*}:                                                               \
  cc.poptions += $math_includes                                                 \
                 "-I$src_base/Integrators/src/CPodes/sundials/include"          \
                 -DSimTK_SIMMATH_AUTHORS=\"Jack.Middleton_Michael.Sherman\"     \
                 -DSimTK_SIMMATH_COPYRIGHT_YEARS=\"2005-10\"                    \
                 -DSimTK_SIMMATH_LIBRARY_NAME=SimTKmath                         \
                 -DSimTK_SIMMATH_MAJOR_VERSION="$version.major"                 \
                 -DSimTK_SIMMATH_MINOR_VERSION="$version.minor"                 \
                 -DSimTK_SIMMATH_PATCH_VERSION="$version.patch"

SimTKmath/objs{*}: cc.poptions += -DSimTK_SIMMATH_BUILDING_SHARED_LIBRARY       \
                                  -DSimTKmath_EXPORTS

SimTKmath/obja{*}: cc.poptions += -DSimTK_SIMMATH_BUILDING_STATIC_LIBRARY

# Build options: SimTKsimbody
#
simbody_includes = "-I$src_base/Simbody/include"
for d: $simbody_dirs
  simbody_includes += "-I$src_base/Simbody/$d/include"

# Note that the various path/directory macros are only used to launch the
# Visualizer executable which is not supported so just use fake values for the
# sake of simplicity (and to flush out problems early).
#
Simbody/obj{*}:                                                                 \
  cxx.poptions += $simbody_includes                                             \
                  -DSimTK_SIMBODY_AUTHORS=\"Michael.Sherman_Peter.Eastman\"     \
                  -DSimTK_SIMBODY_COPYRIGHT_YEARS=\"2005-20\"                   \
                  -DSimTK_SIMBODY_LIBRARY_NAME=SimTKsimbody                     \
                  -DSimTK_SIMBODY_MAJOR_VERSION="$version.major"                \
                  -DSimTK_SIMBODY_MINOR_VERSION="$version.minor"                \
                  -DSimTK_SIMBODY_PATCH_VERSION="$version.patch"                \
                  -DSIMBODY_PATH_FROM_LIBDIR_TO_VIZ_DIR="\"nonexistent_dir\""   \
                  -DSIMBODY_VISUALIZER_INSTALL_DIR="\"nonexistent_dir\""        \
                  -DSIMBODY_VISUALIZER_REL_INSTALL_DIR="\"nonexistent_dir\""

Simbody/objs{*}: cxx.poptions += -DSimTK_SIMBODY_BUILDING_SHARED_LIBRARY        \
                                 -DSimTKsimbody_EXPORTS

Simbody/obja{*}: cxx.poptions += -DSimTK_SIMBODY_BUILDING_STATIC_LIBRARY

# Disable warnings about illegal UTF-8 characters (treated as errors on
# Windows CI).
#
# Note that Geodesic.cpp and ContactGeometry.cpp include the errant code which
# is in GeodesicEquations.h.
#
if ($cxx.class == 'msvc')
{
  SimTKmath/Geometry/src/obj{CollisionDetectionAlgorithm        \
                             Geodesic                           \
                             ContactGeometry}: cxx.coptions += /wd4828
}
else
{
  SimTKmath/Geometry/src/obj{CollisionDetectionAlgorithm        \
                             Geodesic                           \
                             ContactGeometry}: cxx.coptions += -Wno-invalid-utf8
}

# Export options: SimTKcommon
#
lib{SimTKcommon}:
{
  cxx.export.poptions = $common_includes
  cxx.export.libs += $intf_libs $sys_libs
}

# Export options: SimTKmath
#
lib{SimTKmath}:
{
  cxx.export.poptions = $math_includes
  cxx.export.libs = lib{SimTKcommon}
}

# Export options: SimTKsimbody
#
lib{SimTKsimbody}:
{
  cxx.export.poptions = $simbody_includes
  cxx.export.libs = lib{SimTKcommon SimTKmath}
}

# Export options: All simbody libraries
#
liba{SimTKcommon SimTKmath SimTKsimbody}: \
  cxx.export.poptions += -DSimTK_USE_STATIC_LIBRARIES

# Force all object files from each static library into the final executable.
# Without this, the linker may omit translation units that contain only
# file-scope self-registering statics (e.g. registerStandardAlgorithms() in
# CollisionDetectionAlgorithm.cpp), causing silent missing functionality.
#
# Note: SimTKcommon is excluded here. It is a direct dependency of both
# SimTKmath and SimTKsimbody, so it is reachable via more than one path in
# the static link graph; forcing it whole would make the linker extract its
# object files once per path, causing 'multiple definition' errors.
liba{SimTKmath SimTKsimbody}: bin.whole = true

# 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{SimTKcommon SimTKmath SimTKsimbody}: \
    bin.lib.version = "-$version.project_id"
else
  lib{SimTKcommon SimTKmath SimTKsimbody}: \
    bin.lib.version = "-$version.major.$version.minor"

# Installation
#
# The general header installation scheme is as follows.
#
#   The "Core", "Top", and "Internal" names are from the upstream
#   CMakeLists.txt.
#
#   <srcdir> Is the library's source directory.
#
#   <incdir> is the include directory the library's headers will be installed
#            to below include/simbody/.
#
# Core headers
#
# <srcdir>/include/h          -> include/simbody/
# <srcdir>/<subdir>/include/h -> include/simbody/
#
# Top headers
#
# <srcdir>/include/<incdir>/h          -> include/simbody/<incdir>/
# <srcdir>/<subdir>/include/<incdir>/h -> include/simbody/<incdir>/
#
# Internal headers
#
# <srcdir>/include/<incdir>/internal/h          -> include/simbody/<incdir>/internal/
# <srcdir>/<subdir>/include/<incdir>/internal/h -> include/simbody/<incdir>/internal/
#
{hxx h}{*}:
{
  install = false # Default to not installed
  install.subdirs = false
}

# SimTKcommon
#
for d: . $common_dirs
{
  # Core headers
  SimTKcommon/$d/include/hxx{*}: install = include/simbody/

  # Top headers
  SimTKcommon/$d/include/SimTKcommon/hxx{*}: \
    install = include/simbody/SimTKcommon/

  # Internal headers
  SimTKcommon/$d/include/SimTKcommon/internal/hxx{*}: \
      install = include/simbody/SimTKcommon/internal/
}

# SiMTKmath
#
for d: . $math_dirs
{
  # Core headers
  SimTKmath/$d/include/hxx{*}: install = include/simbody/

  # Top headers
  SimTKmath/$d/include/simmath/hxx{*}: install = include/simbody/simmath/

  # Internal headers
  SimTKmath/$d/include/simmath/internal/hxx{*}: \
      install = include/simbody/simmath/internal/
}

# Simbody
#
for d: . $simbody_dirs
{
  # Core headers
  Simbody/$d/include/hxx{*}: install = include/simbody/

  # Top headers
  Simbody/$d/include/simbody/hxx{*}: install = include/simbody/simbody/

  # Internal headers
  Simbody/$d/include/simbody/internal/hxx{*}: \
    install = include/simbody/simbody/internal/
}

lib{SimTKcommon SimTKmath SimTKsimbody}: cxx.pkgconfig.include = include/simbody/
