--- /dev/null
+# XXX ATM only boost context, no SystemV fallback as it is obsolete anyway
+
+dep_boost_context = dependency('boost', modules: ['context'], required: true)
+conf.set('HAVE_BOOST_CONTEXT', true)
+summary('Context', dep_boost_context.found(), bool_yn: true, section: 'Boost')
+
--- /dev/null
+dep_libresolv = dependency('resolv', required: false)
+
+need = false
+if build_machine.system() == 'darwin'
+ add_project_link_arguments('-lresolv', language: 'cpp')
+ need = true
+endif
+
+summary('Need -lresolv', need, bool_yn: true, section: 'System')
--- /dev/null
+opt_libsnmp = get_option('snmp')
+dep_libsnmp = dependency('libsnmp', required: opt_libsnmp)
+
+conf.set('HAVE_LIBSSNMP', dep_libsnmp.found(), description: 'libsnmp')
+summary('SNMP', dep_libsnmp.found(), bool_yn: true, section: 'Configuration')
--- /dev/null
+../../../../ext/arc4random/meson.build
\ No newline at end of file
--- /dev/null
+../../../../ext/json11/meson.build
\ No newline at end of file
--- /dev/null
+module_dist = ['LICENSE', 'README.md']
+
+subdir('yahttp')
--- /dev/null
+lib_yahttp = static_library(
+ 'yahttp',
+ 'reqresp.cpp',
+ 'router.cpp',
+ extra_files: [
+ 'cookie.hpp',
+ 'exception.hpp',
+ 'reqresp.hpp',
+ 'router.hpp',
+ 'url.hpp',
+ 'utility.hpp',
+ 'yahttp-config.h',
+ 'yahttp.hpp',
+ ],
+ cpp_args: '-Wno-overloaded-virtual',
+ dependencies: [dep_pdns],
+)
+
+dep_yahttp = declare_dependency(
+ link_with: lib_yahttp,
+ include_directories: include_directories('..'),
+)
--- /dev/null
+../../meson
\ No newline at end of file
--- /dev/null
+project(
+ 'pdns-recursor',
+ ['c', 'cpp'],
+ version: run_command('../../builder-support' / 'gen-version', check: true).stdout().strip(),
+ license: 'GPLv2',
+ license_files: 'NOTICE',
+ meson_version: '>= 1.2.1',
+ default_options: [
+ 'buildtype=debugoptimized',
+ 'warning_level=2', # TODO Move this to 3 to enable -Wpedantic
+ 'cpp_std=c++17',
+ ],
+)
+add_project_arguments('-DRECURSOR', language: 'cpp')
+#add_project_arguments('-DSYSCONFDIR=X', language: 'cpp') # XXX
+add_project_arguments('-DNODCACHEDIRNOD="Y"', language: 'cpp') # XXX
+add_project_arguments('-DNODCACHEDIRUDR="Z"', language: 'cpp') # XXX
+
+product_source_dir = meson.current_source_dir()
+product_build_dir = meson.current_build_dir()
+summary('Source Dir', product_source_dir, section: 'Build')
+summary('Build Dir', product_build_dir, section: 'Build')
+
+# Create the configuration object and dependencies list.
+conf = configuration_data()
+
+# Feature detection and system configuration
+subdir('meson' / 'config') # Config
+subdir('meson' / 'version') # Generate version define
+subdir('meson' / 'compiler-setup') # Common compiler setup
+subdir('meson' / 'summary') # Print a system/project summary
+subdir('meson' / 'sysconfdir') # Sysconfdir
+#subdir('meson' / 'libdir') # Libdir
+subdir('meson' / 'platform') # Platform detection
+subdir('meson' / 'timet-size') # Check the size of time_t
+subdir('meson' / 'timet-sign') # Check the sign of time_t
+subdir('meson' / 'atomics') # Check atomics support
+subdir('meson' / 'pthread-headers') # Check pthread headers
+subdir('meson' / 'pthread-setname') # Pthread setname madness
+subdir('meson' / 'strerror') # Strerror_r
+subdir('meson' / 'lua') # Lua
+subdir('meson' / 'hardening') # Hardening
+subdir('meson' / 'net-libs') # Network Libraries
+subdir('meson' / 'tm-gmtoff') # Check for tm_gmtoff field in struct tm
+subdir('meson' / 'mmap') # Check for mmap
+subdir('meson' / 'libsodium') # Libsodium-based signers
+subdir('meson' / 'libdecaf') # Libdecaf-based signers
+subdir('meson' / 'libcrypto') # OpenSSL-based signers
+subdir('meson' / 'libssl') # OpenSSL libssl
+subdir('meson' / 'libsnmp') # SNMP
+subdir('meson' / 'gnutls') # GnuTLS
+subdir('meson' / 'dot') # DNS over TLS
+subdir('meson' / 'clock-gettime') # Clock_gettime
+subdir('meson' / 'boost') # Boost
+#subdir('meson' / 'boost-program-options') # Boost Program Options Library
+subdir('meson' / 'boost-context') # Boost Context Switching Library
+subdir('meson' / 'boost-test') # Boost Testing Library
+subdir('meson' / 'reproducible') # Reproducible Builds
+subdir('meson' / 'libsystemd') # Systemd notification
+subdir('meson' / 'systemd') # Systemd and unit file handling
+subdir('meson' / 'code-coverage') # Code coverage
+subdir('meson' / 'auto-var-init') # Automatic Variable Initialization
+subdir('meson' / 'sanitizers') # Sanitizers
+subdir('meson' / 'malloc-trace') # Malloc-trace
+subdir('meson' / 'socket-dir') # Socket Dir
+subdir('meson' / 'various-functions') # Various Functions
+subdir('meson' / 'various-headers') # Various Headers
+subdir('meson' / 'libresolv') # res_query XXX
+
+common_sources = []
+
+fs = import('fs')
+src_dir = fs.is_dir('.') ? '.' : ''
+docs_dir = 'docs'
+# Toplevel includes
+dep_pdns = declare_dependency(include_directories: include_directories('.', src_dir))
+
+# Ext
+subdir('ext' / 'arc4random')
+subdir('ext' / 'json11')
+subdir('ext' / 'luawrapper')
+#subdir('ext' / 'probds') XXX
+subdir('ext' / 'protozero')
+subdir('ext' / 'yahttp')
+subdir('settings')
+#subdir('settings' / 'rust')
+
+common_sources += files(
+ src_dir / 'aggressive_nsec.cc',
+ src_dir / 'arguments.cc',
+ src_dir / 'axfr-retriever.cc',
+ src_dir / 'base32.cc',
+ src_dir / 'base64.cc',
+ src_dir / 'capabilities.cc',
+ src_dir / 'channel.cc',
+ src_dir / 'coverage.cc',
+ src_dir / 'credentials.cc',
+ src_dir / 'dns.cc',
+ src_dir / 'dnsname.cc',
+ src_dir / 'dnsparser.cc',
+ src_dir / 'dnsrecords.cc',
+ src_dir / 'dnssecinfra.cc',
+ src_dir / 'dnswriter.cc',
+ src_dir / 'ednsextendederror.cc',
+ src_dir / 'ednsoptions.cc',
+ src_dir / 'ednspadding.cc',
+ src_dir / 'ednssubnet.cc',
+ src_dir / 'filterpo.cc',
+ src_dir / 'fstrm_logger.cc',
+ src_dir / 'gettime.cc',
+ src_dir / 'gss_context.cc',
+ src_dir / 'iputils.cc',
+ src_dir / 'ixfr.cc',
+ src_dir / 'json.cc',
+ src_dir / 'libssl.cc',
+ src_dir / 'logger.cc',
+ src_dir / 'logging.cc',
+ src_dir / 'lua-base4.cc',
+ src_dir / 'lua-recursor4.cc',
+ src_dir / 'lwres.cc',
+ src_dir / 'misc.cc',
+ src_dir / 'mtasker_context.cc',
+ src_dir / 'negcache.cc',
+ src_dir / 'nsecrecords.cc',
+ src_dir / 'opensslsigners.cc',
+ src_dir / 'pdns_recursor.cc',
+ src_dir / 'pollmplexer.cc',
+ src_dir / 'protozero.cc',
+ src_dir / 'proxy-protocol.cc',
+ src_dir / 'pubsuffix.cc',
+ src_dir / 'pubsuffixloader.cc',
+ src_dir / 'qtype.cc',
+ src_dir / 'query-local-address.cc',
+ src_dir / 'rcpgenerator.cc',
+ src_dir / 'rec-carbon.cc',
+ src_dir / 'rec-eventtrace.cc',
+ src_dir / 'rec-lua-conf.cc',
+ src_dir / 'rec-protozero.cc',
+ src_dir / 'rec-responsestats.cc',
+ src_dir / 'rec-system-resolve.cc',
+ src_dir / 'rec-taskqueue.cc',
+ src_dir / 'rec-tcounters.cc',
+ src_dir / 'rec-tcp.cc',
+ src_dir / 'rec-tcpout.cc',
+ src_dir / 'rec-zonetocache.cc',
+ src_dir / 'rec_channel.cc',
+ src_dir / 'rec_channel_rec.cc',
+ src_dir / 'recpacketcache.cc',
+ src_dir / 'rec-snmp.cc',
+ src_dir / 'rec-tcp.cc',
+ src_dir / 'recursor_cache.cc',
+ src_dir / 'reczones-helpers.cc',
+ src_dir / 'reczones.cc',
+ src_dir / 'remote_logger.cc',
+ src_dir / 'resolver.cc',
+ src_dir / 'rpzloader.cc',
+ src_dir / 'secpoll-recursor.cc',
+ src_dir / 'secpoll.cc',
+ src_dir / 'shuffle.cc',
+ src_dir / 'sillyrecords.cc',
+ src_dir / 'snmp-agent.cc',
+ src_dir / 'sortlist.cc',
+ src_dir / 'svc-records.cc',
+ src_dir / 'syncres.cc',
+ src_dir / 'taskqueue.cc',
+ src_dir / 'tcpiohandler.cc',
+ src_dir / 'threadname.cc',
+ src_dir / 'tsigverifier.cc',
+ src_dir / 'unix_utility.cc',
+ src_dir / 'uuid-utils.cc',
+ src_dir / 'validate.cc',
+ src_dir / 'validate-recursor.cc',
+ src_dir / 'version.cc',
+ src_dir / 'webserver.cc',
+ src_dir / 'ws-api.cc',
+ src_dir / 'ws-recursor.cc',
+ src_dir / 'zonemd.cc',
+ src_dir / 'zoneparser-tng.cc',
+)
+
+# Generate config.h
+config_h = configure_file(configuration: conf, output: 'config.h')
+
+html_sources = [] # XXX
+incfiles = find_program('incfiles')
+
+htmlfiles = custom_target(
+ command: [incfiles, '@SOURCE_ROOT@'],
+ input: html_sources,
+ output: 'htmlfiles.h',
+ capture: true
+)
+
+dep_htmlfiles = declare_dependency(
+ sources: [htmlfiles],
+)
+
+deps = [
+ dep_pdns,
+ dep_boost,
+ dep_boost_context,
+ dep_json11,
+ dep_libcrypto,
+ dep_libresolv,
+ dep_libsnmp,
+ dep_libsodium,
+ dep_libssl,
+ dep_lua,
+ dep_protozero,
+ dep_rust_settings,
+ dep_settings,
+ dep_yahttp,
+ dep_htmlfiles,
+]
+
+libpdns_dnslabeltext_source = src_dir / 'dnslabeltext.rl'
+libpdns_dnslabeltext_gen = src_dir / 'dnslabeltext.cc'
+if not fs.is_file(libpdns_dnslabeltext_gen)
+ ragel = find_program('ragel', required: true)
+
+ summary('Ragel', ragel.found(), bool_yn: ragel.found(), section: 'DNS Labels')
+ summary('Ragel Path', ragel.full_path(), section: 'DNS Labels')
+ summary('Ragel Version', ragel.version(), section: 'DNS Labels')
+
+ ragel_generator = generator(
+ ragel,
+ output: '@BASENAME@.cc',
+ arguments: ['@INPUT@', '-o', '@OUTPUT@'],
+ )
+
+ libpdns_dnslabeltext_gen = ragel_generator.process(libpdns_dnslabeltext_source)
+endif
+
+libpdns_dnslabeltext = declare_dependency(
+ link_with: static_library(
+ 'pdns-dnslabeltext',
+ libpdns_dnslabeltext_gen,
+ dependencies: deps,
+ )
+)
+
+libpdns_common = declare_dependency(
+ link_with: static_library(
+ 'pdns-common',
+ common_sources,
+ config_h,
+ dependencies: [
+ deps,
+ libpdns_dnslabeltext,
+ ],
+ )
+)
+
+
+tools = {
+ 'pdns-recursor': {
+ 'main': src_dir / 'rec-main.cc',
+ 'deps-extra': [
+ ],
+ 'manpages': [],
+ },
+}
+
+man_pages = []
+foreach tool, info: tools
+ var_name = tool.underscorify()
+ main = files(info['main'])
+
+ export_dynamic = 'export-dynamic' in info ? info['export-dynamic'] : false
+ files_extra = 'files-extra' in info ? info['files-extra'] : []
+ deps_extra = 'deps-extra' in info ? info['deps-extra'] : []
+
+ set_variable(
+ var_name,
+ executable(
+ tool,
+ main,
+ config_h,
+ files_extra,
+ export_dynamic: export_dynamic,
+ dependencies: [
+ deps,
+ libpdns_common,
+ deps_extra,
+ ],
+ )
+ )
+
+ if 'manpages' in info
+ foreach man_page: info['manpages']
+ man_pages += docs_dir / 'manpages' / (man_page + '.rst')
+ endforeach
+ endif
+endforeach
+
--- /dev/null
+option('lua', type: 'combo', choices: ['auto', 'luajit', 'lua'], value: 'auto', description: 'Lua implementation to use')
+option('hardening', type: 'feature', value: 'auto', description: 'Compiler security checks')
+option('hardening-experimental-cf', type: 'combo', choices: ['disabled', 'full', 'branch', 'return', 'check'], value: 'disabled', description: 'Control Flow hardening')
+option('hardening-experimental-scp', type: 'feature', value: 'disabled', description: 'Stack Clash Protection')
+option('hardening-fortify-source', type: 'combo', choices: ['auto', 'disabled', '1', '2', '3'], value: '2', description: 'Source fortification level')
+#option('rng-kiss', type: 'boolean', value: false, description: 'Use the unsafe KISS RNG')
+option('signers-libsodium', type: 'feature', value: 'auto', description: 'Enable libsodium-based signers')
+option('signers-libdecaf', type: 'feature', value: 'auto', description: 'Enable libdecaf-based signers')
+option('signers-libcrypto', type: 'feature', value: 'auto', description: 'Enable OpenSSL libcrypto-based signers)')
+option('signers-libcrypto-path', type: 'string', value: '', description: 'Custom path to find OpenSSL libcrypto')
+option('tls-libssl', type: 'feature', value: 'auto', description: 'OpenSSL-based TLS')
+option('tls-gnutls', type: 'feature', value: 'auto', description: 'GnuTLS-based TLS')
+option('dns-over-tls', type: 'boolean', value: false, description: 'DNS over TLS (requires GnuTLS or OpenSSL)')
+option('unit-tests', type: 'boolean', value: false, description: 'Build and run unit tests')
+# not relevant for rec, but access by boost meson.build
+option('unit-tests-backends', type: 'boolean', value: false, description: 'Build and run backend unit tests')
+option('reproducible', type: 'boolean', value: false, description: 'Reproducible builds (for distro maintainers, makes debugging difficult)')
+option('systemd', type: 'feature', value: 'auto', description: 'Systemd notification (requires libsystemd)')
+option('auto-var-init', type: 'combo', value: 'disabled', choices: ['zero', 'pattern', 'disabled'], description: 'Enable initialization of automatic variables')
+option('malloc-trace', type: 'boolean', value: false, description: 'Enable malloc-trace')
+option('socket-dir', type: 'string', value: '/var/run', description: 'Where the control socket lives')
+option('snmp', type: 'boolean', value: false, description: 'Enable SNMP')
# For C++ it generates cxxsettings-generated.cc containing support for old style
# settings plus conversion from old style to new style.
#
-# For Rust it generates rust/src/lib.rs, containing the structs with
+# For Ruopenst it generates rust/src/lib.rs, containing the structs with
# CXX and Serde annotations and associated code. rust-preamble-in.rs is
# included before the generated code and rus-bridge-in.rs inside the
# bridge module in the generated lib.rs. Header files generated by CXX
file.write(f'to_arg(settings.{section}.{name});\n')
file.write('}\n')
-def gen_cxx(entries):
+def gen_cxx(gendir, entries):
"""Generate the C++ code from the defs in table.py"""
- with open('cxxsettings-generated.cc', mode='w', encoding="UTF-8") as file:
+ with open(gendir + '/cxxsettings-generated.cc', mode='w', encoding="UTF-8") as file:
file.write('// THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n\n')
file.write('#include "arguments.hh"\n')
file.write('#include "cxxsettings.hh"\n')
file.write(' }\n')
file.write('}\n\n')
-def gen_rust(entries):
+def gen_rust(srcdir, entries):
"""Generate Rust code all entries"""
def_functions = []
sections = {}
- with open('rust/src/lib.rs', mode='w', encoding='UTF-8') as file:
+ with open(srcdir + '/rust/src/lib.rs', mode='w', encoding='UTF-8') as file:
file.write('// THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n')
file.write('// START INCLUDE rust-preable-in.rs\n')
- with open('rust-preamble-in.rs', mode='r', encoding='UTF-8') as pre:
+ with open(srcdir + '/rust-preamble-in.rs', mode='r', encoding='UTF-8') as pre:
file.write(pre.read())
file.write('// END INCLUDE rust-preamble-in.rs\n\n')
file.write('#[cxx::bridge(namespace = "pdns::rust::settings::rec")]\n')
file.write('mod recsettings {\n')
- with open('rust-bridge-in.rs', mode='r', encoding='UTF-8') as bridge:
+ with open(srcdir + '/rust-bridge-in.rs', mode='r', encoding='UTF-8') as bridge:
file.write(' // START INCLUDE rust-bridge-in.rs\n')
for line in bridge:
file.write(' ' + line)
else:
file.write(f'.. {name}:: {vers}\n')
-def gen_oldstyle_docs(entries):
+def gen_oldstyle_docs(srcdir, entries):
"""Write old style docs"""
- with open('../docs/settings.rst', mode='w', encoding='UTF-8') as file:
+ with open(srcdir + '/../docs/settings.rst', mode='w', encoding='UTF-8') as file:
file.write('.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n')
file.write(' START INCLUDE docs-old-preamble-in.rst\n\n')
- with open('docs-old-preamble-in.rst', mode='r', encoding='UTF-8') as pre:
+ with open(srcdir + '/docs-old-preamble-in.rst', mode='r', encoding='UTF-8') as pre:
file.write(pre.read())
file.write('.. END INCLUDE docs-old-preamble-in.rst\n\n')
arg = arg.replace(key, repl)
return arg
-def gen_newstyle_docs(argentries):
+def gen_newstyle_docs(srcdir, argentries):
"""Write new style docs"""
entries = sorted(argentries, key = lambda entry: [entry['section'], entry['name']])
- with open('../docs/yamlsettings.rst', 'w', encoding='utf-8') as file:
+ with open(srcdir + '/../docs/yamlsettings.rst', 'w', encoding='utf-8') as file:
file.write('.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n')
file.write(' START INCLUDE docs-new-preamble-in.rst\n\n')
- with open('docs-new-preamble-in.rst', mode='r', encoding='utf-8') as pre:
+ with open(srcdir + '/docs-new-preamble-in.rst', mode='r', encoding='utf-8') as pre:
file.write(pre.read())
file.write('.. END INCLUDE docs-new-preamble-in.rst\n\n')
def generate():
"""Read table, validate and generate C++, Rst and .rst files"""
+ srcdir = '.'
+ gendir = '.'
+ print(len(sys.argv))
+ if len(sys.argv) == 3:
+ print("using ARGS!")
+ srcdir = sys.argv[1]
+ gendir = sys.argv[2]
+
+ print("cwd: " + os.getcwd())
+ print("srcdir: " + srcdir + " = " + os.path.realpath(srcdir))
+ print("gendir: " + gendir + " = " + os.path.realpath(gendir))
+
+ #os.makedirs(gendir + '/rust/src', exist_ok=True)
# read table
- with open('table.py', mode='r', encoding="utf-8") as file:
+ with open(srcdir + '/table.py', mode='r', encoding="utf-8") as file:
entries = eval(file.read())
for entry in entries:
dupcheck1[entry['oldname']] = True
dupcheck2[entry['section'] + '.' + entry['name']] = True
# And generate C++, Rust and docs code based on table
- gen_cxx(entries)
- gen_rust(entries)
+ gen_cxx(srcdir, entries)
+ gen_rust(srcdir, entries)
# Avoid generating doc files in a sdist based build
if os.path.isdir('../docs'):
- gen_oldstyle_docs(entries)
- gen_newstyle_docs(entries)
-
+ gen_oldstyle_docs(srcdir, entries)
+ gen_newstyle_docs(srcdir, entries)
+ # touch pseudo output file
+ with open(gendir + '/timestamp', mode='w', encoding="utf-8") as file:
+ file.write('')
+ file.close()
generate()
--- /dev/null
+sources = files(
+ 'generate.py',
+ 'docs-new-preamble-in.rst',
+ 'docs-old-preamble-in.rst',
+ 'rust-bridge-in.rs',
+ 'rust-preamble-in.rs',
+ 'table.py',
+)
+
+generated = [
+ 'timestamp',
+]
+
+python = find_program('python3')
+
+settings = custom_target(
+ command: [python, '@INPUT0@', '@SOURCE_ROOT@/settings', '@BUILD_ROOT@/settings'],
+ input: sources,
+ output: generated,
+)
+
+subdir('rust')
+
+dep_settings = declare_dependency(
+ dependencies: dep_rust_settings,
+ sources: [settings, 'cxxsupport.cc', 'cxxsettings-generated.cc'],
+ include_directories: [include_directories('.'), ]
+)
+
--- /dev/null
+#!/bin/sh -xe
+
+echo "PWD=$PWD"
+echo "srcdir=$srcdir"
+echo "builddir=$builddir"
+
+$CARGO build --release $RUST_TARGET --target-dir=$builddir/target --manifest-path $srcdir/Cargo.toml
+
+
+cp -p target/$RUSTC_TARGET_ARCH/release/libsettings.a $builddir/settings/rust/libsettings.a
+cp -p target/$RUSTC_TARGET_ARCH/cxxbridge/settings/src/lib.rs.h $srcdir/lib.rs.h
+cp -p target/$RUSTC_TARGET_ARCH/cxxbridge/rust/cxx.h $srcdir/cxx.h
--- /dev/null
+
+build = find_program('build_settings')
+cargo = find_program('cargo')
+infile = 'Cargo.toml'
+outfile = 'libsettings.a'
+
+
+env = environment()
+env.append('CARGO', cargo.full_path())
+env.append('SYSCONFDIR', conf.get('SYSCONFDIR'))
+env.append('NODCACHEDIRNOD', 'XXXlocalstatedir/nod')
+env.append('NODCACHEDIRUDR', 'XXXlocalstatedir/udr')
+env.append('builddir', '.')
+env.append('srcdir', meson.current_source_dir())
+env.append('RUST_TARGET', '')
+env.append('RUSTC_TARGET_ARCH', '')
+
+lib_settings = custom_target('libsettings.a',
+ output: outfile,
+ input: infile,
+ command: [build,
+ ],
+ depend_files: [
+ 'src/bridge.hh',
+ 'src/bridge.rs',
+ 'src/helpers.rs',
+ ],
+ env: env,
+)
+
+dep_rust_settings = declare_dependency(
+ link_with: lib_settings,
+ include_directories: [include_directories('.'), include_directories('src')]
+)