From 8ad51dbba0fd2bcd193bfef544c64dce857856c3 Mon Sep 17 00:00:00 2001 From: Matt Jolly Date: Tue, 1 Oct 2024 19:58:55 +1000 Subject: [PATCH] Implement meson build This is a first pass at porting autoconf/automake to Meson. Signed-off-by: Matt Jolly --- dpi/meson.build | 70 +++++++++ dpid/meson.build | 45 ++++++ dw/meson.build | 74 ++++++++++ meson.build | 354 +++++++++++++++++++++++++++++++++++++++++++++ meson.options | 84 +++++++++++ src/IO/meson.build | 28 ++++ src/meson.build | 71 +++++++++ 7 files changed, 726 insertions(+) create mode 100644 dpi/meson.build create mode 100644 dpid/meson.build create mode 100644 dw/meson.build create mode 100644 meson.build create mode 100644 meson.options create mode 100644 src/IO/meson.build create mode 100644 src/meson.build diff --git a/dpi/meson.build b/dpi/meson.build new file mode 100644 index 00000000..4346f0fa --- /dev/null +++ b/dpi/meson.build @@ -0,0 +1,70 @@ +dpi_link_libs = [dlib, dpip] + +bookmarks_dpi_sources = files( + 'bookmarks.c', + 'dpiutil.c', +) + +cookies_dpi_sources = files( + 'cookies.c', + 'dpiutil.c', +) + +datauri_filter_dpi_sources = files( + 'datauri.c', + 'dpiutil.c', +) + +downloads_dpi_sources = files( + 'downloads.cc', + 'dpiutil.c', +) + +file_dpi_sources = files( + 'dpiutil.c', + 'file.c', +) + +ftp_filter_dpi_sources = files( + 'dpiutil.c', + 'ftp.c', +) + +hello_filter_dpi_sources = files( + 'dpiutil.c', + 'hello.c', +) + +vsource_filter_dpi_sources = files( + 'dpiutil.c', + 'vsource.c', +) + +dpis = { + 'bookmarks': bookmarks_dpi_sources, + 'cookies': cookies_dpi_sources, + 'datauri.filter': datauri_filter_dpi_sources, + 'downloads': downloads_dpi_sources, + 'file': file_dpi_sources, + 'ftp.filter': ftp_filter_dpi_sources, + 'hello.filter': hello_filter_dpi_sources, + 'vsource.filter': vsource_filter_dpi_sources, +} + +# These are all so similar that it's trivial to iterate over +foreach dpi_name, dpi : dpis + installdir = ( + get_option('libdir') / meson.project_name() / 'dpi' / dpi_name.split( + '.', + )[0] + ) + executable( + f'@dpi_name@.dpi', + sources: dpi, + dependencies: fltk, + link_with: dpi_link_libs, + install: true, + install_dir: installdir, + include_directories: [incdir, fltk_include_dirs], + ) +endforeach diff --git a/dpid/meson.build b/dpid/meson.build new file mode 100644 index 00000000..6c1b8d6a --- /dev/null +++ b/dpid/meson.build @@ -0,0 +1,45 @@ +dpid_sources = files( + 'dpi.c', + 'dpi_socket_dir.c', + 'dpid.c', + 'dpid_common.c', + 'main.c', + 'misc_new.c', +) + +link_libs = [ + dlib, + dpip, +] + +executable( + 'dpid', + sources: dpid_sources, + include_directories: incdir, + link_with: link_libs, + install: true, +) + +executable( + 'dpidc', + sources: 'dpidc.c', + include_directories: incdir, + link_with: link_libs, + install: true, +) + +sed = find_program('sed', required: true) +dpid_libdir = get_option('libdir') # TODO: Can we reuse this? +configure_file( + input: 'dpidrc.in', + output: 'dpidrc', + command: [ + sed, + '-e', f's|[@]libdir[@]|@dpid_libdir@|;s|[@]EXEEXT[@]|@exe_suffix@|g', + '@INPUT@', + ], + install_dir: get_option('sysconfdir'), + install: true, +) + + diff --git a/dw/meson.build b/dw/meson.build new file mode 100644 index 00000000..09360d88 --- /dev/null +++ b/dw/meson.build @@ -0,0 +1,74 @@ +dwcore_sources = files( + 'findtext.cc', + 'imgrenderer.cc', + 'iterator.cc', + 'layout.cc', + 'selection.cc', + 'stackingcontextmgr.cc', + 'style.cc', + 'tools.cc', + 'types.cc', + 'ui.cc', + 'widget.cc', +) + +dw_fltk_sources = files( + 'fltkcomplexbutton.cc', + 'fltkflatview.cc', + 'fltkimgbuf.cc', + 'fltkmisc.cc', + 'fltkplatform.cc', + 'fltkpreview.cc', + 'fltkui.cc', + 'fltkviewbase.cc', + 'fltkviewport.cc', +) + +dw_widgets_sources = files( + 'alignedtablecell.cc', + 'alignedtextblock.cc', + 'bullet.cc', + 'hyphenator.cc', + 'image.cc', + 'listitem.cc', + 'oofawarewidget.cc', + 'oofawarewidget_iterator.cc', + 'ooffloatsmgr.cc', + 'oofposabslikemgr.cc', + 'oofposabsmgr.cc', + 'oofposfixedmgr.cc', + 'oofpositionedmgr.cc', + 'oofposrelmgr.cc', + 'outofflowmgr.cc', + 'regardingborder.cc', + 'ruler.cc', + 'simpletablecell.cc', + 'table.cc', + 'table_iterator.cc', + 'tablecell.cc', + 'textblock.cc', + 'textblock_iterator.cc', + 'textblock_linebreaking.cc', +) + +dwcore = static_library( + 'dwcore', + sources: dwcore_sources, + include_directories: incdir, +) + +dw_fltk = static_library( + 'dw_fltk', + sources: dw_fltk_sources, + # libDw_fltk_a_CXXFLAGS = @LIBFLTK_CXXFLAGS@ + include_directories: [fltk_include_dirs, incdir], +) + +dw_widgets = static_library( + 'dw_widgets', + sources: dw_widgets_sources, + include_directories: incdir, + link_with: liblout, +) + +dillo_libs += [dwcore, dw_fltk, dw_widgets] diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..6b36d302 --- /dev/null +++ b/meson.build @@ -0,0 +1,354 @@ +project( + 'dillo', + 'cpp', + 'c', + version: '3.1.1', + license: 'GPL-3.0-or-later', + meson_version: '>= 1.1.0', # meson.options + default_options: [ + 'c_std=c11', + 'cpp_std=c++11', + 'warning_level=everything', + 'werror=false', + ], +) + +host = host_machine.system() +cxx = meson.get_compiler('cpp') +cc = meson.get_compiler('c') +exe_suffix = host_machine.system() == 'windows' ? 'exe' : '' + +incdir = include_directories('.') + +if cxx.get_id() == 'gcc' or cxx.get_id() == 'clang' + add_project_arguments( + '-Wno-unused-parameter', + '-fno-exceptions', + '-D_POSIX_C_SOURCE=200112L', + language: 'c', + ) + add_project_arguments( + '-Wno-unused-parameter', + '-fno-rtti', + '-fno-exceptions', + '-D_POSIX_C_SOURCE=200112L', + language: 'cpp', + ) +endif + +conf = configuration_data() + +# Some basic defines upfront, we'll do the rest right before we configure_file +conf.set_quoted('VERSION', meson.project_version()) +# TODO: This is -DDILLO_BINDIR why? +conf.set_quoted('DILLO_BINDIR', get_option('prefix') / get_option('bindir')) +conf.set_quoted( + 'DILLO_DOCDIR', + get_option('prefix') / get_option('datadir') / 'doc' / meson.project_name(), +) +conf.set_quoted( + 'DILLO_LIBDIR', + get_option('prefix') / get_option('libdir') / meson.project_name(), +) +conf.set_quoted( + 'DILLO_SYSCONF', + get_option('prefix') / get_option('sysconfdir') / meson.project_name(), +) +conf.set_quoted('DPIDRC_SYS', get_option('sysconfdir') / 'dpidrc') +conf.set_quoted('EXEEXT', exe_suffix) +conf.set_quoted('PACKAGE', meson.project_name()) + +################### +# Function checks # +################### + +functions = [] + +# 'aix' isn't actually supported by meson, but we'll check for it anyway +if host == 'sunos' or host == 'aix' + functions = ['gethostbyname', 'setsockopt'] + foreach func : functions + if not cc.has_function(func) + error(f'Function @func@ not found') + endif + endforeach +endif + +########### +# Headers # +########### + +# Check for socklen_t (in Unix98) +if host_machine.system() == 'windows' + socket_header = 'ws2tcpip.h' +else + socket_header = 'sys/socket.h' +endif + +if not cc.has_header_symbol(socket_header, 'socklen_t') + code = f''' +#include +#include <@socket_header@> +int accept(int, struct sockaddr *, size_t *); +int main() {} +''' + if cc.compiles(code, name: 'socklen_t is size_t') + conf.set('socklen_t', 'size_t') + else + conf.set('socklen_t', 'int') + endif +endif + +################ +# Dependencies # +################ + +all_deps = [] +dillo_deps = [] + +# fltk is a nightmare. Since 2009 they've been 'considering' pkg-config support +# but even though they have most of the pieces in place nobody has bothered to implement +# Thanks to Eli Schwartz for the following: +fltk_config = find_program('fltk-config') +fltk_include_dirs = run_command( + fltk_config, + '--includedir', + check: true, +).stdout().strip().split() +fltk_cxxflags = run_command( + fltk_config, + '--cxxflags', + check: true, +).stdout().strip().split() +#fltk_link_args = run_command(fltk_config, '--ldflags', '--libs', check: +#true).stdout().strip().split() +# --libs _always_ reports the .a file which means if you're using a shared library +# you'll get a link error. We'll just use --ldflags for now. +fltk_link_args = run_command( + fltk_config, + '--ldflags', + check: true, +).stdout().strip().split() +fltk = declare_dependency( + compile_args: fltk_cxxflags, + include_directories: fltk_include_dirs, + link_args: fltk_link_args, +) + +# iconv has custom lookup functionality; Meson will check for iconv.h and libiconv +iconv = dependency('iconv', required: true) +jpeg = dependency('libjpeg', required: get_option('jpeg')) +png = dependency('libpng', required: get_option('png')) +pthread = dependency('threads', required: get_option('posix-threads')) +zlib = dependency('zlib', required: true) +x11 = dependency('x11', required: false) # This is not needed on some platforms; we should gate or otherwise handle this + +all_deps = [fltk, iconv, jpeg, png, pthread, zlib, x11] + +use_tls = get_option( + 'tls', +).enable_if(get_option('mbedtls') or get_option('openssl')) +if use_tls.enabled() + if get_option('mbedtls') and get_option('openssl') + error('Cannot enable both mbedtls and openssl') + endif + + conf.set10('ENABLE_TLS', true, description: 'Enable TLS support') + + if get_option('openssl') + openssl = dependency('openssl', required: true) + all_deps += [openssl] + conf.set10('HAVE_OPENSSL', true) + elif get_option('mbedtls') + mbedtls = dependency('mbedtls', required: true) + all_deps += [mbedtls] + endif +endif + +### Test Deps: + +efence = dependency('efence', required: get_option('efence')) +gprof = dependency('gprof', required: get_option('gprof')) + +all_deps += [efence, gprof] + +# Rely on meson to die if a required dependency is not found +# Add all 'found' deps to dillo_deps to link against. +foreach dep : all_deps + if dep.found() + dillo_deps += dep + endif +endforeach + +############## +# Misc Logic # +############## + +# Since we tried to keep finding dependencies as tidy as possible we'll explicitly +# do any other checks (and config setting) in one place: here. + +# Legacy autotools would check for old style libiconf and define inbuf_t accordingly; we'll only support new style +conf.set('inbuf_t', 'char') + +if get_option('cookies').disabled() + add_project_arguments('-DDISABLE_COOKIES', language: 'c') + add_project_arguments('-DDISABLE_COOKIES', language: 'cpp') +endif + +if get_option('gif').enabled() + conf.set10('ENABLE_GIF', true, description: 'Enable GIF support') +endif + +if get_option('ipv6').enabled() + # I guess this is C only? + add_project_arguments('-DENABLE_IPV6', language: 'c') +endif + +if jpeg.found() + conf.set10('HAVE_JPEG', true, description: 'Enable JPEG support') +endif + +if png.found() + conf.set10('HAVE_PNG', true, description: 'Enable PNG support') +endif + +if get_option('svg').enabled() + conf.set10('HAVE_SVG', true, description: 'Enable SVG support') +endif + +if get_option('threaded-dns').enabled() + add_project_arguments('-DD_DNS_THREADED', language: 'c') +endif + +if get_option('rtfl').enabled() + add_project_arguments('-DDBG_RTFL', language: 'cpp') +endif + +if get_option('xembed').enabled() + add_project_arguments('-DDISABLE_XEMBED', language: 'cpp') +endif + +# This is a bit more complex; TODO: +# I suspect that those wishing to use insure should set CC and LIBS themselves outside of the build system. +# if test "x$enable_insure" = "xyes" ; then +# CC="insure -Zoi \"compiler $CC\"" +# LIBS="$LIBS -lstdc++-2-libc6.1-1-2.9.0" +# fi + +# These autotools macros existed previously +# check for these and defines them if they're not present +# TODO: For now we'll just jam @include stdint.h into config.h +# AC_TYPE_INT16_T +# AC_TYPE_UINT16_T +# AC_TYPE_INT32_T +# AC_TYPE_UINT32_T +# We may not need this at all; these types have all been mandatory in posix since 2001! + +conf.set('CA_CERTS_DIR', get_option('ca-certs-dir')) +conf.set('CA_CERTS_FILE', get_option('ca-certs-file')) + +configure_file( + output: 'config.h', + configuration: conf, +) + +############ +# Subdirs! # +############ + +# SUBDIRS = lout dw dlib dpip src doc dpid dpi test + +# We store internal static libs here to link against in the main executable +dillo_libs = [] + +# We could some of these small libs, but honestly it's so small it's not worth it. +dlib = static_library('dlib', sources: files('dlib/dlib.c')) + +liblout_files = files( + 'lout/container.cc', + 'lout/debug.hh', + 'lout/identity.cc', + 'lout/misc.cc', + 'lout/object.cc', + 'lout/signal.cc', + 'lout/unicode.cc', +) + +liblout = static_library( + 'liblout', + sources: liblout_files, + include_directories: incdir, +) + +dpip = static_library( + 'dpip', + sources: files('dpip/dpip.c'), + include_directories: incdir, +) + +dillo_libs += [dlib, dpip, liblout] + +subdir('dpi') + +subdir('dw') +subdir('src') + +subdir('dpid') + +################## +# Config Summary # +################## + +summary( + { + 'Build': build_machine.system(), + 'Build CPU Family': build_machine.cpu_family(), + 'Host CPU Family': host_machine.cpu_family(), + 'Cross-compiling': meson.is_cross_build(), + 'Build Endianness': build_machine.endian(), + 'Host Endianness': host_machine.endian(), + 'Target': host, + 'C Compiler': cc.get_id(), + 'C Compiler Version': cc.version(), + 'Linker': cc.get_linker_id(), + }, + section: 'Environment', +) + +featurevals = { + 'TLS': use_tls.enabled(), +} + +if use_tls.enabled() + if openssl.found() + featurevals += {'TLS Library': openssl} + elif mbedtls.found() + featurevals += {'TLS Library': mbedtls} + endif +endif + +featurevals += { + 'Cookies': get_option('cookies').enabled(), + 'GIF': get_option('gif').enabled(), + 'JPEG': jpeg.found() ? jpeg : false, + 'PNG': png.found() ? png : false, + 'SVG': get_option('svg').enabled(), + 'XEmbed': get_option('xembed').enabled(), +} + +summary( + featurevals, + bool_yn: true, + section: 'Features', +) + +summary( + { + 'Electric Fence': efence.found() ? efence : false, + 'gprof': gprof.found() ? gprof : false, + 'RTFL': get_option('rtfl').enabled(), + 'HTML tests': get_option('html-tests').enabled(), + }, + bool_yn: true, + section: 'Test and Debugging', +) diff --git a/meson.options b/meson.options new file mode 100644 index 00000000..e8f32d54 --- /dev/null +++ b/meson.options @@ -0,0 +1,84 @@ +option( + 'ca-certs-dir', + type: 'string', + description: 'Specify where to find a directory containing trusted CA certificates for TLS', +) +option( + 'ca-certs-file', + type: 'string', + description: 'Specify where to find a bundle of trusted CA certificates for TLS', +) +option( + 'cookies', + type: 'feature', + value: 'enabled', + description: 'Enable cookie support', +) +option('gif', type: 'feature', value: 'auto', description: 'Enable gif support') +option('ipv6', type: 'feature', value: 'enabled', description: 'IPv6 support') # There is rarely a reason to disable this +option( + 'jpeg', + type: 'feature', + value: 'auto', + description: 'Enable jpeg support', +) +option('png', type: 'feature', value: 'auto', description: 'Enable png support') +option( + 'posix-threads', + type: 'feature', + value: 'auto', + description: 'Enable POSIX thread support', +) +option('svg', type: 'feature', value: 'auto', description: 'Enable svg support') +option( + 'threaded-dns', + type: 'feature', + value: 'enabled', + description: 'Enable threaded DNS support', +) +option( + 'tls', + type: 'feature', + value: 'enabled', + description: 'Enable TLS support', +) # Default to enabling tls +option('mbedtls', type: 'boolean', value: false, description: 'TLS via mbedTLS') +option('openssl', type: 'boolean', value: true, description: 'TLS via OpenSSL') +option( + 'xembed', + type: 'feature', + value: 'enabled', + description: 'Enable XEmbed support', +) + +# Testing, safety, and debugging options +option( + 'efence', + type: 'feature', + value: 'disabled', + description: 'Enable Electric Fence support', +) +option( + 'gprof', + type: 'feature', + value: 'disabled', + description: 'Enable gprof support', +) +option( + 'html-tests', + type: 'feature', + value: 'disabled', + description: 'Enable HTML tests (requires xvfb, xwd and imagemagick)', +) +# option( +# 'insure', +# type: 'boolean', +# value: false, +# description: 'Enable Insure++ support', +# ) +option( + 'rtfl', + type: 'feature', + value: 'disabled', + description: 'Print low-level RTFL messages for debugging the renderer (very large slowdown)', +) diff --git a/src/IO/meson.build b/src/IO/meson.build new file mode 100644 index 00000000..fad34179 --- /dev/null +++ b/src/IO/meson.build @@ -0,0 +1,28 @@ +libdio_sources = files( + 'IO.c', + 'Url.h', + 'about.c', + 'dpi.c', + 'http.c', + 'iowatch.cc', + 'mime.c', + 'tls.c', +) + +# TODO: What's supposed to happen here if tls isn't enabled? What does tls.c do then? +if get_option('tls').enabled() + if get_option('mbedtls') + libdio_sources += files('tls_mbedtls.c') + elif get_option('openssl') + libdio_sources += files('tls_openssl.c') + endif +endif + +libdio = static_library( + 'libdio', + sources: libdio_sources, + include_directories: [incdir, fltk_include_dirs], + link_with: dpip, +) + +dillo_libs += libdio diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..a2dc13d9 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,71 @@ +subdir('IO') + +dillo_files = files( + 'auth.c', + 'bitvec.c', + 'bookmark.c', + 'bw.c', + 'cache.c', + 'capi.c', + 'chain.c', + 'colors.c', + 'cookies.c', + 'css.cc', + 'cssparser.cc', + 'decode.c', + 'dialog.cc', + 'dicache.c', + 'digest.c', + 'dillo.cc', + 'dns.c', + 'domain.c', + 'dpiapi.c', + 'findbar.cc', + 'form.cc', + 'gif.c', + 'history.c', + 'hsts.c', + 'html.cc', + 'image.cc', + 'imgbuf.cc', + 'jpeg.c', + 'keys.cc', + 'klist.c', + 'md5.c', + 'menu.cc', + 'misc.c', + 'nav.c', + 'paths.cc', + 'plain.cc', + 'png.c', + 'prefs.c', + 'prefsparser.cc', + 'styleengine.cc', + 'svg.c', + 'table.cc', + 'timeout.cc', + 'tipwin.cc', + 'ui.cc', + 'uicmd.cc', + 'url.c', + 'utf8.cc', + 'web.cc', + 'xembed.cc', +) + +executable( + 'dillo', + sources: dillo_files, + dependencies: dillo_deps, + include_directories: [incdir, fltk_include_dirs], + install: true, + link_with: dillo_libs, +) + +sysconf_files = files( + 'domainrc', + 'hsts_preload', + 'keysrc', +) + +install_data(sysconf_files, install_dir: get_option('sysconfdir'))