Packaging Intel’s libDFP as a CMake static library

Scope: This article is a how-to for wiring your own CMake build around Intel’s official Decimal Floating-Point Math Library package. It does not redistribute Intel’s source code, binaries, or license text. You must download the library from Intel and follow Intel’s license and terms for any use, modification, or sharing.

If you integrate with Interactive Brokers’ API, you may eventually need decimal floating-point support: their stack expects IEEE decimal semantics in places, and one practical route is Intel’s Decimal Floating-Point Math Library (Intel® Decimal Floating-Point Math Library) — often referred to as libDFP or the BID implementation.

Binary float / double are fine for many things, but decimal is what financial rules and APIs often assume; mixing binary floats in those paths can introduce tiny errors that are unacceptable when you need deterministic decimal behavior.

Intel publishes source for Linux, Windows, and macOS. The upstream tree is Makefile-oriented. For personal projects, a small CMake layer you write yourself — living beside a local checkout of Intel’s sources (with Intel’s license file preserved next to them) — can give you one build description you reuse across all three platforms and wire into a parent CMakeLists.txt with add_subdirectory, without mixing Intel’s files into unrelated trees.

This post is how to reason about that wrapper and how it adapts to macOS, Linux, and Windows so the same workflow stays consistent across all three.

Obtaining Intel’s package (your responsibility)#

  1. Use only Intel’s official distribution page and any license or README they ship.
  2. Keep Intel’s license and attribution files with the sources you extract—wherever you store them.
  3. Before you publish a repo that contains Intel source (even in a submodule), read Intel’s license and confirm your use case (private mirror, fork, etc.) is allowed. This guide does not summarize those terms.

What follows assumes you already have Intel’s tree locally in a directory layout you control (e.g. a private repo or a vendor folder) and that you are not relying on this blog to supply any Intel files.

What to take from Intel’s package (conceptually)#

After you unpack Intel’s official package, the pieces you typically compile are essentially the LIBRARY / src tree of C files, plus a CMakeLists.txt that you author. You do not need to wire Intel’s float128/ / DPML transcendental path in a minimal CMake build: that subtree expects Intel’s proprietary mphoc preprocessor for a couple of generated files (#include "mp.h" fails without it). For IB-style decimal work, the core BID operations in src/ (arithmetic, compare, conversions, rounding) are often enough; the missing piece is transcendentals (sin, cos, exp, log, …) in some configurations — match symbols to whatever your consumer actually links.

CMake#

The idea is a single static library target (e.g. bid) that compiles all src/*.c files you choose to include from your Intel tree. Compiler flags and preprocessor defines are platform-specific, but the approach stays the same.

Non-MSVC (macOS, Linux):

target_compile_options(bid PRIVATE -O3 -fPIC -w)
target_compile_definitions(bid PRIVATE
    CALL_BY_REF=0 GLOBAL_RND=0 GLOBAL_FLAGS=0 UNCHANGED_BINARY_FLAGS=0
)

MSVC (Windows):

target_compile_options(bid PRIVATE /w)
target_compile_definitions(bid PRIVATE
    WINDOWS
    CALL_BY_REF=0 GLOBAL_RND=0 GLOBAL_FLAGS=0 UNCHANGED_BINARY_FLAGS=0
)

Key points:

  • -O3 / build type: On macOS and Linux, -O3 is explicit. On Windows with MSVC, optimization is controlled by build type (/Od for Debug, /O2 for Release) — don’t add /O2 directly as it conflicts with MSVC’s /RTC1 debug flag.
  • -fPIC: Needed on POSIX systems; N/A on Windows.
  • WINDOWS define: Tells bid_conf.h that sizeof(long) == 4 on MSVC x64 (critical for correct ABI).
  • -w / /w: Suppress all warnings from this third-party code.

For standalone builds, use a predictable output layout that works across all platforms:

if(APPLE)
    set(_arch ${CMAKE_OSX_ARCHITECTURES})
else()
    set(_arch ${CMAKE_SYSTEM_PROCESSOR})
endif()

set_target_properties(bid PROPERTIES
    ARCHIVE_OUTPUT_DIRECTORY
        "${CMAKE_SOURCE_DIR}/bin/${_arch}/$<LOWER_CASE:$<CONFIG>>"
)

The $<LOWER_CASE:$<CONFIG>> generator expression produces debug or release at build time and works for both single-config generators (Ninja, NMake) and multi-config generators (Visual Studio).

Build commands:

macOS / Linux:

cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j

Windows (Developer Command Prompt, any generator):

cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build

Using the library in a larger app:

add_subdirectory(extern/<your-wrapper-or-vendor-dir>)
target_link_libraries(your_target PRIVATE bid)

The bid target exposes include directories for src/ headers publicly, so consumers compile against the same API.

Platform-specific details#

The sources are portable C; differences are toolchain, ABI, and output layout.

Concern macOS Linux Windows
Compiler Clang (Xcode) GCC or Clang MSVC
Optimization -O3 -O3 build type (/Od//O2)
Warnings -w -w /w
PIC -fPIC -fPIC N/A
Extra define WINDOWS (fixes sizeof(long))
Static output libbid.a libbid.a bid.lib
Architecture variable CMAKE_OSX_ARCHITECTURES CMAKE_SYSTEM_PROCESSOR CMAKE_SYSTEM_PROCESSOR

Using the library in your project#

Once you have libbid.a (or the platform equivalent), wire it into your project with target_link_libraries. The bid target exposes public include directories, so consumers automatically get the right paths and linking.

If you’re integrating with Interactive Brokers’ C++ API (version 9.79+), Part 2 covers packaging the TWS client as a static CMake library that depends on bid. The two libraries combine cleanly: protobuf and decimal support in a single coherent binary without symbol conflicts or version skew. Part 2 includes a full cross-platform CMakeLists.txt walkthrough and a smoke test that validates both the decimal math and protobuf linkage without needing a live IB Gateway connection.

Summary#

  • Intel’s library addresses decimal math where binary float is wrong for the API; you obtain it from Intel and comply with their license.
  • A CMake wrapper you write can sit next to those sources for personal or internal builds and integrate with add_subdirectory.
  • Toolchain-specific CMake branches bridge macOS, Linux, and Windows without maintaining three separate shell builds.

Disclaimer: This is not legal advice. Verify Intel’s current license, redistribution rules, and any Interactive Brokers terms that apply to your deployment before production use.

Share ->