Packages
glazer
0.1.4
1.0.0
0.5.17
0.5.16
0.5.15
retired
0.5.14
retired
0.5.13
retired
0.5.12
retired
0.5.11
retired
0.5.10
retired
0.5.9
retired
0.5.8
retired
0.5.7
retired
0.5.6
retired
0.5.5
retired
0.5.4
retired
0.5.3
retired
0.5.2
retired
0.5.1
retired
0.5.0
retired
0.3.2
retired
0.3.0
retired
0.2.6
retired
0.2.5
retired
0.2.4
retired
0.2.3
retired
0.2.2
retired
0.2.1
retired
0.2.0
retired
0.1.7
retired
0.1.6
retired
0.1.5
retired
0.1.4
retired
Erlang NIF JSON encoder/decoder using the glaze C++ library
Retired package: Deprecated - Deprecated
Current section
Files
Jump to
Current section
Files
c_src/CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(glazer CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(ENV{MAKEFLAGS} "--no-print-directory")
# ---- Detect <format> availability ----
# Some toolchains (e.g. GCC 12's libstdc++, or Clang against an older system
# libstdc++) don't ship a working <format> header, which Glaze otherwise
# includes by default (see glaze/core/write_chars.hpp). Probe for it here and
# tell Glaze to fall back to <cstdio>-based float formatting when missing.
include(CheckIncludeFileCXX)
set(CMAKE_REQUIRED_FLAGS "-std=c++23")
check_include_file_cxx("format" GLZ_HAVE_STD_FORMAT)
unset(CMAKE_REQUIRED_FLAGS)
# ---- Fetch glaze ----
include(FetchContent)
FetchContent_Declare(
glaze
GIT_REPOSITORY https://github.com/stephenberry/glaze.git
GIT_TAG v7.7.1
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(glaze)
# ---- Erlang include paths ----
execute_process(
COMMAND erl -noshell -noinput
-eval "io:format(\"~ts/erts-~ts/include\", [code:root_dir(), erlang:system_info(version)]), halt(0)."
OUTPUT_VARIABLE ERL_ERTS_INCLUDE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND erl -noshell -noinput
-eval "io:format(\"~ts\", [code:lib_dir(erl_interface, include)]), halt(0)."
OUTPUT_VARIABLE ERL_EI_INCLUDE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND erl -noshell -noinput
-eval "io:format(\"~ts\", [code:lib_dir(erl_interface, lib)]), halt(0)."
OUTPUT_VARIABLE ERL_EI_LIB
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# ---- NIF shared library ----
add_library(glazer SHARED glaze_nif.cpp)
target_include_directories(glazer PRIVATE
${ERL_ERTS_INCLUDE}
${ERL_EI_INCLUDE}
${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_directories(glazer PRIVATE ${ERL_EI_LIB})
target_link_libraries(glazer PRIVATE glaze::glaze ei)
# NIF symbols (enif_*) are resolved at load time by the BEAM, not at link
# time. On Linux this is fine by default (lazy symbol binding), but macOS's
# linker rejects undefined symbols in shared libraries unless told otherwise.
if(APPLE)
target_link_options(glazer PRIVATE -undefined dynamic_lookup)
endif()
if(NOT GLZ_HAVE_STD_FORMAT)
target_compile_definitions(glazer PRIVATE GLZ_USE_STD_FORMAT_FLOAT=0)
endif()
include(CheckCXXCompilerFlag)
set(CMAKE_REQUIRED_FLAGS "-std=c++23")
check_cxx_compiler_flag("-march=native" GLZ_HAVE_MARCH_NATIVE)
check_cxx_compiler_flag("-mtune=native" GLZ_HAVE_MTUNE_NATIVE)
unset(CMAKE_REQUIRED_FLAGS)
set(GLZ_NATIVE_FLAGS "")
if(GLZ_HAVE_MARCH_NATIVE)
list(APPEND GLZ_NATIVE_FLAGS -march=native)
endif()
if(GLZ_HAVE_MTUNE_NATIVE)
list(APPEND GLZ_NATIVE_FLAGS -mtune=native)
endif()
# GCC's "-flto=auto" produces objects with GNU LTO sections that GNU ld/gold
# can link directly. Upstream Clang on Linux instead emits LLVM bitcode, which
# requires lld (or another LLVM-aware linker) to consume — plain GNU ld fails
# with "file format not recognized". Use Clang's own thin-LTO + lld pairing
# there. AppleClang uses Apple's ld64 (which understands its own LTO objects
# via libLTO), and doesn't ship/accept "-fuse-ld=lld", so leave it on its
# default LTO handling.
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(GLZ_LTO_FLAGS -flto=thin)
target_link_options(glazer PRIVATE -fuse-ld=lld)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
set(GLZ_LTO_FLAGS -flto=thin)
else()
set(GLZ_LTO_FLAGS -flto=auto -fno-fat-lto-objects)
endif()
target_compile_options(glazer PRIVATE
-fPIC
-Wall
-finline-functions
$<$<CONFIG:Release>:-O3 -DNDEBUG ${GLZ_LTO_FLAGS} ${GLZ_NATIVE_FLAGS}>
$<$<CONFIG:Debug>:-O0 -g>
)
# Remove the "lib" prefix so Erlang can load it as "glazer.so"
# Erlang loads NIF libraries with a ".so" extension on every platform
# (including macOS, where CMake's shared-library default is ".dylib").
set_target_properties(glazer PROPERTIES
PREFIX ""
SUFFIX ".so"
OUTPUT_NAME "glazer"
)
# ---- Output to priv/ ----
if(DEFINED PRIV_DIR)
set_target_properties(glazer PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PRIV_DIR}"
)
else()
set_target_properties(glazer PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../priv"
)
endif()