# -*- bazel -*-

# This file is only used in cases when we need to rebuild spdlog from source.
# See repository.bzl for the logic to select when that occurs.

load("@drake//tools/install:install.bzl", "install")
load("@drake//tools/skylark:cc.bzl", "cc_binary", "cc_library")

licenses(["notice"])  # MIT

config_setting(
    name = "linux",
    values = {"cpu": "k8"},
    visibility = ["//visibility:private"],
)

# The public headers are all of the non-inl include files.  When we're building
# our own spdlog, we'll use Drake's @fmt external, not the bundled version.
_HDRS = glob(
    [
        "include/spdlog/**",
    ],
    exclude = [
        "**/*-inl.h",
        "include/spdlog/fmt/bundled/**",
    ],
)

_INCLUDES = ["include"]

_DEFINES = [
    "HAVE_SPDLOG",
    # Use the compiled (not header-only) variant of spdlog for build speed and
    # substantially (20%+) smaller binary sizes.
    "SPDLOG_COMPILED_LIB",
    # Use Drake's @fmt external, not the bundled version inside spdlog.
    "SPDLOG_FMT_EXTERNAL",
]

# The library sources are the srcs plus the -inl include files.
# We use Drake's @fmt external, not the bundled version inside spdlog.
_SRCS = glob(
    [
        "include/spdlog/**/*-inl.h",
        "src/**",
    ],
    exclude = [
        "include/spdlog/fmt/bundled/**",
    ],
)

# Upstream's default is to ship static (not shared), but it is difficult to
# ensure that we obey ODR for libdrake.so if we were to use libspdlog.a.
# Therefore, we will always use a shared library for spdlog inside Drake.
# (We can't use the header-only variant of spdlog because it substantially
# bloats binary sizes by 20% or more in Debug builds, which pushes us over
# the 2 GiB file size limit.)
cc_binary(
    name = "libdrake_spdlog.so",
    srcs = _HDRS + _SRCS,
    defines = _DEFINES,
    includes = _INCLUDES,
    linkopts = select({
        ":linux": [
            "-pthread",
            "-Wl,-soname,libdrake_spdlog.so",
        ],
        # This is a bazel-default rule, and does not need @drake//
        "@//conditions:default": [],
    }),
    # These two lines are how you tell Bazel to create a shared library.
    linkshared = True,
    linkstatic = True,
    deps = ["@fmt"],
)

cc_library(
    name = "spdlog",
    srcs = ["libdrake_spdlog.so"],
    hdrs = _HDRS,
    defines = _DEFINES,
    includes = _INCLUDES,
    linkstatic = True,
    deps = [
        # This is valid iff fmt is compiled in header-only mode.  If it gains a
        # library, we should depend only on the headers here.
        "@fmt",
    ],
    visibility = ["//visibility:public"],
)

install(
    name = "install",
    targets = [":libdrake_spdlog.so"],
    hdr_dest = "include/spdlog",
    hdr_strip_prefix = ["include"],
    hdrs = _HDRS,
    docs = ["LICENSE"],
    visibility = ["//visibility:public"],
)
