The zep.h header uses the ZEP_SINGLE_HEADER_BUILD macro to determine whether to include implementation:
include/zep.h
#ifdef ZEP_SINGLE_HEADER_BUILD// Include all implementation files#include "../src/buffer.cpp"#include "../src/commands.cpp"#include "../src/display.cpp"#include "../src/editor.cpp"// ... and more#else// Just include headers#include "zep/editor.h"#include "zep/buffer.h"#include "zep/mode_vim.h"// ...#endif
Only define ZEP_SINGLE_HEADER_BUILD in one translation unit. Defining it in multiple files will cause linker errors due to duplicate symbols.
If you’re using CMake, here’s a minimal configuration:
CMakeLists.txt
cmake_minimum_required(VERSION 3.2)project(MyZepApp)set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)# Add Zep include directorytarget_include_directories(myapp PRIVATE zep/include)# Your source filesadd_executable(myapp main.cpp # other source files...)# Link with your rendering backend (ImGui, Qt, etc.)# target_link_libraries(myapp PRIVATE imgui)
You don’t need to add Zep source files to your CMake target - the single header include handles everything.
Single-header builds compile all Zep source in one translation unit, which means:Advantages:
No library to build separately
No linking step
Maximum compiler optimization opportunities
Disadvantages:
Longer initial compile time (typically 5-30 seconds depending on your system)
Every change to the file with ZEP_SINGLE_HEADER_BUILD requires full recompilation
Higher memory usage during compilation
For faster iteration, put the ZEP_SINGLE_HEADER_BUILD definition in a separate .cpp file that you rarely modify. This way, your main code changes don’t trigger Zep recompilation.