# file      : odb/buildfile
# license   : GNU GPL v3; see accompanying LICENSE file

define plugin: libs

plugin{*}:
{
  bin.lib.prefix = # No lib prefix.
  backlink = true  # Backlink in forwarded configs (next to exe).
}

# For now we use the .so extension everywhere except Windows (see
# plugin_path() in odb.cxx for details).
#
if ($cxx.target.class != 'windows')
  plugin{*}: extension = so

# By default install the plugin next to the driver.
#
# On Windows this is the only sane option where we want the plugin (odb.dll)
# to go into bin/ since failed that we won't be able to find libraries we
# depend on.
#
# On other platforms another option is to install into the GCC's plugin
# directory. This way the same driver can be used with multiple GCC versions
# and is something that distributions packagers sometimes want to do.
#
# So at some point we should also make it configurable, including support for
# installing into GCC's plugin directory.
#
# NOTE: see ODB_GCC_PLUGIN_DIR when adding this support.
#
# NOTE: also think about relocatable installation.
#
plugin{*}: install = bin/

import libs  = libcutl%lib{cutl}
import libs += libstudxml%lib{studxml}
import libs += libstud-optional%lib{stud-optional}

./: exe{odb} plugin{odb}

# We need to make driver depend on plugin but not link it so that when, for
# example, driver is imported, plugin is updated as well.
#
# We, however, don't want to install via the driver since the same driver
# build could be used with multiple plugin builds (e.g., for different GCC
# versions, which is something distribution packagers sometimes want to do).
#
exe{odb}: cxx{odb}
exe{odb}: libus{odb}: bin.whole = false
exe{odb}: plugin{odb}:
{
  include = adhoc

  # @@ This work but triggers "incompatible libs{cutl} build". Feels like to
  #    solve this we will also need to say update_for_install=false which
  #    we currently cant.
  #
  #install = false
}

# Target metadata, see also --build2-metadata in odb.cxx.
#
# While ODB itself doesn't use any environment variables, it uses GCC
# underneath which does (see "Environment Variables Affecting GCC").
#
exe{odb}:
{
  export.metadata = 1 odb
  odb.name = [string] odb
  odb.version = [string] $version
  odb.checksum = [string] $version
  odb.environment = [strings] CPATH CPLUS_INCLUDE_PATH GCC_EXEC_PREFIX COMPILER_PATH
}

plugin{odb}: libus{odb}

switch $cxx.target.system
{
  # On Windows we have to link the import stub.
  #
  case 'mingw32'
    plugin{odb}: cxx.libs += $plugin_dir/cc1plus.exe.a

  # On Mac OS we have to allow undefined symbols.
  #
  case 'darwin'
    plugin{odb}: cxx.loptions += -undefined dynamic_lookup
}

libus{odb}: {hxx ixx txx cxx}{** -odb -version -options -pregenerated/**} \
            hxx{version} $libs

# Include the generated version header into the distribution (so that we don't
# pick up an installed one) and don't remove it when cleaning in src (so that
# clean results in a state identical to distributed).
#
hxx{version}: in{version} $src_root/manifest
hxx{version}:
{
  dist  = true
  clean = ($src_root != $out_root)
}

# Build options.
#
# Note: escape backslashes in gxx_name.
#
cxx.poptions += "-I$plugin_dir/include"
cxx.poptions += "-DODB_GXX_NAME=\"$regex.replace($gxx_name, '\\', '\\\\')\""

## Consumption build ($develop == false).
#

# Use pregenerated versions in the consumption build.
#
libus{odb}: pregenerated/{hxx ixx cxx}{**}: include = (!$develop)

if! $develop
  cxx.poptions =+ "-I($src_base/pregenerated)" # Note: must come first.

# Distribute pregenerated versions only in the consumption build.
#
pregenerated/{hxx ixx cxx}{*}: dist = (!$develop)

#
##

## Development build ($develop == true).
#

libus{odb}: {hxx ixx cxx}{options}: include = $develop

if $develop
  import! [metadata] cli = cli%exe{cli}

# In the development build distribute regenerated {hxx ixx cxx}{options},
# remapping their locations to the paths of the pregenerated versions (which
# are only distributed in the consumption build; see above). This way we make
# sure that the distributed files are always up-to-date.
#
<{hxx ixx cxx}{options}>: cli{options} $cli
{
  dist = ($develop ? pregenerated/odb/ : false)

  # Symlink the generated code in src for convenience of development.
  #
  backlink = true
}
%
if $develop
{{
  options = --include-with-brackets --include-prefix odb --guard-prefix ODB  \
            --generate-file-scanner --generate-specifier --generate-modifier \
            --generate-description --suppress-undocumented                   \
            --cxx-prologue '#include <odb/option-parsers.hxx>'

  $cli $options -o $out_base $path($<[0])

  # If the result differs from the pregenerated version, copy it over.
  #
  if diff $src_base/pregenerated/odb/options.hxx $path($>[0]) >- && \
     diff $src_base/pregenerated/odb/options.ixx $path($>[1]) >- && \
     diff $src_base/pregenerated/odb/options.cxx $path($>[2]) >-
    exit

  cp $path($>[0]) $src_base/pregenerated/odb/options.hxx
  cp $path($>[1]) $src_base/pregenerated/odb/options.ixx
  cp $path($>[2]) $src_base/pregenerated/odb/options.cxx
}}

#
##

# Pass the copyright notice extracted from the LICENSE file.
#
obj{odb}: cxx.poptions += -DODB_COPYRIGHT=\"$copyright\"

# Don't install any of the plugin's headers.
#
{hxx ixx txx}{*}: install = false
