https://codeberg.org/interpeer/s3kr1t.git
Tip revision: de06e4aab9bff4a9491a8f7fdaaf4a28064a00bc authored by Jens Finkhaeuser on 08 May 2023, 09:37:19 UTC
Merge branch 'maintenance'
Merge branch 'maintenance'
Tip revision: de06e4a
meson.build
##############################################################################
# Project
project('s3kr1t', 'cpp',
version: '0.1.0',
license: 'GPLv3',
meson_version: '>=0.58.0',
default_options: [
'cpp_std=c++17',
'default_library=both',
])
##############################################################################
# Versioning, project and libraries
# There are so many versioning schemes, each of which is incompatible with
# others. We'll manage best by keeping things simple:
#
# - The package version follows semver
# - The library version is the package version
# - The ABI version, i.e. the compatibility we expect, is the major
# component of the package
_splitver = meson.project_version().split('.')
PACKAGE_MAJOR = _splitver[0]
PACKAGE_MINOR = _splitver[1]
PACKAGE_PATCH = _splitver[2]
ABI_VERSION = PACKAGE_MAJOR
LIB_VERSION = meson.project_version()
PACKAGE_VERSION = meson.project_version()
##############################################################################
# Configuration
conf_data = configuration_data()
compiler = meson.get_compiler('cpp')
host_type = ''
if host_machine.system() in [ 'cygwin', 'darwin', 'dragonfly', 'freebsd', 'gnu', 'linux', 'netbsd' ]
host_type = 'posix'
elif host_machine.system() == 'windows'
host_type = 'win32'
elif host_machine.system().startswith('android')
host_type = 'android'
endif
summary('Host platform', host_type, section: 'Platform')
# For Windows, try to determine the SDK version.
winsdk_ver = -1
if compiler.has_header('ntverp.h')
code = '''#include <iostream>
#include <ntverp.h>
int main()
{
std::cout << VER_PRODUCTMAJORVERSION;
}
'''
result = compiler.run(code, name: 'Windows SDK version check.')
winsdk_ver = result.stdout().to_int()
summary('Windows SDK major version', winsdk_ver, section: 'Platform')
endif
### Build configuration
bt = get_option('buildtype')
libtype = get_option('default_library')
build_shared = false
if libtype in ['shared', 'both']
build_shared = true
endif
build_static = false
if libtype in ['static', 'both']
build_static = true
endif
### Compiler flags
compiler_id = compiler.get_id()
cpp_args = []
link_args = []
cpp_defines = []
cpp_define_args = []
define_prefix = '-D'
posix_common_args = [
'-Wall', '-Wextra', '-Wpedantic', '-Wshadow', '-Wstrict-aliasing',
'-Wstrict-overflow=5', '-Wcast-align',
'-Wpointer-arith', '-Wcast-qual',
# '-Wold-style-cast', No, because OpenSSL generates a lot of these
]
if compiler_id == 'clang'
cpp_args += posix_common_args + [
'-Wabi', '-flto',
]
link_args += ['-flto']
cpp_defines += ['S3KR1T_IS_BUILDING=1']
elif compiler_id == 'gcc'
cpp_args += posix_common_args + [
'-Wstrict-null-sentinel', '-flto',
]
link_args += ['-flto']
cpp_defines += ['S3KR1T_IS_BUILDING=1']
elif compiler_id == 'msvc'
cpp_args += [
'/wd4250', '/wd4251', '/wd4275',
]
cpp_defines += ['S3KR1T_IS_BUILDING=1']
define_prefix = '/D'
endif
if bt in ['debug', 'debugoptimized']
cpp_defines += ['DEBUG=1']
if compiler_id == 'clang'
cpp_args += ['-ggdb']
elif compiler_id == 'gcc'
cpp_args += ['-g3']
elif compiler_id == 'msvc'
cpp_args += ['/FS']
endif
else
cpp_defines += ['NDEBUG=1']
posix_release_args = [
'-fvisibility=hidden', '-fvisibility-inlines-hidden',
]
if compiler_id == 'clang'
cpp_args += posix_release_args
elif compiler_id == 'gcc'
cpp_args += posix_release_args
elif compiler_id == 'msvc'
cpp_args += ['/Oi', '/DNDEBUG=1']
endif
endif
if host_type == 'android'
# Only posix compilers supported (?)
cpp_defines += ['ANDROID_STL=c++_shared']
cpp_args += [
'-fexceptions', '-frtti',
]
link_args = [
'-lstdc++', '-lm',
]
endif
# Make things work with MSVC and Windows SDK <10
if compiler_id == 'msvc' and winsdk_ver < 10
cpp_args += ['/permissive']
endif
# Turn defines into cpp args
foreach def : cpp_defines
cpp_define_args += [define_prefix + def]
endforeach
add_project_arguments(cpp_args, language: 'cpp')
### Version and package information
conf_data.set_quoted('S3KR1T_PACKAGE_MAJOR', PACKAGE_MAJOR)
conf_data.set_quoted('S3KR1T_PACKAGE_MINOR', PACKAGE_MINOR)
conf_data.set_quoted('S3KR1T_PACKAGE_PATCH', PACKAGE_PATCH)
conf_data.set_quoted('S3KR1T_PACKAGE_VERSION', PACKAGE_VERSION)
conf_data.set_quoted('S3KR1T_ABI_VERSION', ABI_VERSION)
conf_data.set_quoted('S3KR1T_LIB_VERSION', LIB_VERSION)
conf_data.set_quoted('S3KR1T_PACKAGE_NAME', meson.project_name())
conf_data.set_quoted('S3KR1T_PACKAGE_URL', 'https://codeberg.org/interpeer/s3kr1t')
### Host platform details
conf_data.set('S3KR1T_BIGENDIAN', host_machine.endian() == 'big')
### Headers
# TODO
# conf_data.set('S3KR1T_HAVE_ARPA_INET_H',
# compiler.has_header('arpa' / 'inet.h'))
### Types
compiler.sizeof('int32_t', prefix: '#include <stdint.h>')
compiler.sizeof('uint32_t', prefix: '#include <stdint.h>')
compiler.sizeof('int64_t', prefix: '#include <stdint.h>')
compiler.sizeof('uint64_t', prefix: '#include <stdint.h>')
compiler.sizeof('size_t', prefix: '#include <stdint.h>')
compiler.sizeof('ssize_t', prefix: '#include <stdint.h>')
char8_size = compiler.sizeof('char8_t')
if char8_size > 0
conf_data.set('S3KR1T_HAVE_CHAR8_T', true)
endif
wchar_size = compiler.sizeof('wchar_t')
if wchar_size > 0
conf_data.set('S3KR1T_HAVE_WCHAR_T', true)
endif
stdbyte_size = compiler.sizeof('std::byte', prefix: '#include <cstddef>')
if stdbyte_size > 0
conf_data.set('S3KR1T_HAVE_STD_BYTE', true)
endif
have_strerror_s = compiler.compiles('''
#include <string.h>
int main(int, char**)
{
char buf[1];
auto e = strerror_s(buf, sizeof(buf), 0);
}
''', name: 'strerror_s()')
conf_data.set('S3KR1T_HAVE_STRERROR_S', have_strerror_s)
have_strerror_r = compiler.compiles('''
#include <string.h>
int main(int, char**)
{
char buf[1];
auto e = strerror_r(0, buf, sizeof(buf));
}
''', name: 'strerror_r()')
conf_data.set('S3KR1T_HAVE_STRERROR_R', have_strerror_r)
have_getentropy = compiler.compiles('''
#include <unistd.h>
int main(int, char**)
{
char buf[1];
auto e = getentropy(buf, sizeof(buf));
}
''', name: 'getentropy()')
conf_data.set('S3KR1T_HAVE_GETENTROPY', have_getentropy)
have_getrandom = compiler.compiles('''
#include <sys/random.h>
int main(int, char**)
{
char buf[1];
auto e = getrandom(buf, sizeof(buf), GRND_RANDOM);
}
''', name: 'getrandom()')
conf_data.set('S3KR1T_HAVE_GETRANDOM', have_getrandom)
have_bcrypt_genrandom = compiler.compiles('''
#define NOMINMAX
#define UNICODE
#define _UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <WinDef.h>
#include <bcrypt.h>
int main(int, char**)
{
UCHAR buf[1];
auto e = BCryptGenRandom(NULL, buf, sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
}
''', name: 'BCryptGenRandom()')
conf_data.set('S3KR1T_HAVE_BCRYPT_GENRANDOM', have_bcrypt_genrandom)
##############################################################################
# Dependencies
subproject_opts = [
'default_library=' + libtype,
]
libvar_postfix = ''
if libtype in ['static', 'both']
libvar_postfix = '_static_dep'
else
libvar_postfix = '_dep'
endif
deps = []
##### OpenSSL
# Try detecting OpenSSL installed globally
openssl_no_deprecated = get_option('openssl_no_deprecated')
conf_data.set('OPENSSL_NO_DEPRECATED', openssl_no_deprecated)
openssl_dep = dependency(
'OpenSSL',
modules: ['OpenSSL::Crypto'],
fallback: ['openssl', 'libcrypto_dep'],
default_options: subproject_opts,
required: false,
)
deps += [openssl_dep]
openssl_type = openssl_dep.type_name() + ', ' + openssl_dep.version()
summary('OpenSSL', openssl_type, section: 'Crypto Libraries')
conf_data.set('S3KR1T_HAVE_OPENSSL', openssl_dep.found())
if openssl_dep.found()
if openssl_dep.type_name() != 'internal'
have_openssl_sha3 = compiler.compiles('''
#include <openssl/evp.h>
int main(int, char**)
{
EVP_MD const * ret = NULL;
ret = EVP_sha3_224();
}
''',
name: 'EVP_sha3_224()',
dependencies: openssl_dep,
)
conf_data.set('S3KR1T_HAVE_OPENSSL_SHA3', have_openssl_sha3)
if not have_openssl_sha3
error('OpenSSL version does not support SHA-3 family of hash functions.')
endif
else
# Subproject is known to have this
conf_data.set('S3KR1T_HAVE_OPENSSL_SHA3', true)
endif
endif
##### liberate
liberate_dep = dependency(
'liberate',
fallback: ['liberate', 'liberate' + libvar_postfix],
default_options: subproject_opts,
)
deps += [liberate_dep]
summary('liberate', liberate_dep.version(), section: 'Other Dependencies')
##############################################################################
# Set values from options
configure_file(
input: 'build-config.h.in',
output: 'build-config.h',
configuration: conf_data
)
main_build_dir = declare_dependency(
include_directories: include_directories('.')
)
##############################################################################
# Library
includes = include_directories(
'include',
)
install_headers(
'include' / 's3kr1t.h',
)
install_headers(
'include' / 's3kr1t' / 'version.h',
'include' / 's3kr1t' / 'visibility.h',
'include' / 's3kr1t' / 'error.h',
'include' / 's3kr1t' / 'keys.h',
'include' / 's3kr1t' / 'digests.h',
'include' / 's3kr1t' / 'signatures.h',
'include' / 's3kr1t' / 'random.h',
'include' / 's3kr1t' / 'ciphers.h',
'include' / 's3kr1t' / 'pad.h',
subdir: 's3kr1t',
)
libsrc = [
'lib' / 'version.cpp',
'lib' / 'error.cpp',
'lib' / 'keys.cpp',
'lib' / 'digests.cpp',
'lib' / 'signatures.cpp',
'lib' / 'random.cpp',
'lib' / 'ciphers.cpp',
'lib' / 'pad.cpp',
]
dep_internal = false
# Shared library?
if build_shared
so_lib = shared_library('s3kr1t', libsrc,
include_directories: [includes],
dependencies: deps,
link_args: link_args,
cpp_args: cpp_define_args,
version: LIB_VERSION,
soversion: ABI_VERSION,
install: true
)
s3kr1t_dep = declare_dependency(
include_directories: [includes],
dependencies: deps,
compile_args: [],
link_with: [so_lib],
link_args: link_args,
version: LIB_VERSION,
)
dep_internal = s3kr1t_dep
endif
# Static library?
if build_static
static_args = [define_prefix + 'S3KR1T_STATIC=1']
sta_lib = static_library('s3kr1t', libsrc,
include_directories: [includes],
dependencies: deps,
link_args: link_args,
cpp_args: cpp_define_args + static_args,
install: true,
)
s3kr1t_static_dep = declare_dependency(
include_directories: [includes],
dependencies: deps,
compile_args: static_args,
link_with: [sta_lib],
link_args: link_args,
version: LIB_VERSION,
)
dep_internal = s3kr1t_static_dep
endif
##############################################################################
# Subdirectories
subdir('test')
##############################################################################
# Linter, etc.
cppcheck = find_program('cppcheck', required: false)
if cppcheck.found()
run_target('cppcheck', command: [
cppcheck.full_path(),
'--cppcheck-build-dir=@0@/cppcheck'.format(meson.current_build_dir()),
'--enable=all', '-v',
'--suppress=missingIncludeSystem',
'--inline-suppr',
'-I', '@0@/include'.format(meson.current_source_dir()),
'-I', '@0@/lib'.format(meson.current_source_dir()),
'-I', meson.current_build_dir(),
'--std=c++17',
cpp_define_args,
'--quiet',
'@0@/lib'.format(meson.current_source_dir()),
])
endif
oclint = find_program('oclint', required: false)
if oclint.found()
oclint_config = custom_target('oclint_config',
output: '.oclint',
input: '.oclint',
command: ['cp', '@INPUT@', '@OUTPUT@'],
install: false,
)
oclintsrc = []
foreach fname : libsrc
oclintsrc += [meson.current_source_dir() / fname]
endforeach
run_target('oclint', command: [
oclint.full_path(),
oclintsrc,
'-o', '@0@/oclint.log'.format(meson.current_build_dir()),
'--',
'-I', '@0@/include'.format(meson.current_source_dir()),
'-I', '@0@/lib'.format(meson.current_source_dir()),
'-I', meson.current_build_dir(),
'--std=@0@'.format(get_option('cpp_std')),
cpp_args,
cpp_define_args,
'-DOCLINT_IS_RUNNING',
],
depends: oclint_config,
)
endif