2020-01-04 14:21:38 +00:00
project (
2020-02-29 20:34:08 +00:00
'tomlplusplus' ,
'cpp' ,
2021-08-11 15:42:00 +00:00
version : '2.5.0' ,
2020-09-05 10:26:12 +00:00
meson_version : '>=0.53.0' ,
2020-01-04 14:21:38 +00:00
license : 'MIT' ,
2020-10-30 13:09:28 +00:00
default_options : [ # https://mesonbuild.com/Builtin-options.html
2020-09-05 10:26:12 +00:00
# core options
'buildtype=release' ,
2020-01-04 14:21:38 +00:00
'warning_level=3' ,
2020-02-29 20:34:08 +00:00
'werror=true' ,
2020-09-05 10:26:12 +00:00
'layout=flat' ,
# base options
'b_lto=true' ,
'b_ndebug=if-release' ,
# compiler options
'cpp_std=c++17'
2020-01-04 14:21:38 +00:00
]
)
2020-02-29 20:34:08 +00:00
2020-09-05 10:26:12 +00:00
#######################################################################################################################
# compiler management
#######################################################################################################################
2020-03-04 11:01:46 +00:00
2020-09-05 10:26:12 +00:00
compiler = meson . get_compiler ( 'cpp' )
message ( [ 'target cpu_family' , host_machine . cpu_family ( ) ] )
message ( [ 'target cpu' , host_machine . cpu ( ) ] )
message ( [ 'target system' , host_machine . system ( ) ] )
message ( [ 'target endian' , host_machine . endian ( ) ] )
2020-03-18 13:28:00 +00:00
2020-09-05 10:26:12 +00:00
is_gcc = compiler . get_id ( ) == 'gcc'
is_clang = compiler . get_id ( ) == 'clang'
is_msvc = compiler . get_id ( ) == 'msvc'
is_icc_cl = compiler . get_id ( ) == 'intel-cl'
is_icc = is_icc_cl or compiler . get_id ( ) == 'intel'
2020-10-09 05:50:15 +00:00
is_lld = compiler . get_linker_id ( ) == 'ld.lld'
2020-09-05 10:26:12 +00:00
is_debug = get_option ( 'debug' )
is_release = not is_debug
is_pedantic = get_option ( 'pedantic' )
is_windows = host_machine . system ( ) == 'windows'
is_x64 = host_machine . cpu_family ( ) == 'x86_64'
is_subproject = meson . is_subproject ( )
has_exceptions = get_option ( 'cpp_eh' ) != 'none'
2021-04-18 12:04:46 +00:00
include_dirs = include_directories ( 'include' , 'external' )
2020-09-05 10:26:12 +00:00
overrides = [ ]
additional_arguments = [ ]
2020-03-18 13:28:00 +00:00
2020-09-05 10:26:12 +00:00
message ( [ 'is_release' , is_release ] )
message ( [ 'is_windows' , is_windows ] )
message ( [ 'is_x64' , is_x64 ] )
2020-10-30 13:09:28 +00:00
message ( [ 'has_exceptions' , has_exceptions ] )
2020-08-08 17:51:33 +00:00
2020-09-05 10:26:12 +00:00
# compiler argument references:
# msvc: https://docs.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-alphabetically?view=vs-2019
# intel and intel-cl: https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-oneapi-dev-guide-and-reference/top/compiler-reference/compiler-options/alphabetical-list-of-compiler-options.html
# gcc:
# clang:
2020-04-08 13:33:57 +00:00
2020-09-05 10:26:12 +00:00
# GCC or Clang
if is_gcc or is_clang
add_project_arguments (
'-march=native' ,
2021-04-18 12:04:46 +00:00
'-fvisibility=hidden' ,
'-fvisibility-inlines-hidden' ,
2020-09-05 10:26:12 +00:00
language : 'cpp'
)
if is_release
add_project_arguments (
'-fdata-sections' ,
'-ffunction-sections' ,
'-Wl,--gc-sections' ,
'-Wl,-s' ,
2021-04-18 12:04:46 +00:00
'-mfma' ,
2020-03-18 13:28:00 +00:00
language : 'cpp'
)
endif
2020-09-05 10:26:12 +00:00
endif
2020-03-18 13:28:00 +00:00
2020-10-30 13:09:28 +00:00
2020-09-05 10:26:12 +00:00
# GCC
if is_gcc
add_project_arguments (
'-fmax-errors=5' ,
'-Wno-init-list-lifetime' ,
language : 'cpp'
)
if is_pedantic
2020-10-09 05:50:15 +00:00
add_project_arguments (
'-Wcast-align' ,
'-Wcast-qual' ,
'-Wctor-dtor-privacy' ,
'-Wdisabled-optimization' ,
'-Wextra' ,
'-Wfloat-equal' ,
'-Wimport' ,
'-Winit-self' ,
'-Wlogical-op' ,
'-Wmissing-declarations' ,
'-Wmissing-field-initializers' ,
'-Wmissing-format-attribute' ,
'-Wmissing-include-dirs' ,
'-Wmissing-noreturn' ,
'-Wnoexcept' ,
'-Wold-style-cast' ,
'-Woverloaded-virtual' ,
'-Wpacked' ,
'-Wpadded' ,
'-Wpedantic' ,
'-Wpointer-arith' ,
'-Wredundant-decls' ,
'-Wshadow' ,
'-Wsign-conversion' ,
'-Wsign-promo' ,
'-Wstack-protector' ,
'-Wstrict-null-sentinel' ,
'-Wswitch-default' ,
'-Wswitch-enum' ,
'-Wundef' ,
'-Wunreachable-code' ,
'-Wunused' ,
'-Wunused-parameter' ,
2020-12-15 11:39:58 +00:00
'-Wuseless-cast' ,
2020-10-09 05:50:15 +00:00
'-Wvariadic-macros' ,
'-Wwrite-strings' ,
'-Wmissing-noreturn' ,
'-Wsuggest-attribute=const' ,
'-Wsuggest-attribute=pure' ,
2020-03-18 13:28:00 +00:00
language : 'cpp'
)
endif
2020-09-05 10:26:12 +00:00
if is_release
2020-10-09 05:50:15 +00:00
add_project_arguments (
'-fmerge-constants' ,
language : 'cpp'
)
2020-09-05 10:26:12 +00:00
endif
endif
2020-03-18 13:28:00 +00:00
2020-09-05 10:26:12 +00:00
# Clang
if is_clang
if is_pedantic
add_project_arguments ( '-Weverything' , language : 'cpp' )
2020-08-08 17:51:33 +00:00
endif
2020-09-05 10:26:12 +00:00
add_project_arguments (
'-ferror-limit=5' ,
'-Wno-unused-command-line-argument' ,
2020-08-08 17:51:33 +00:00
2020-09-05 10:26:12 +00:00
# flags from here down are disabling stupidly pedantic warnings that only appear with -Weverything
'-Wno-c++98-compat' ,
'-Wno-c++98-compat-pedantic' ,
'-Wno-documentation' ,
'-Wno-documentation-unknown-command' ,
'-Wno-switch-enum' ,
'-Wno-covered-switch-default' ,
language : 'cpp'
)
if get_option ( 'time_trace' )
add_project_arguments ( '-ftime-trace' , language : 'cpp' )
endif
if is_release
2020-10-09 05:50:15 +00:00
add_project_arguments (
'-Oz' ,
'-fmerge-all-constants' ,
language : 'cpp'
)
2020-09-05 10:26:12 +00:00
endif
endif
# MSVC or icc-cl
if is_msvc or is_icc_cl
add_project_arguments (
'/bigobj' ,
'/fp:except-' , # disable floating-point exceptions
'/Gy' , # function-level linking
'/GF' , # string pooling
'/openmp-' ,
'/permissive-' ,
2020-09-17 12:16:36 +00:00
'/sdl-' ,
2020-09-05 10:26:12 +00:00
'/utf-8' ,
'/volatile:iso' ,
'/Zc:__cplusplus' ,
'/Zc:inline' ,
'/Zc:throwingNew' ,
'/Zi' , # generate debug info (doesn't affect optimization)
language : 'cpp'
)
add_project_link_arguments ( '/DEBUG' , language : 'cpp' ) # generate PDB (doesn't affect optimization)
if is_release
add_project_arguments (
'/GL' , # whole program optimization
'/Gw' , # Optimize Global Data
'/Ob3' , # aggressive inlining
'/Oy' , # omit frame pointers
'/Oi' , # generate intrinsics
2020-03-18 13:28:00 +00:00
language : 'cpp'
2020-09-17 12:16:36 +00:00
)
2020-09-05 10:26:12 +00:00
add_project_link_arguments ( '/ltcg' , language : 'cpp' )
endif
if is_pedantic
add_project_arguments ( '/W4' , language : 'cpp' )
2020-03-18 13:28:00 +00:00
endif
2020-09-05 10:26:12 +00:00
if is_x64
add_project_arguments ( '/arch:AVX' , language : 'cpp' )
endif
endif
2020-03-18 13:28:00 +00:00
2020-09-05 10:26:12 +00:00
# icc-cl
if is_icc_cl
add_project_arguments (
'/wd82' , # storage class is not first
'/wd177' , # unreferenced var
'/wd280' , # selector expression is constant (why the fuck is that a warning?)
'/wd411' , # class provides no constructor (duh, it's an aggregate)
'/wd869' , # parameter "blah" was never referenced
'/wd1011' , # missing return statement (false negative)
'/wd1628' , # function marked [[noreturn]] returns (false positive)
'/wd2261' , # assume with side effects discarded
'/wd2557' , # mismatched sign compare
'/wd3280' , # declaration hides member (triggered in Catch2)
language : 'cpp'
)
endif
2020-03-18 13:28:00 +00:00
2020-09-05 10:26:12 +00:00
# icc (any)
if is_icc
add_project_arguments (
'/Qdiag-error-limit:5' ,
'/Qoption,cpp,--unicode_source_kind,UTF-8' ,
'/D__builtin_bit_cast(T, v)=([&]()noexcept{ T val; memcpy(&val, &v, sizeof(T)); return val; })()' , # __builtin_bit_cast workaround
language : 'cpp'
)
endif
# windows stuff
if is_windows
add_project_arguments (
'-D_ITERATOR_DEBUG_LEVEL=0' ,
'-D_WINSOCK_DEPRECATED_NO_WARNINGS' ,
'-D_SCL_SECURE_NO_WARNINGS' ,
'-D_CRT_SECURE_NO_WARNINGS' ,
language : 'cpp'
)
add_project_arguments ( has_exceptions ? '-D_HAS_EXCEPTIONS=1' : '-D_HAS_EXCEPTIONS=0' , language : 'cpp' )
elif is_release
overrides + = 'strip=true'
endif
2020-10-30 13:09:28 +00:00
2020-10-09 05:50:15 +00:00
# LTO
if is_lld or is_debug
overrides + = 'b_lto=false'
endif
2020-09-05 10:26:12 +00:00
#######################################################################################################################
# c++ 20 check
#######################################################################################################################
compiler_supports_cpp20_args = [ ]
if is_gcc or is_clang
compiler_supports_cpp20_args + = '-std=c++2a'
elif is_icc
compiler_supports_cpp20_args + = '/Qstd=c++2a'
elif is_msvc
compiler_supports_cpp20_args + = '/std:c++latest'
endif
compiler_supports_cpp20 = compiler_supports_cpp20_args . length ( ) > 0 and compiler . links ( '' '
#include <version>
#include <string>
#include <iostream>
int main ( )
{
std : : string s = " kek " ;
std : : cout < < s < < std : : endl ;
return 0 ;
}
'' ' ,
name : 'supports c++20' ,
args : compiler_supports_cpp20_args
)
2020-03-18 13:28:00 +00:00
2020-09-05 10:26:12 +00:00
#######################################################################################################################
# char8_t check
#######################################################################################################################
compiler_supports_char8_args = [ ]
if is_gcc or is_clang
compiler_supports_char8_args + = '-fchar8_t'
endif
compiler_supports_char8_args_private = [ ]
compiler_supports_char8_args_private + = compiler_supports_cpp20_args
compiler_supports_char8_args_private + = compiler_supports_char8_args
compiler_supports_char8 = compiler_supports_cpp20 and compiler . links ( '' '
#include <version>
#include <string_view>
#include <string>
#include <type_traits>
using namespace std : : string_view_literals ;
2021-05-19 11:36:25 +00:00
#if !defined(__cpp_char8_t) || __cpp_char8_t < 201811 || !defined(__cpp_lib_char8_t) || __cpp_lib_char8_t < 201907
2020-09-05 10:26:12 +00:00
#error oh noes
#endif
static_assert ( ! std : : is_same_v < char , char8_t > ) ;
static_assert ( ! std : : is_same_v < std : : string , std : : u8string > ) ;
std : : u8string func ( )
{
return std : : u8string { u8 " this is a test . " sv } ;
}
int main ( )
{
return 0 ;
}
'' ' ,
name : 'supports char8_t' ,
args : compiler_supports_char8_args_private
)
#######################################################################################################################
# consteval check
2020-10-30 13:09:28 +00:00
# (this doesn't inform the build in any way; it's just so i can see who supports it properly)
2020-09-05 10:26:12 +00:00
#######################################################################################################################
compiler_supports_consteval = compiler_supports_cpp20 and compiler . compiles ( '' '
2020-10-09 05:50:15 +00:00
consteval int test ( ) noexcept
2020-09-05 10:26:12 +00:00
{
return 42 ;
}
int main ( )
{
2020-10-09 05:50:15 +00:00
constexpr auto val = test ( ) ; / / test ( ) should be compiletime - callable
return val ;
2020-09-05 10:26:12 +00:00
}
'' ' ,
2020-10-09 05:50:15 +00:00
name : 'supports consteval keyword' ,
2020-09-05 10:26:12 +00:00
args : compiler_supports_cpp20_args
)
2020-10-30 13:09:28 +00:00
compiler_supports_consteval_properly = compiler_supports_consteval and not compiler . compiles ( '' '
consteval int test ( int i ) noexcept
{
return 42 + i ;
}
int get_value ( ) noexcept ;
int main ( )
{
return test ( get_value ( ) ) ; / / test ( ) should not be runtime - callable
}
'' ' ,
name : 'consteval is just renamed constexpr' ,
args : compiler_supports_cpp20_args
)
2020-09-05 10:26:12 +00:00
#######################################################################################################################
# __fp16 and _Float16 checks
#######################################################################################################################
float_16_preprocessor_single_check_template = '' '
#ifndef @0@
#error @0@ wasn't defined!
#else
#pragma message("@0@: " MAKE_STRING(@0@))
#endif
#if @0@ != @1@
#error @0@ was not @1@!
#endif
'' '
float_16_preprocessor_checks = '' '
#define MAKE_STRING(s) MAKE_STRING_1(s)
#define MAKE_STRING_1(s) #s
2020-10-09 05:50:15 +00:00
'' ' + float_16_preprocessor_single_check_template.format(' __FLT_RADIX__ ', ' 2 ' ) \
+ float_16_preprocessor_single_check_template . format ( '__FLT16_MANT_DIG__' , '11' ) \
+ float_16_preprocessor_single_check_template . format ( '__FLT16_DIG__' , '3' ) \
+ float_16_preprocessor_single_check_template . format ( '__FLT16_MIN_EXP__' , '-13' ) \
+ float_16_preprocessor_single_check_template . format ( '__FLT16_MIN_10_EXP__' , '-4' ) \
+ float_16_preprocessor_single_check_template . format ( '__FLT16_MAX_EXP__' , '16' ) \
2020-09-05 10:26:12 +00:00
+ float_16_preprocessor_single_check_template . format ( '__FLT16_MAX_10_EXP__' , '4' )
compiler_supports_float16_args = [ ]
if is_gcc
compiler_supports_float16_args + = '-mfp16-format=ieee'
endif
compiler_supports_fp16 = compiler . links ( '' '
int main ( )
{
static_assert ( sizeof ( __fp16 ) == 2 ) ;
__fp16 f = static_cast < __fp16 > ( 1 ) ;
const auto f2 = static_cast < float > ( f ) ;
const auto f3 = static_cast < __fp16 > ( 0 . 2 L ) ;
return 0 ;
}
2020-10-09 05:50:15 +00:00
'' ' ,
2020-09-05 10:26:12 +00:00
name : 'supports __fp16' ,
args : compiler_supports_float16_args
)
compiler_supports_float16 = compiler . links ( '' '
@ 0 @
int main ( )
{
static_assert ( sizeof ( _Float16 ) == 2 ) ;
_Float16 f = static_cast < _Float16 > ( 1 ) ;
const auto f2 = static_cast < float > ( f ) ;
const auto f3 = static_cast < _Float16 > ( 0 . 2 L ) ;
return 0 ;
}
'' ' . format ( float_16_preprocessor_checks ) ,
name : 'supports _Float16' ,
args : compiler_supports_float16_args
)
if compiler_supports_fp16 or compiler_supports_float16
additional_arguments + = compiler_supports_float16_args
endif
#######################################################################################################################
# int128 check
#######################################################################################################################
compiler_supports_int128 = compiler . links ( '' '
#ifndef __SIZEOF_INT128__
#error __SIZEOF_INT128__ wasn't defined!
#endif
#include <cstdint>
int main ( )
{
static_assert ( __SIZEOF_INT128__ == 16 ) ;
static_assert ( sizeof ( __int128_t ) == 16 ) ;
static_assert ( sizeof ( __uint128_t ) == 16 ) ;
__int128_t i = static_cast < __int128_t > ( 1 ) ;
const auto i2 = static_cast < int64_t > ( i ) ;
const auto i3 = static_cast < int32_t > ( i ) ;
return 0 ;
}
'' ' ,
name : 'supports __int128_t'
)
#######################################################################################################################
# float128 check
#######################################################################################################################
compiler_supports_float128 = compiler . links ( '' '
#ifndef __SIZEOF_FLOAT128__
#error __SIZEOF_FLOAT128__ wasn't defined!
#endif
#ifndef __FLT128_MANT_DIG__
#error __FLT128_MANT_DIG__ wasn't defined!
#endif
#ifndef __LDBL_MANT_DIG__
#error __LDBL_MANT_DIG__ wasn't defined!
#endif
#if __FLT128_MANT_DIG__ <= __LDBL_MANT_DIG__
#error __FLT128_MANT_DIG__ was <= __LDBL_MANT_DIG__
#endif
int main ( )
{
static_assert ( __SIZEOF_FLOAT128__ == 16 ) ;
static_assert ( sizeof ( __float128 ) == 16 ) ;
__float128 f = static_cast < __float128 > ( 1 ) ;
const auto f2 = static_cast < long double > ( f ) ;
const auto f3 = static_cast < double > ( f ) ;
return 0 ;
}
'' ' ,
name : 'supports __float128'
)
2020-12-09 07:48:02 +00:00
if compiler_supports_float128 and is_gcc and not is_subproject
2020-10-30 13:09:28 +00:00
add_global_arguments ( '-fext-numeric-literals' , language : 'cpp' )
2020-09-05 10:26:12 +00:00
endif
2020-03-18 13:28:00 +00:00
2020-09-05 10:26:12 +00:00
#######################################################################################################################
# subdirectories
#######################################################################################################################
build_tests = get_option ( 'build_tests' ) and not is_subproject
if build_tests
2021-04-18 12:04:46 +00:00
run_command ( 'git' , 'submodule' , 'update' , '--init' , '--depth' , '1' , 'external/Catch2' )
run_command ( 'git' , 'submodule' , 'update' , '--init' , '--depth' , '1' , 'external/tloptional' )
2020-09-05 10:26:12 +00:00
subdir ( 'tests' )
2020-03-04 11:01:46 +00:00
endif
2020-01-04 14:21:38 +00:00
2020-09-05 10:26:12 +00:00
build_examples = get_option ( 'build_examples' ) and not is_subproject
if build_examples
subdir ( 'examples' )
endif
2021-09-21 13:57:05 +00:00
if not is_subproject
install_subdir ( 'include/toml++' ,
strip_directory : true ,
install_dir : 'include/toml++'
)
endif
2020-04-03 08:03:15 +00:00
2020-09-05 10:26:12 +00:00
#######################################################################################################################
# dependencies, cmake etc.
#######################################################################################################################
tomlplusplus_dep = declare_dependency (
include_directories : include_directories ( 'include' ) ,
version : meson . project_version ( ) ,
)
2021-09-21 13:57:05 +00:00
if not is_subproject
import ( 'pkgconfig' ) . generate (
name : meson . project_name ( ) ,
version : meson . project_version ( ) ,
description : 'Header-only TOML config file parser and serializer for C++' ,
install_dir : join_paths ( get_option ( 'datadir' ) , 'pkgconfig' ) ,
)
endif
2020-04-07 15:33:00 +00:00
2020-09-05 10:26:12 +00:00
# cmake
if get_option ( 'generate_cmake_config' ) and not is_subproject
cmake = import ( 'cmake' )
cmake . write_basic_package_version_file (
name : meson . project_name ( ) ,
2020-09-17 12:16:36 +00:00
version : meson . project_version ( ) ,
install_dir : join_paths ( 'lib' , 'cmake' , meson . project_name ( ) ) ,
2020-09-05 10:26:12 +00:00
)
2020-09-17 12:16:36 +00:00
2020-09-05 10:26:12 +00:00
cmake_conf = configuration_data ( )
cmake . configure_package_config_file (
name : meson . project_name ( ) ,
input : 'cmake/tomlplusplus.cmake.in' ,
configuration : cmake_conf ,
2020-09-17 12:16:36 +00:00
install_dir : join_paths ( 'lib' , 'cmake' , meson . project_name ( ) ) ,
2020-09-05 10:26:12 +00:00
)
2020-04-07 19:34:54 +00:00
endif