|
JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
|
Macro setup for dual-mode headers (header-only / static). More...
Go to the source code of this file.
Macros | |
| #define | JH_INTERNAL_SHOULD_DEFINE 1 |
| #define | JH_INLINE inline |
Macro setup for dual-mode headers (header-only / static).
#pragma once.This header initializes macros that control whether a header emits inline definitions (header-only mode) or only declarations (linked static/shared mode). It allows one unified .h file to serve both build styles.
| Macro | Definition Behavior | Description |
|---|---|---|
(none) | Emit inline definitions | Default header-only mode. |
JH_HEADER_IMPL_BUILD | Emit non-inline definitions | Used by the single implementation TU. |
JH_HEADER_NO_IMPL | Suppress definitions (declarations only) | Used when linking prebuilt objects. |
#if JH_INTERNAL_SHOULD_DEFINE block. #if JH_INTERNAL_SHOULD_DEFINE to avoid redefinition when linked from a static or shared object. #include <jh/macros/header_end.h>. Once you have written a header using <jh/macros/header_begin.h> and <jh/macros/header_end.h>, you can control how that header behaves in each translation unit (TU) by defining specific macros before including it.
Header-only (default)
#include "example.h"
Emits inline definitions. Safe for multiple inclusion. Ideal for direct inclusion without linking any static library.
Implementation TU (static/shared build)
#define JH_HEADER_IMPL_BUILD
#include "example.h"
Emits non-inline strong definitions. Only one TU should use this mode.
#define JH_HEADER_NO_IMPL#include "example.h"#undef JH_HEADER_NO_IMPLSuppose other.h depends on example.h. When you want to strongly instantiate other but not example in the same TU:
Because example.h has already been included once, its definitions are fixed for this TU. Any further includes (directly or indirectly) are guarded and will not re-instantiate.
If you need to build other but not include any example implementation at all:
This is valid only if another TU already provides the strong definition of example.
| Mode | Macro | Effect | Typical Use |
|---|---|---|---|
| Header-only | (none) | Emit inline definitions | Direct inclusion |
| Static/Shared | JH_HEADER_IMPL_BUILD | Emit non-inline strong definitions | Library implementation TU |
| Interface-only | JH_HEADER_NO_IMPL | Suppress definitions (declarations only) | Type visibility only |
<jh/macros/header_end.h>, ensuring no cross-header contamination. With this pattern, a single C++ header can flexibly serve as both a header-only and a static/shared library implementation — eliminating the traditional need to maintain duplicate .h / .cpp files.
Dual-mode headers are designed for both in-library use and external reuse through CMake targets. This section explains how to apply them in practice.
Inside your own library build
Define JH_HEADER_IMPL_BUILD before including each dual-mode header in the single implementation translation unit (TU). This causes strong, non-inline definitions to be generated and linked into the static or shared library.
Other headers or source files in the same project can simply include those headers normally (header-only mode); header guards prevent redefinition.
When providing your library to external users
In your CMake packaging, propagate JH_HEADER_NO_IMPL via target_compile_definitions(... INTERFACE JH_HEADER_NO_IMPL). This ensures that all consumers automatically include headers in declaration-only mode when they link your exported target.
Consumers do not need to define any macros manually — simply linking to the correct target selects the right mode.
Example CMake configuration
add_library(jh-toolkit INTERFACE ${INCLUDE})
add_library(jh-toolkit-static STATIC ${SRC})
target_compile_definitions(jh-toolkit-static INTERFACE JH_HEADER_NO_IMPL)
jh::jh-toolkit → header-only mode (full inline) jh::jh-toolkit-static → prebuilt static object (declarations only) jh/macros/header_begin.h and jh/macros/header_end.h) are intended to be copied directly into your own project, rather than included from jh-toolkit. jh-toolkit, you should rename the macros (e.g. MYLIB_HEADER_NO_IMPL) to avoid namespace pollution or conflicts.