[gtkmm/use-dllexport: 43/60] Add support for building gtkmm with Meson
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm/use-dllexport: 43/60] Add support for building gtkmm with Meson
- Date: Mon, 8 Jun 2020 02:45:37 +0000 (UTC)
commit e4f49de0d57be395cb3681e7fb2237292184032c
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Tue Jun 2 18:57:37 2020 +0200
Add support for building gtkmm with Meson
gtkmm-4.0 can be built with either Autotools or Meson.
New files have been copied from gtkmm-3.0 and modified.
See MR !27
MSVC_NMake/gdkmm/meson.build | 11 +
MSVC_NMake/gendef/meson.build | 9 +
MSVC_NMake/gtkmm/meson.build | 17 ++
Makefile.am | 20 ++
demos/gtk-demo/meson.build | 53 ++++
docs/reference/meson.build | 173 +++++++++++++
gdk/gdkmm/meson.build | 271 ++++++++++++++++++++
gdk/gdkmmconfig.h.meson | 18 ++
gdk/meson.build | 53 ++++
gtk/gtkmm/meson.build | 526 +++++++++++++++++++++++++++++++++++++++
gtk/gtkmmconfig.h.meson | 43 ++++
gtk/meson.build | 29 +++
meson.build | 358 ++++++++++++++++++++++++++
meson_options.txt | 16 ++
tests/meson.build | 61 +++++
tools/dummy-header.py | 15 ++
tools/extra_defs_gen/meson.build | 35 +++
untracked/README | 40 +++
18 files changed, 1748 insertions(+)
---
diff --git a/MSVC_NMake/gdkmm/meson.build b/MSVC_NMake/gdkmm/meson.build
new file mode 100644
index 00000000..849157b9
--- /dev/null
+++ b/MSVC_NMake/gdkmm/meson.build
@@ -0,0 +1,11 @@
+# MSVC_NMake/gdkmm
+
+# Input: gdkmmconfig_h
+# Output: -
+
+# Copy the generated configuration header into the MSVC project directory.
+configure_file(
+ input: gdkmmconfig_h,
+ output: 'gdkmmconfig.h',
+ copy: true,
+)
diff --git a/MSVC_NMake/gendef/meson.build b/MSVC_NMake/gendef/meson.build
new file mode 100644
index 00000000..32babb7d
--- /dev/null
+++ b/MSVC_NMake/gendef/meson.build
@@ -0,0 +1,9 @@
+# MSVC_NMake/gendef
+
+# Input: is_msvc
+# Output: gendef
+
+# Used to generate the .def file required to obtain the import .lib file
+if is_msvc
+ gendef = executable('gendef', 'gendef.cc', install: false,)
+endif
diff --git a/MSVC_NMake/gtkmm/meson.build b/MSVC_NMake/gtkmm/meson.build
new file mode 100644
index 00000000..a68c8fa8
--- /dev/null
+++ b/MSVC_NMake/gtkmm/meson.build
@@ -0,0 +1,17 @@
+# MSVC_NMake/gtkmm
+
+# Input: pkg_conf_data, gtkmmconfig_h
+# Output: gtkmm_rc
+
+gtkmm_rc = configure_file(
+ input: 'gtkmm.rc.in',
+ output: '@BASENAME@',
+ configuration: pkg_conf_data,
+)
+
+# Copy the generated configuration header into the MSVC project directory.
+configure_file(
+ input: gtkmmconfig_h,
+ output: 'gtkmmconfig.h',
+ copy: true,
+)
diff --git a/Makefile.am b/Makefile.am
index 713e2b91..f94f297d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -55,5 +55,25 @@ dist_noinst_SCRIPTS = autogen.sh
DISTCLEANFILES = $(filter %mmconfig.h,$(msvc_files)) win32_installer/lgpl.txt
+# Distribute files needed when building gtkmm with Meson.
+EXTRA_DIST = \
+ meson.build \
+ meson_options.txt \
+ MSVC_NMake/gendef/meson.build \
+ MSVC_NMake/gdkmm/meson.build \
+ MSVC_NMake/gtkmm/meson.build \
+ demos/gtk-demo/meson.build \
+ docs/reference/meson.build \
+ gdk/meson.build \
+ gdk/gdkmmconfig.h.meson \
+ gdk/gdkmm/meson.build \
+ gtk/meson.build \
+ gtk/gtkmmconfig.h.meson \
+ gtk/gtkmm/meson.build \
+ tests/meson.build \
+ tools/dummy-header.py \
+ tools/extra_defs_gen/meson.build \
+ untracked/README
+
# Optional: auto-generate the ChangeLog file from the git log on make dist
include $(top_srcdir)/build/dist-changelog.am
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
new file mode 100644
index 00000000..c1510995
--- /dev/null
+++ b/demos/gtk-demo/meson.build
@@ -0,0 +1,53 @@
+# demos/gtk-demo
+
+# Input: gtkmm_dep, epoxy_dep, build_demos, gui_app_ldflags, gtkmm_extra_gendef_cpp_args
+# Output: -
+
+gtkmm_demo_cc_files = [
+ 'main.cc',
+ 'demowindow.cc',
+ 'textwidget.cc',
+ 'example_appwindow.cc',
+ 'example_builder.cc',
+ 'example_colorsel.cc',
+ 'example_dialog.cc',
+ 'example_drawingarea.cc',
+ 'example_flowbox.cc',
+ 'example_gestures.cc',
+ 'example_glarea.cc',
+ 'example_headerbar.cc',
+ 'example_iconbrowser.cc',
+ 'example_iconview.cc',
+ 'example_images.cc',
+ 'example_overlay.cc',
+ 'example_panes.cc',
+ 'example_pixbufs.cc',
+ 'example_shortcuts.cc',
+ 'example_sizegroup.cc',
+ 'example_stack.cc',
+ 'example_stacksidebar.cc',
+ 'example_textview.cc',
+ 'example_treeview_editable_cells.cc',
+ 'example_treeview_liststore.cc',
+ 'example_treeview_treestore.cc',
+]
+
+gnome = import('gnome')
+
+if epoxy_dep.found()
+ demo_resources = gnome.compile_resources('demo-resources',
+ 'demo.gresource.xml',
+ source_dir: meson.current_source_dir(),
+ install: false,
+ )
+
+ executable('gtkmm-demo',
+ gtkmm_demo_cc_files, demo_resources,
+ dependencies: [gtkmm_dep, epoxy_dep],
+ gui_app: true,
+ build_by_default: build_demos,
+ link_args: gui_app_ldflags,
+ cpp_args: gtkmm_extra_gendef_cpp_args,
+ install: false,
+ )
+endif
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
new file mode 100644
index 00000000..241aa23f
--- /dev/null
+++ b/docs/reference/meson.build
@@ -0,0 +1,173 @@
+# docs/reference
+
+# Input: built_files_root, project_source_root, gdkmm_pcname, gtkmm_pcname,
+# gdkmm_hg_ccg_basenames, gtkmm_hg_ccg_basenames, gdkmm_extra_h_files,
+# gtkmm_extra_h_files, gdkmm_built_h_file_targets,
+# gtkmm_built_h_file_targets, install_datadir, python3,
+# doc_reference_py, build_documentation
+# Output: install_docdir, install_devhelpdir
+
+tag_file_modules = [
+ 'mm-common-libstdc++',
+ 'sigc++-3.0',
+ 'glibmm-2.66',
+ 'cairomm-1.16',
+ 'pangomm-2.44',
+ 'atkmm-2.30',
+]
+doxygen_tagfiles = ''
+docinstall_flags = []
+foreach module : tag_file_modules
+ depmod = dependency(module, required: false)
+ if depmod.found()
+ doxytagfile = depmod.get_pkgconfig_variable('doxytagfile')
+ htmlrefpub = depmod.get_pkgconfig_variable('htmlrefpub', default: '')
+ htmlrefdir = depmod.get_pkgconfig_variable('htmlrefdir', default: '')
+ if htmlrefpub == ''
+ htmlrefpub = htmlrefdir
+ elif htmlrefdir == ''
+ htmlrefdir = htmlrefpub
+ endif
+ doxygen_tagfiles += ' "' + doxytagfile + '=' + htmlrefpub + '"'
+ if not htmlrefdir.endswith('/')
+ htmlrefdir += '/'
+ endif
+ docinstall_flags += ['-l', doxytagfile.split('/')[-1] + '@' + htmlrefdir]
+ endif
+endforeach
+
+book_name = gtkmm_pcname
+book_title = meson.project_name() + ' Reference Manual'
+
+# Configuration data for Doxyfile.
+doc_conf_data = configuration_data()
+doc_conf_data.set('configure_input',
+ 'docs/reference/Doxyfile. Generated from Doxyfile.in by meson.configure_file().')
+doc_conf_data.set('PACKAGE_NAME', meson.project_name())
+doc_conf_data.set('PACKAGE_VERSION', meson.project_version())
+doc_conf_data.set('abs_top_builddir', built_files_root)
+doc_conf_data.set('abs_top_srcdir', project_source_root)
+doc_conf_data.set('GTKMM_MODULE_NAME', book_name)
+doc_conf_data.set('DOXYGEN_TAGFILES', doxygen_tagfiles)
+
+configure_file(
+ input: 'Doxyfile.in',
+ output: '@BASENAME@',
+ configuration: doc_conf_data,
+)
+
+# Installation directories relative to {prefix}.
+install_docdir = install_datadir / 'doc' / book_name
+install_reference_docdir = install_docdir / 'reference'
+install_image_docdir = install_docdir / 'images'
+install_devhelpdir = install_datadir / 'devhelp' / 'books' / book_name
+
+if not build_documentation
+ # Documentation shall not be built or installed.
+ # Return to the calling meson.build file.
+ subdir_done()
+endif
+
+# Built input .h files to Doxygen.
+built_h_files = []
+foreach file : gdkmm_hg_ccg_basenames
+ built_h_files += built_files_root / 'gdk' / 'gdkmm' / file + '.h'
+endforeach
+foreach file : gtkmm_hg_ccg_basenames
+ built_h_files += built_files_root / 'gtk' / 'gtkmm' / file + '.h'
+endforeach
+
+# Hand-coded input .h files to Doxygen.
+src_h_files = []
+foreach file : gdkmm_extra_h_files
+ if file != 'wrap_init.h'
+ src_h_files += project_source_root / 'gdk' / 'gdkmm' / file
+ endif
+endforeach
+foreach file : gtkmm_extra_h_files
+ if file != 'wrap_init.h'
+ src_h_files += project_source_root / 'gtk' / 'gtkmm' / file
+ endif
+endforeach
+src_h_files += project_source_root / 'gdk' / 'gdkmm.h'
+src_h_files += project_source_root / 'gtk' / 'gtkmm.h'
+
+doctool_dir = project_source_root / 'untracked' / 'docs' # MMDOCTOOLDIR
+doctool_dist_dir = 'untracked' / 'docs' # Relative to MESON_DIST_ROOT
+
+doc_h_files = src_h_files
+if gdkmm_built_h_file_targets.length() + gtkmm_built_h_file_targets.length() > 0
+ # .h files have been generated from .hg files (maintainer mode).
+ # Use built_h_file_targets instead of built_h_files here, or else Meson won't
+ # know that Doxygen must not be executed until the .h files have been built.
+ doc_h_files += gdkmm_built_h_file_targets + gtkmm_built_h_file_targets
+else
+ # All .h files are stored in the source tree (not maintainer mode).
+ doc_h_files += built_h_files
+endif
+
+# Can't use @INPUT@ in the command. It requires absolute file paths.
+# Paths in built_h_file_targets are relative to project_build_root.
+tag_file = custom_target('html_and_tag',
+ input: doc_h_files,
+ output: book_name + '.tag',
+ command: [
+ python3, doc_reference_py, 'doxygen',
+ doctool_dir,
+ '@OUTPUT@',
+ src_h_files,
+ built_h_files,
+ ],
+ build_by_default: build_documentation,
+ install: true,
+ install_dir: install_reference_docdir,
+)
+
+devhelp_file = custom_target('devhelp',
+ input: tag_file,
+ output: book_name + '.devhelp2',
+ command: [
+ python3, doc_reference_py, 'devhelp',
+ doctool_dir,
+ '@INPUT@',
+ '@OUTPUT@',
+ book_name,
+ book_title,
+ ],
+ build_by_default: build_documentation,
+)
+
+# Install Devhelp file and html files.
+meson.add_install_script(
+ python3.path(), doc_reference_py, 'install_doc',
+ doctool_dir,
+ devhelp_file.full_path(),
+ install_devhelpdir,
+ install_reference_docdir / 'html',
+ docinstall_flags
+)
+
+# Install images.
+image_basefiles = [
+ 'gtkmm_logo.gif',
+ 'top.gif',
+]
+image_files = []
+foreach file : image_basefiles
+ image_files += '..' / 'images' / file
+endforeach
+
+install_data(image_files, install_dir: install_image_docdir)
+
+if not meson.is_subproject()
+ # Distribute built files and files copied by mm-common-get.
+ # (add_dist_script() is not allowed in a subproject)
+ meson.add_dist_script(
+ python3.path(), doc_reference_py, 'dist_doc',
+ doctool_dir,
+ doctool_dist_dir,
+ meson.current_build_dir(),
+ tag_file.full_path(),
+ devhelp_file.full_path(),
+ )
+endif
diff --git a/gdk/gdkmm/meson.build b/gdk/gdkmm/meson.build
new file mode 100644
index 00000000..293dc928
--- /dev/null
+++ b/gdk/gdkmm/meson.build
@@ -0,0 +1,271 @@
+# gdk/gdkmm
+
+# Input: gdkmm_build_dep, gtkmm_pcname, maintainer_mode, project_source_root,
+# generate_binding_py, m4_files, install_includedir, python3,
+# dummy_header_py, gmmproc_dir, build_deprecated_api,
+# gmmproc_extra_m4_dirs, gdkmm_extra_gendef_cpp_args
+# Output: gdkmm_hg_ccg_basenames, gdkmm_extra_h_files, built_files_root,
+# gdkmm_built_h_file_targets, gdkmm_used_built_h_file_targets,
+# gdkmm_library
+
+gdkmm_defs_basefiles = [
+ 'gdk.defs',
+ 'gdk_enums.defs',
+ 'gdk_extra.defs',
+ 'gdk_extra_objects.defs',
+ 'gdk_methods.defs',
+ 'gdk_pixbuf_enums.defs',
+ 'gdk_pixbuf_methods.defs',
+ 'gdk_signals.defs',
+ 'gdk_vfuncs.defs',
+ 'gdk_docs.xml',
+ 'gdk_docs_override.xml',
+]
+
+gdkmm_defs_files = []
+foreach file : gdkmm_defs_basefiles
+ gdkmm_defs_files += '..' / 'src' / file
+endforeach
+
+# Generated from pairs of .hg and .ccg files.
+gdkmm_any_hg_ccg_basenames = [
+ 'applaunchcontext',
+ 'cairocontext',
+ 'clipboard',
+ 'contentformats',
+ 'contentformatsbuilder',
+ 'contentprovider',
+ 'cursor',
+ 'device',
+ 'devicepad',
+ 'devicetool',
+ 'display',
+ 'displaymanager',
+ 'drag',
+ 'dragsurface',
+ 'drawcontext',
+ 'drop',
+ 'enums',
+ 'event',
+ 'frameclock',
+ 'frametimings',
+ 'glcontext',
+ 'gltexture',
+ 'monitor',
+ 'paintable',
+ 'pixbuf',
+ 'pixbufanimation',
+ 'pixbufanimationiter',
+ 'pixbufformat',
+ 'pixbufloader',
+ 'popup',
+ 'popuplayout',
+ 'rectangle',
+ 'rgba',
+ 'seat',
+ 'snapshot',
+ 'surface',
+ 'texture',
+ 'timecoord',
+ 'toplevel',
+ 'toplevellayout',
+ 'types',
+]
+
+gdkmm_deprecated_hg_ccg_basenames = []
+
+# Pairs of hand-coded .h and .cc files.
+gdkmm_extra_any_h_cc_basenames = [
+ 'cairoutils',
+ 'devicewithpad',
+ 'general',
+ 'value_cairo',
+]
+
+gdkmm_extra_cc_files = []
+
+gdkmm_extra_h_files = [
+ 'wrap_init.h',
+]
+
+# All .hg/.ccg files, regardless of deprecation.
+gdkmm_hg_ccg_basenames = \
+ gdkmm_any_hg_ccg_basenames + \
+ gdkmm_deprecated_hg_ccg_basenames
+
+# Used .hg/.ccg files in the present build.
+gdkmm_used_hg_ccg_basenames = gdkmm_any_hg_ccg_basenames
+if build_deprecated_api
+ gdkmm_used_hg_ccg_basenames += gdkmm_deprecated_hg_ccg_basenames
+endif
+
+foreach file : gdkmm_extra_any_h_cc_basenames
+ gdkmm_extra_h_files += file + '.h'
+ gdkmm_extra_cc_files += file + '.cc'
+endforeach
+
+install_headers('..' / 'gdkmm.h', subdir: gtkmm_pcname)
+install_headers(gdkmm_extra_h_files, subdir: gtkmm_pcname / 'gdkmm')
+
+untracked_gdkmm = 'untracked' / 'gdk' / 'gdkmm'
+src_untracked_gdkmm = project_source_root / untracked_gdkmm
+
+gdkmm_cpp_args = [ '-DGDKMM_BUILD=1' ] + gdkmm_extra_gendef_cpp_args
+
+if maintainer_mode
+
+ # Maintainer mode. Generate .h and .cc files from .hg and .ccg files in ../src.
+
+ # docs/reference/meson.build needs these.
+ built_files_root = project_build_root
+ gdkmm_built_h_file_targets = []
+
+ # Force meson+ninja to generate source files before anything is compiled.
+ # Compilation must depend on these targets.
+ gdkmm_used_built_cc_file_targets = []
+ gdkmm_used_built_h_file_targets = []
+
+ hg_files = []
+ foreach file : gdkmm_hg_ccg_basenames
+ hg_files += '..' / 'src' / file + '.hg'
+ endforeach
+
+ # Create wrap_init.cc in project_build_root/gdk/gdkmm.
+ gdkmm_used_built_cc_file_targets += custom_target('gdkmm-wrap_init.cc',
+ input: hg_files,
+ output: 'wrap_init.cc',
+ command: [
+ python3, generate_binding_py, 'generate_wrap_init',
+ gmmproc_dir,
+ '@OUTPUT@',
+ 'Gdk', # namespace
+ '@INPUT@',
+ ],
+ build_by_default: maintainer_mode,
+ install: false,
+ )
+
+ # Create .h/_p.h/.cc files in project_build_root/gdk/gdkmm
+ # from .hg/.ccg files in project_source_root/gdk/src.
+ foreach file : gdkmm_hg_ccg_basenames
+ hg_file = '..' / 'src' / file + '.hg'
+ ccg_file = '..' / 'src' / file + '.ccg'
+ built_file_target = custom_target('gdkmm-' + file + '.cc',
+ input: [hg_file, ccg_file],
+ output: [file + '.stamp', file + '.cc', file + '.h'],
+ command: [
+ python3, generate_binding_py, 'gmmproc',
+ gmmproc_dir,
+ '@OUTPUT0@',
+ file,
+ meson.current_source_dir() / '..' / 'src',
+ project_source_root / 'tools' / 'm4',
+ gmmproc_extra_m4_dirs,
+ ],
+ depend_files: gdkmm_defs_files + m4_files,
+ build_by_default: maintainer_mode,
+ install: false,
+ )
+ gdkmm_built_h_file_targets += built_file_target[2]
+ if gdkmm_used_hg_ccg_basenames.contains(file)
+ gdkmm_used_built_cc_file_targets += built_file_target[1]
+ gdkmm_used_built_h_file_targets += built_file_target[2]
+ endif
+ endforeach
+
+ # Create dummy_header.h, depending on all generated headers.
+ # It's created if it does not exist, but it's never updated.
+ # It guarantees that all generated headers are built before gdkmm_library
+ # is built, at the same time avoiding unnecessary recompilations.
+ # If gdkmm_used_built_h_file_targets would be listed as sources to gdkmm_library,
+ # all generated .cc files could be recompiled if one generated .h file has
+ # been changed.
+ built_dummy_h_file_target = custom_target('gdkmm-dummy_header.h',
+ input: gdkmm_used_built_h_file_targets,
+ output: 'dummy_header.h',
+ command: [
+ python3, dummy_header_py,
+ '@OUTPUT@',
+ ],
+ build_by_default: maintainer_mode,
+ install: false,
+ )
+
+ extra_include_dirs = ['..']
+
+ gdk_gen_sources = gdkmm_used_built_cc_file_targets
+
+ built_h_cc_dir = meson.current_build_dir()
+
+else # not maintainer_mode
+
+ # Not maintainer mode. Compile built source code files in
+ # project_source_root/untracked/gdk/gdkmm.
+
+ gdkmm_used_built_h_file_targets = []
+
+ # docs/reference/meson.build needs these.
+ built_files_root = project_source_root / 'untracked'
+ gdkmm_built_h_file_targets = []
+
+ # Two cases:
+ # 1. The source code comes from a tarball, where the built files
+ # are stored in project_source_root/untracked.
+ # There are no built files in the build tree.
+ # 2. Files have been built in the build tree. Then maintainer_mode has
+ # been changed from true to false. Files that are missing or not up to date
+ # in project_source_root/untracked are copied from the build tree.
+
+ # Try to copy built source code files to the source tree.
+ run_command(
+ python3, generate_binding_py, 'copy_built_files',
+ meson.current_build_dir(),
+ src_untracked_gdkmm,
+ gdkmm_hg_ccg_basenames,
+ )
+
+ built_cc_files = [ src_untracked_gdkmm / 'wrap_init.cc' ]
+ foreach file : gdkmm_used_hg_ccg_basenames
+ built_cc_files += src_untracked_gdkmm / file + '.cc'
+ endforeach
+
+ gdk_gen_sources = built_cc_files
+ built_dummy_h_file_target = []
+
+ extra_include_dirs = [ '..', '..' / '..' / 'untracked' / 'gdk' ]
+
+ built_h_cc_dir = src_untracked_gdkmm
+
+endif
+
+# This is an internal static library.
+# The objects in this library will be included in gtkmm_library.
+gdkmm_library = static_library('gdkmm',
+ gdk_gen_sources, built_dummy_h_file_target, gdkmm_extra_cc_files,
+ include_directories: extra_include_dirs,
+ cpp_args: gdkmm_cpp_args,
+ dependencies: gdkmm_build_dep,
+ install: false,
+)
+
+# Install built .h and _p.h files.
+meson.add_install_script(
+ python3.path(), generate_binding_py, 'install_built_h_files',
+ built_h_cc_dir,
+ install_includedir / gtkmm_pcname / 'gdkmm', # subdir below {prefix}
+ gdkmm_used_hg_ccg_basenames
+)
+
+if not meson.is_subproject()
+ # Distribute built files.
+ # (add_dist_script() is not allowed in a subproject)
+ meson.add_dist_script(
+ python3.path(), generate_binding_py, 'dist_built_files',
+ built_h_cc_dir,
+ untracked_gdkmm,
+ gdkmm_hg_ccg_basenames,
+ )
+endif
+
+# We don't define gdkmm_dep = declare_dependency() with gdkmm_library,
+# which is an internal library.
diff --git a/gdk/gdkmmconfig.h.meson b/gdk/gdkmmconfig.h.meson
new file mode 100644
index 00000000..872cc8b1
--- /dev/null
+++ b/gdk/gdkmmconfig.h.meson
@@ -0,0 +1,18 @@
+#ifndef _GDKMM_CONFIG_H
+#define _GDKMM_CONFIG_H
+
+#include <pangommconfig.h>
+
+/* Define to omit deprecated API from gdkmm. */
+#mesondefine GDKMM_DISABLE_DEPRECATED
+
+/* Major version number of gdkmm. */
+#mesondefine GDKMM_MAJOR_VERSION
+
+/* Minor version number of gdkmm. */
+#mesondefine GDKMM_MINOR_VERSION
+
+/* Micro version number of gdkmm. */
+#mesondefine GDKMM_MICRO_VERSION
+
+#endif /* !_GDKMM_CONFIG_H */
diff --git a/gdk/meson.build b/gdk/meson.build
new file mode 100644
index 00000000..7ebf3a3e
--- /dev/null
+++ b/gdk/meson.build
@@ -0,0 +1,53 @@
+# gdk
+
+# Input: install_prefix, install_libdir, install_datadir, install_includedir,
+# gtkmm_pcname, gtkmm_api_version, gtkmm_requires, build_deprecated_api,
+# cpp_compiler, gtkmm_major_version, gtkmm_minor_version,
+# gtkmm_micro_version, build_atkmm_api
+# Output: pkg_conf_data, install_gdkmmconfigdir, gdkmmconfig_h
+
+pkg_conf_data = configuration_data()
+pkg_conf_data.set('prefix', install_prefix)
+pkg_conf_data.set('exec_prefix', '${prefix}')
+pkg_conf_data.set('libdir', '${exec_prefix}' / install_libdir)
+pkg_conf_data.set('datarootdir', '${prefix}' / install_datadir)
+pkg_conf_data.set('datadir', '${datarootdir}')
+pkg_conf_data.set('includedir', '${prefix}' / install_includedir)
+pkg_conf_data.set('PACKAGE_TARNAME', meson.project_name())
+pkg_conf_data.set('PACKAGE_VERSION', meson.project_version())
+pkg_conf_data.set('GTKMM_MODULE_NAME', gtkmm_pcname)
+pkg_conf_data.set('GTKMM_API_VERSION', gtkmm_api_version)
+pkg_conf_data.set('GTKMM_MODULES', gtkmm_requires)
+if not build_deprecated_api
+ pkg_conf_data.set('GDKMM_DISABLE_DEPRECATED', 1)
+ pkg_conf_data.set('GTKMM_DISABLE_DEPRECATED', 1)
+endif
+if build_atkmm_api
+ pkg_conf_data.set('GTKMM_ATKMM_ENABLED', 1)
+endif
+pkg_conf_data.set('GDKMM_MAJOR_VERSION', gtkmm_major_version)
+pkg_conf_data.set('GDKMM_MINOR_VERSION', gtkmm_minor_version)
+pkg_conf_data.set('GDKMM_MICRO_VERSION', gtkmm_micro_version)
+pkg_conf_data.set('GTKMM_MAJOR_VERSION', gtkmm_major_version)
+pkg_conf_data.set('GTKMM_MINOR_VERSION', gtkmm_minor_version)
+pkg_conf_data.set('GTKMM_MICRO_VERSION', gtkmm_micro_version)
+
+library_build_type = get_option('default_library')
+
+if cpp_compiler.get_argument_syntax() == 'msvc'
+ if library_build_type == 'static' or library_build_type == 'both'
+ error('Static builds are not supported by MSVC-style builds')
+ endif
+endif
+
+if library_build_type == 'static'
+ pkg_conf_data.set('GTKMM_STATIC_LIB', 1)
+endif
+
+install_gdkmmconfigdir = install_libdir / gtkmm_pcname / 'include'
+gdkmmconfig_h = configure_file(
+ input: 'gdkmmconfig.h.meson',
+ output: 'gdkmmconfig.h',
+ configuration: pkg_conf_data,
+ install_dir: install_gdkmmconfigdir,
+)
diff --git a/gtk/gtkmm/meson.build b/gtk/gtkmm/meson.build
new file mode 100644
index 00000000..4d1e98a2
--- /dev/null
+++ b/gtk/gtkmm/meson.build
@@ -0,0 +1,526 @@
+# gtk/gtkmm
+
+# Input: gtkmm_build_dep, gtkmm_pcname, maintainer_mode, project_source_root,
+# generate_binding_py, m4_files, gtkmm_libversion, install_includedir,
+# python3, gtkmm_rc, dummy_header_py, gmmproc_dir, build_shared_libs_directly,
+# build_deprecated_api, gmmproc_extra_m4_dirs, is_host_windows,
+# gdkmm_library, gdkmm_used_built_h_file_targets, gtkmm_extra_gendef_cpp_args
+# Output: gtkmm_hg_ccg_basenames, gtkmm_extra_h_files, built_files_root,
+# gtkmm_built_h_file_targets, gtkmm_dep
+
+gtkmm_defs_basefiles = [
+ 'gtk.defs',
+ 'gtk_enums.defs',
+ 'gtk_extra_objects.defs',
+ 'gtk_methods.defs',
+ 'gtk_signals.defs',
+ 'gtk_vfuncs.defs',
+ 'gtk_docs.xml',
+ 'gtk_docs_override.xml',
+]
+
+gtkmm_defs_files = []
+foreach file : gtkmm_defs_basefiles
+ gtkmm_defs_files += '..' / 'src' / file
+endforeach
+
+# Generated from pairs of .hg and .ccg files.
+gtkmm_any_hg_ccg_basenames = [
+ 'aboutdialog',
+ 'accellabel',
+ 'actionable',
+ 'actionbar',
+ 'adjustment',
+ 'appchooser',
+ 'appchooserbutton',
+ 'appchooserdialog',
+ 'appchooserwidget',
+ 'application',
+ 'applicationwindow',
+ 'aspectframe',
+ 'assistant',
+ 'assistantpage',
+ 'binlayout',
+ 'border',
+ 'box',
+ 'boxlayout',
+ 'buildable',
+ 'builder',
+ 'button',
+ 'calendar',
+ 'cellarea',
+ 'cellareabox',
+ 'cellareacontext',
+ 'celleditable',
+ 'celllayout',
+ 'cellrenderer',
+ 'cellrendereraccel',
+ 'cellrenderercombo',
+ 'cellrendererpixbuf',
+ 'cellrendererprogress',
+ 'cellrendererspin',
+ 'cellrendererspinner',
+ 'cellrenderertext',
+ 'cellrenderertoggle',
+ 'cellview',
+ 'centerbox',
+ 'centerlayout',
+ 'checkbutton',
+ 'colorbutton',
+ 'colorchooser',
+ 'colorchooserdialog',
+ 'combobox',
+ 'comboboxtext',
+ 'constraint',
+ 'constraintguide',
+ 'constraintlayout',
+ 'constrainttarget',
+ 'csslocation',
+ 'cssprovider',
+ 'csssection',
+ 'dialog',
+ 'dragicon',
+ 'dragsource',
+ 'drawingarea',
+ 'dropcontrollermotion',
+ 'droptarget',
+ 'droptargetasync',
+ 'editable',
+ 'emojichooser',
+ 'entry',
+ 'entrycompletion',
+ 'entrybuffer',
+ 'enums',
+ 'eventcontroller',
+ 'eventcontrollerfocus',
+ 'eventcontrollerkey',
+ 'eventcontrollermotion',
+ 'eventcontrollerscroll',
+ 'expander',
+ 'filechooser',
+ 'filechooserbutton',
+ 'filechooserdialog',
+ 'filechoosernative',
+ 'filechooserwidget',
+ 'filefilter',
+ 'fixed',
+ 'flowbox',
+ 'flowboxchild',
+ 'fontbutton',
+ 'fontchooser',
+ 'fontchooserdialog',
+ 'fontchooserwidget',
+ 'frame',
+ 'gesture',
+ 'gestureclick',
+ 'gesturedrag',
+ 'gesturelongpress',
+ 'gesturepan',
+ 'gesturerotate',
+ 'gesturesingle',
+ 'gesturestylus',
+ 'gestureswipe',
+ 'gesturezoom',
+ 'glarea',
+ 'grid',
+ 'gridlayout',
+ 'gridlayoutchild',
+ 'headerbar',
+ 'iconpaintable',
+ 'icontheme',
+ 'iconview',
+ 'image',
+ 'infobar',
+ 'label',
+ 'layoutchild',
+ 'layoutmanager',
+ 'levelbar',
+ 'linkbutton',
+ 'listbox',
+ 'listboxrow',
+ 'liststore',
+ 'lockbutton',
+ 'main',
+ 'mediacontrols',
+ 'mediafile',
+ 'mediastream',
+ 'menubutton',
+ 'messagedialog',
+ 'native',
+ 'nativedialog',
+ 'noselection',
+ 'notebook',
+ 'notebookpage',
+ 'orientable',
+ 'overlay',
+ 'padactionentry',
+ 'padcontroller',
+ 'pagesetup',
+ 'paned',
+ 'papersize',
+ 'passwordentry',
+ 'picture',
+ 'popover',
+ 'popovermenu',
+ 'popovermenubar',
+ 'printcontext',
+ 'printoperation',
+ 'printoperationpreview',
+ 'printsettings',
+ 'progressbar',
+ 'radiobutton',
+ 'range',
+ 'recentinfo',
+ 'recentmanager',
+ 'requisition',
+ 'revealer',
+ 'root',
+ 'scale',
+ 'scalebutton',
+ 'scrollable',
+ 'scrollbar',
+ 'scrolledwindow',
+ 'searchbar',
+ 'searchentry',
+ 'selectionmodel',
+ 'separator',
+ 'settings',
+ 'shortcutlabel',
+ 'shortcutsgroup',
+ 'shortcutssection',
+ 'shortcutsshortcut',
+ 'shortcutswindow',
+ 'singleselection',
+ 'sizegroup',
+ 'snapshot',
+ 'spinbutton',
+ 'spinner',
+ 'stack',
+ 'stackpage',
+ 'stacksidebar',
+ 'stackswitcher',
+ 'statusbar',
+ 'stylecontext',
+ 'styleprovider',
+ 'switch',
+ 'text',
+ 'textbuffer',
+ 'textchildanchor',
+ 'textiter',
+ 'textmark',
+ 'texttag',
+ 'texttagtable',
+ 'textview',
+ 'togglebutton',
+ 'tooltip',
+ 'treedragdest',
+ 'treedragsource',
+ 'treeiter',
+ 'treemodel',
+ 'treemodelfilter',
+ 'treemodelsort',
+ 'treepath',
+ 'treerowreference',
+ 'treeselection',
+ 'treesortable',
+ 'treestore',
+ 'treeview',
+ 'treeviewcolumn',
+ 'video',
+ 'viewport',
+ 'volumebutton',
+ 'widget',
+ 'widgetpaintable',
+ 'window',
+ 'windowcontrols',
+ 'windowgroup',
+ 'windowhandle',
+]
+
+gtkmm_posix_hg_ccg_basenames = [
+ 'pagesetupunixdialog',
+ 'printer',
+ 'printjob',
+ 'printunixdialog',
+]
+
+gtkmm_deprecated_hg_ccg_basenames = []
+
+# Pairs of hand-coded .h and .cc files.
+gtkmm_extra_any_h_cc_basenames = [
+ 'accelerator',
+ 'accelkey',
+ 'cellrenderer_generation',
+ 'listviewtext',
+ 'object',
+ 'radiobuttongroup',
+ 'treemodelcolumn',
+ 'treeview_private',
+]
+
+gtkmm_extra_deprecated_h_cc_basenames = []
+
+gtkmm_extra_h_files = [
+ 'version.h',
+ 'wrap_init.h',
+]
+
+gtkmm_extra_cc_files = []
+
+gtkmm_extra_ph_files = [
+ 'private' / 'object_p.h',
+]
+
+# All .hg/.ccg files, regardless of deprecation and type of host.
+gtkmm_hg_ccg_basenames = \
+ gtkmm_any_hg_ccg_basenames + \
+ gtkmm_posix_hg_ccg_basenames + \
+ gtkmm_deprecated_hg_ccg_basenames
+
+# Used .hg/.ccg files in the present build.
+gtkmm_used_hg_ccg_basenames = gtkmm_any_hg_ccg_basenames
+if not is_host_windows
+ gtkmm_used_hg_ccg_basenames += gtkmm_posix_hg_ccg_basenames
+endif
+if build_deprecated_api
+ gtkmm_used_hg_ccg_basenames += gtkmm_deprecated_hg_ccg_basenames
+endif
+
+foreach file : gtkmm_extra_any_h_cc_basenames
+ gtkmm_extra_h_files += file + '.h'
+ gtkmm_extra_cc_files += file + '.cc'
+endforeach
+gtkmm_extra_deprecated_h_files = []
+gtkmm_extra_deprecated_cc_files = []
+foreach file : gtkmm_extra_deprecated_h_cc_basenames
+ gtkmm_extra_deprecated_h_files += file + '.h'
+ gtkmm_extra_deprecated_cc_files += file + '.cc'
+endforeach
+gtkmm_extra_used_h_files = gtkmm_extra_h_files
+gtkmm_extra_used_cc_files = gtkmm_extra_cc_files
+gtkmm_extra_h_files += gtkmm_extra_deprecated_h_files
+gtkmm_extra_cc_files += gtkmm_extra_deprecated_cc_files
+if build_deprecated_api
+ gtkmm_extra_used_h_files += gtkmm_extra_deprecated_h_files
+ gtkmm_extra_used_cc_files += gtkmm_extra_deprecated_cc_files
+endif
+
+install_headers('..' / 'gtkmm.h', subdir: gtkmm_pcname)
+install_headers(gtkmm_extra_used_h_files, subdir: gtkmm_pcname / 'gtkmm')
+install_headers(gtkmm_extra_ph_files, subdir: gtkmm_pcname / 'gtkmm' / 'private')
+
+untracked_gtkmm = 'untracked' / 'gtk' / 'gtkmm'
+src_untracked_gtkmm = project_source_root / untracked_gtkmm
+
+gtkmm_cpp_args = [ '-DGTKMM_BUILD=1' ] + gtkmm_extra_gendef_cpp_args
+
+if maintainer_mode
+
+ # Maintainer mode. Generate .h and .cc files from .hg and .ccg files in ../src.
+
+ # docs/reference/meson.build needs these.
+ built_files_root = project_build_root
+ gtkmm_built_h_file_targets = []
+
+ # Force meson+ninja to generate source files before anything is compiled.
+ # Compilation must depend on these targets.
+ gtkmm_used_built_cc_file_targets = []
+ gtkmm_used_built_h_file_targets = []
+
+ hg_files = []
+ foreach file : gtkmm_hg_ccg_basenames
+ hg_files += '..' / 'src' / file + '.hg'
+ endforeach
+
+ # Create wrap_init.cc in project_build_root/gtk/gtkmm.
+ gtkmm_used_built_cc_file_targets += custom_target('gtkmm-wrap_init.cc',
+ input: hg_files,
+ output: 'wrap_init.cc',
+ command: [
+ python3, generate_binding_py, 'generate_wrap_init',
+ gmmproc_dir,
+ '@OUTPUT@',
+ 'Gtk', # namespace
+ '@INPUT@',
+ ],
+ build_by_default: maintainer_mode,
+ install: false,
+ )
+
+ # Create .h/_p.h/.cc files in project_build_root/gtk/gtkmm
+ # from .hg/.ccg files in project_source_root/gtk/src.
+ foreach file : gtkmm_hg_ccg_basenames
+ hg_file = '..' / 'src' / file + '.hg'
+ ccg_file = '..' / 'src' / file + '.ccg'
+ built_file_target = custom_target('gtkmm-' + file + '.cc',
+ input: [hg_file, ccg_file],
+ output: [file + '.stamp', file + '.cc', file + '.h'],
+ command: [
+ python3, generate_binding_py, 'gmmproc',
+ gmmproc_dir,
+ '@OUTPUT0@',
+ file,
+ meson.current_source_dir() / '..' / 'src',
+ project_source_root / 'tools' / 'm4',
+ gmmproc_extra_m4_dirs,
+ ],
+ depend_files: gtkmm_defs_files + m4_files,
+ build_by_default: maintainer_mode,
+ install: false,
+ )
+ gtkmm_built_h_file_targets += built_file_target[2]
+ if gtkmm_used_hg_ccg_basenames.contains(file)
+ gtkmm_used_built_cc_file_targets += built_file_target[1]
+ gtkmm_used_built_h_file_targets += built_file_target[2]
+ endif
+ endforeach
+
+ # Create dummy_header.h, depending on all generated headers.
+ # It's created if it does not exist, but it's never updated.
+ # It guarantees that all generated headers are built before gtkmm_library
+ # is built, at the same time avoiding unnecessary recompilations.
+ # If gtkmm_used_built_h_file_targets would be listed as sources to gtkmm_library,
+ # all generated .cc files could be recompiled if one generated .h file has
+ # been changed.
+ built_dummy_h_file_target = custom_target('gtkmm-dummy_header.h',
+ input: gtkmm_used_built_h_file_targets,
+ output: 'dummy_header.h',
+ command: [
+ python3, dummy_header_py,
+ '@OUTPUT@',
+ ],
+ build_by_default: maintainer_mode,
+ install: false,
+ )
+
+ extra_include_dirs = ['..', '..' / '..' / 'gdk']
+
+ gtk_gen_sources = gtkmm_used_built_cc_file_targets
+
+ built_h_cc_dir = meson.current_build_dir()
+
+else # not maintainer_mode
+
+ # Not maintainer mode. Compile built source code files in
+ # project_source_root/untracked/gtk/gtkmm.
+
+ gtkmm_used_built_h_file_targets = []
+
+ # docs/reference/meson.build needs these.
+ built_files_root = project_source_root / 'untracked'
+ gtkmm_built_h_file_targets = []
+
+ # Two cases:
+ # 1. The source code comes from a tarball, where the built files
+ # are stored in project_source_root/untracked.
+ # There are no built files in the build tree.
+ # 2. Files have been built in the build tree. Then maintainer_mode has
+ # been changed from true to false. Files that are missing or not up to date
+ # in project_source_root/untracked are copied from the build tree.
+
+ # Try to copy built source code files to the source tree.
+ run_command(
+ python3, generate_binding_py, 'copy_built_files',
+ meson.current_build_dir(),
+ src_untracked_gtkmm,
+ gtkmm_hg_ccg_basenames,
+ )
+
+ built_cc_files = [ src_untracked_gtkmm / 'wrap_init.cc' ]
+ foreach file : gtkmm_used_hg_ccg_basenames
+ built_cc_files += src_untracked_gtkmm / file + '.cc'
+ endforeach
+
+ gtk_gen_sources = built_cc_files
+ built_dummy_h_file_target = []
+
+ extra_include_dirs = [ '..', '..' / '..' / 'untracked' / 'gtk',
+ '..' / '..' / 'gdk', '..' / '..' / 'untracked' / 'gdk',
+ ]
+
+ built_h_cc_dir = src_untracked_gtkmm
+
+endif
+
+extra_gtkmm_objects = []
+
+# Build the .rc file for Windows builds and link to it
+if is_host_windows
+ windows = import('windows')
+ gtkmm_res = windows.compile_resources(gtkmm_rc)
+ extra_gtkmm_objects += gtkmm_res
+endif
+
+if build_shared_libs_directly
+ gtkmm_library = library(gtkmm_pcname, extra_gtkmm_objects,
+ gtk_gen_sources, built_dummy_h_file_target, gtkmm_extra_used_cc_files,
+ include_directories: extra_include_dirs,
+ cpp_args: gtkmm_cpp_args,
+ version: gtkmm_libversion,
+ dependencies: gtkmm_build_dep,
+ link_whole: gdkmm_library,
+ install: true,
+ )
+else
+ # Building with headers generated from *.hg files with
+ # gmmproc < 2.64.3 on Visual Studio: We need this so
+ # that we can run gendef.exe to get the .def file
+ # needed for obtaining the .lib file for the gtkmm DLL
+ gtk_int_lib = static_library('gtkmm-int',
+ gtk_gen_sources, built_dummy_h_file_target, gtkmm_extra_used_cc_files,
+ include_directories: extra_include_dirs,
+ cpp_args: gtkmm_cpp_args,
+ dependencies: gtkmm_build_dep,
+ link_with: gdkmm_library,
+ install: false,
+ )
+
+ gtkmm_def = custom_target('gtkmm.def',
+ output: 'gtkmm.def',
+ depends: gtk_int_lib,
+ command: [ gendef,
+ '@OUTPUT@',
+ '@0@-@1@.dll'.format(gtkmm_pcname, gtkmm_libversion.split('.')[0]),
+ gtk_int_lib.full_path(),
+ ],
+ install: false,
+ )
+ gtkmm_extra_link_args = ['/def:@0@'.format(gtkmm_def.full_path())]
+
+ gtkmm_library = library(gtkmm_pcname, extra_gtkmm_objects,
+ version: gtkmm_libversion,
+ dependencies: gtkmm_build_dep,
+ link_depends: gtkmm_def,
+ link_args: gtkmm_extra_link_args,
+ link_whole: [gdkmm_library, gtk_int_lib],
+ install: true,
+ )
+endif
+
+# Install built .h and _p.h files.
+meson.add_install_script(
+ python3.path(), generate_binding_py, 'install_built_h_files',
+ built_h_cc_dir,
+ install_includedir / gtkmm_pcname / 'gtkmm', # subdir below {prefix}
+ gtkmm_used_hg_ccg_basenames
+)
+
+if not meson.is_subproject()
+ # Distribute built files.
+ # (add_dist_script() is not allowed in a subproject)
+ meson.add_dist_script(
+ python3.path(), generate_binding_py, 'dist_built_files',
+ built_h_cc_dir,
+ untracked_gtkmm,
+ gtkmm_hg_ccg_basenames,
+ )
+endif
+
+# This is useful in the main project when gtkmm is used as a subproject.
+# It's also used when building demo programs and test programs.
+gtkmm_dep = declare_dependency(
+ sources: gdkmm_used_built_h_file_targets + gtkmm_used_built_h_file_targets,
+ link_with: gtkmm_library,
+ include_directories: extra_include_dirs,
+ dependencies: gtkmm_build_dep,
+)
diff --git a/gtk/gtkmmconfig.h.meson b/gtk/gtkmmconfig.h.meson
new file mode 100644
index 00000000..bbacb747
--- /dev/null
+++ b/gtk/gtkmmconfig.h.meson
@@ -0,0 +1,43 @@
+#ifndef _GTKMM_CONFIG_H
+#define _GTKMM_CONFIG_H
+
+#include <gdkmmconfig.h>
+
+/* Defined when the -Dbuild-atkmm-api=true configure argument was given */
+#mesondefine GTKMM_ATKMM_ENABLED
+
+/* Define to omit deprecated API from gtkmm. */
+#mesondefine GTKMM_DISABLE_DEPRECATED
+
+/* Major version number of gtkmm. */
+#mesondefine GTKMM_MAJOR_VERSION
+
+/* Minor version number of gtkmm. */
+#mesondefine GTKMM_MINOR_VERSION
+
+/* Micro version number of gtkmm. */
+#mesondefine GTKMM_MICRO_VERSION
+
+/* Define when building gtkmm as a static library. */
+#mesondefine GTKMM_STATIC_LIB
+
+/* Enable DLL-specific stuff only when not building a static library. */
+#if (!defined(GTKMM_STATIC_LIB) && !defined(__CYGWIN__) && defined(_WIN32))
+# define GTKMM_DLL 1
+#endif
+
+#ifdef GTKMM_DLL
+# if defined(GTKMM_BUILD) && defined(_WINDLL)
+ /* Do not dllexport as it is handled by gendef on MSVC. */
+# define GTKMM_API
+# elif !defined(GTKMM_BUILD)
+# define GTKMM_API __declspec(dllimport)
+# else
+ /* Build a static library. */
+# define GTKMM_API
+# endif /* GTKMM_BUILD - _WINDLL */
+#else
+# define GTKMM_API
+#endif /* GTKMM_DLL */
+
+#endif /* !_GTKMM_CONFIG_H */
diff --git a/gtk/meson.build b/gtk/meson.build
new file mode 100644
index 00000000..4984ceff
--- /dev/null
+++ b/gtk/meson.build
@@ -0,0 +1,29 @@
+# gtk
+
+# Input: pkg_conf_data, gtkmm_pcname, install_pkgconfigdir, install_libdir
+# Output: install_gtkmmconfigdir, gtkmmconfig_h
+
+configure_file(
+ input: 'gtkmm.pc.in',
+ output: gtkmm_pcname + '.pc',
+ configuration: pkg_conf_data,
+ install_dir: install_pkgconfigdir,
+)
+
+gtkmm_pkg_uninst_conf_data = configuration_data()
+gtkmm_pkg_uninst_conf_data.merge_from(pkg_conf_data)
+gtkmm_pkg_uninst_conf_data.set('srcdir', meson.current_source_dir())
+
+configure_file(
+ input: 'gtkmm-uninstalled.pc.in',
+ output: gtkmm_pcname + '-uninstalled.pc',
+ configuration: gtkmm_pkg_uninst_conf_data,
+)
+
+install_gtkmmconfigdir = install_libdir / gtkmm_pcname / 'include'
+gtkmmconfig_h = configure_file(
+ input: 'gtkmmconfig.h.meson',
+ output: 'gtkmmconfig.h',
+ configuration: pkg_conf_data,
+ install_dir: install_gtkmmconfigdir,
+)
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..a2d0f148
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,358 @@
+# This file is part of gtkmm.
+
+# The resource compiler, used in demos/gtk-demo, requires a C compiler.
+project('gtkmm', 'c', 'cpp',
+ version: '3.97.1',
+ license: 'LGPLv2.1+',
+ default_options: [
+ 'cpp_std=c++17'
+ ],
+ meson_version: '>= 0.50.0', # required for python3.path()
+)
+
+gtkmm_api_version = '4.0'
+gtkmm_pcname = meson.project_name() + '-' + gtkmm_api_version
+
+gtkmm_version_array = meson.project_version().split('.')
+gtkmm_major_version = gtkmm_version_array[0].to_int()
+gtkmm_minor_version = gtkmm_version_array[1].to_int()
+gtkmm_micro_version = gtkmm_version_array[2].to_int()
+
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+# The relation between libtool's current:revison:age interface versioning
+# and the .so filename, .so.x.y.z, is
+# x = current - age
+# y = age
+# z = revision
+# If libtool_soversion is updated as described in libtool's documentation,
+# x.y.z will usually *not* be equal to meson.project_version().
+libtool_soversion = [0, 0, 0]
+gtkmm_libversion = '@0@.@1@.@2@'.format(
+ libtool_soversion[0] - libtool_soversion[2],
+ libtool_soversion[2],
+ libtool_soversion[1])
+
+# Use these instead of meson.source_root() and meson.build_root() in subdirectories.
+# source_root() and build_root() are not useful, if this is a subproject.
+project_source_root = meson.current_source_dir()
+project_build_root = meson.current_build_dir()
+
+cpp_compiler = meson.get_compiler('cpp')
+is_msvc = cpp_compiler.get_id() == 'msvc'
+is_host_windows = host_machine.system() == 'windows'
+python3 = import('python').find_installation('python3')
+
+python_version = python3.language_version()
+python_version_req = '>= 3.5'
+if not python_version.version_compare(python_version_req)
+ error('Requires Python @0@, found @1@.'.format(python_version_req, python_version))
+endif
+
+# Do we build from a git repository?
+# Suppose we do if and only if a '.git' directory or file exists.
+cmd_py = '''
+import os
+import sys
+sys.exit(os.path.isdir("@0@") or os.path.isfile("@0@"))
+'''.format(project_source_root / '.git')
+is_git_build = run_command(python3, '-c', cmd_py).returncode() != 0
+
+# Are we testing a dist tarball while it's being built?
+# There ought to be a better way. https://github.com/mesonbuild/meson/issues/6866
+is_dist_check = project_source_root.contains('dist-unpack') and \
+ project_build_root.contains('dist-build')
+
+# Options.
+maintainer_mode_opt = get_option('maintainer-mode')
+maintainer_mode = maintainer_mode_opt == 'true' or \
+ (maintainer_mode_opt == 'if-git-build' and is_git_build)
+if is_dist_check
+ message('Looks like a tarball is being tested. ' + \
+ 'Option "dist-warnings" is used instead of "warnings".')
+ warning_level = get_option('dist-warnings')
+else
+ warning_level = get_option('warnings')
+endif
+build_deprecated_api = get_option('build-deprecated-api')
+build_atkmm_api = get_option('build-atkmm-api')
+build_documentation_opt = get_option('build-documentation')
+build_documentation = build_documentation_opt == 'true' or \
+ (build_documentation_opt == 'if-maintainer-mode' and maintainer_mode)
+build_demos = get_option('build-demos')
+build_tests = get_option('build-tests')
+
+# Installation directories are relative to {prefix}.
+install_prefix = get_option('prefix')
+install_includedir = get_option('includedir')
+install_libdir = get_option('libdir')
+install_datadir = get_option('datadir')
+install_pkgconfigdir = install_libdir / 'pkgconfig'
+
+# Dependencies. <pkg> = gdk and gtk
+# <pkg>mm_build_dep: Dependencies when building the <pkg>mm library.
+# <pkg>mm_dep (created in <pkg>/<pkg>mm/meson.build):
+# Dependencies when using the <pkg>mm library.
+
+# glibmm recently gained Meson build support, so we can try looking
+# for its pkg-config files on Visual Studio as well
+glibmm_req = '>= 2.65.1'
+
+# Gtk supported pkg-config files on MSVC files for a good while, so just use that
+gtk_req = '>= 3.98.0'
+gtk_dep = dependency('gtk4', version: gtk_req)
+
+cairomm_req = '>= 1.15.4'
+cairomm_dep = dependency('cairomm-1.16', version: cairomm_req)
+
+pangomm_req = '>= 2.43.1'
+pangomm_dep = dependency('pangomm-2.44', version: pangomm_req)
+
+gdk_pixbuf_req = '>= 2.35.5'
+gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: gdk_pixbuf_req)
+
+# atkmm is required in maintainer mode even if atkmm API shall not be built.
+# gmmproc must be able to find atkmm's installed M4 files.
+atkmm_req = '>= 2.29.1'
+atkmm_dep = dependency('atkmm-2.30', version: atkmm_req, required: build_atkmm_api or maintainer_mode)
+
+epoxy_req = '>= 1.2'
+epoxy_dep = dependency('epoxy', version: epoxy_req, required: build_demos)
+
+# The -mm libraries do not yet have pkg-config files for MSVC builds,
+# so check for them manually
+glibmm_req_minor_ver = '66'
+
+glibmm_dep = dependency('glibmm-2.@0@'.format(glibmm_req_minor_ver), version: glibmm_req)
+giomm_dep = dependency('giomm-2.@0@'.format(glibmm_req_minor_ver), version: glibmm_req)
+
+# Where to find gmmproc and generate_wrap_init.pl.
+if glibmm_dep.found() and glibmm_dep.type_name() == 'pkgconfig'
+ gmmproc_dir = glibmm_dep.get_pkgconfig_variable('gmmprocdir')
+else
+ # We don't have a pkg-config file for glibmm, so use build option.
+ gmmproc_dir = get_option('gmmproc-dir')
+endif
+
+gmmproc_extra_m4_dirs = [pangomm_dep.get_pkgconfig_variable('gmmprocm4dir')]
+if atkmm_dep.found()
+ gmmproc_extra_m4_dirs += [atkmm_dep.get_pkgconfig_variable('gmmprocm4dir')]
+endif
+
+gdkmm_build_dep = [giomm_dep, gtk_dep, cairomm_dep, pangomm_dep, gdk_pixbuf_dep]
+gdkmm_requires = [
+ 'giomm-2.@0@'.format(glibmm_req_minor_ver), glibmm_req,
+ 'gtk4', gtk_req,
+ 'cairomm-1.16', cairomm_req,
+ 'pangomm-2.44', cairomm_req,
+ 'gdk-pixbuf-2.0', gdk_pixbuf_req,
+]
+
+gtkmm_build_dep = gdkmm_build_dep
+gtkmm_requires = gdkmm_requires
+
+if build_atkmm_api
+ gtkmm_build_dep += [atkmm_dep]
+ gtkmm_requires += ['atkmm-2.30', atkmm_req]
+endif
+
+# not Windows
+if host_machine.system() != 'windows'
+ gtk_unix_print_dep = dependency('gtk4-unix-print')
+ gtkmm_build_dep += [gtk_unix_print_dep]
+ gtkmm_requires += ['gtk4-unix-print', '']
+endif
+
+gdkmm_requires = ' '.join(gdkmm_requires)
+gtkmm_requires = ' '.join(gtkmm_requires)
+
+# Some dependencies are required only in maintainer mode and/or if
+# reference documentation shall be built.
+mm_common_get = find_program('mm-common-get', required: false)
+if maintainer_mode and not mm_common_get.found()
+ error('mm-common-get not found. mm-common >= 1.0.0 is required.')
+endif
+m4 = find_program('m4', required: maintainer_mode) # Used by gmmproc (in glibmm)
+perl = find_program('perl', required: maintainer_mode or build_documentation)
+doxygen = find_program('doxygen', required: build_documentation)
+dot = find_program('dot', required: build_documentation) # Used by Doxygen
+xsltproc = find_program('xsltproc', required: build_documentation)
+
+# Script files copied to 'untracked' by mm-common-get.
+script_dir = project_source_root / 'untracked' / 'build_scripts'
+generate_binding_py = script_dir / 'generate-binding.py'
+doc_reference_py = script_dir / 'doc-reference.py'
+dist_changelog_py = script_dir / 'dist-changelog.py'
+dist_build_scripts_py = script_dir / 'dist-build-scripts.py'
+check_dllexport_usage_py = script_dir / 'check-dllexport-usage.py'
+
+if maintainer_mode
+ # Copy files to untracked/build_scripts and untracked/doc.
+ run_command(mm_common_get, '--force', script_dir,
+ project_source_root / 'untracked' / 'docs')
+else
+ cmd_py = '''
+import os
+import sys
+sys.exit(os.path.isfile("@0@"))
+'''.format(generate_binding_py)
+ file_exists = run_command(python3, '-c', cmd_py).returncode() != 0
+ if not file_exists
+ error('Missing files in untracked/. You must enable maintainer-mode.')
+ endif
+endif
+
+# gtkmm's own script files.
+gtkmm_script_dir = project_source_root / 'tools'
+dummy_header_py = gtkmm_script_dir / 'dummy-header.py'
+
+# Do we build the gdkmm/gtkmm without using gendef.exe?
+gdkmm_extra_gendef_cpp_args = []
+gtkmm_extra_gendef_cpp_args = []
+if is_msvc
+ add_project_arguments(cpp_compiler.get_supported_arguments([ '/utf-8', '/wd4828']), language: 'cpp')
+ add_project_arguments(cpp_compiler.get_supported_arguments([ '/utf-8']), language: 'c')
+
+ # Check for the first line in a file generated with gmmproc,
+ # to see which gmmproc version was used
+ if maintainer_mode
+ check_gmmproc_ver_cmd = [
+ python3, check_dllexport_usage_py,
+ '--gmmprocdir=@0@'.format(gmmproc_dir),
+ ]
+ else
+ check_gmmproc_ver_cmd = [
+ python3, check_dllexport_usage_py,
+ '--file=@0@/untracked/gtk/gtkmm/aboutdialog.h'.format('/'.join(project_source_root.split('\\')))
+ ]
+ endif
+
+ # Enable __declspec(dllexport) if the gtkmm headers generated from the .hg files
+ # were generated using a recent enough gmmproc
+ build_shared_libs_directly = run_command(check_gmmproc_ver_cmd).returncode() == 0
+ message('Using __declspec(dllexport) to build gtkmm: @0@'.format(build_shared_libs_directly ? 'YES' :
'NO'))
+ if not build_shared_libs_directly
+ gdkmm_extra_gendef_cpp_args += '-DGDKMM_USE_GENDEF'
+ gtkmm_extra_gendef_cpp_args = gdkmm_extra_gendef_cpp_args + [ '-DGTKMM_USE_GENDEF' ]
+ endif
+else
+ build_shared_libs_directly = true
+endif
+
+# Set compiler warnings.
+warning_flags = []
+if warning_level == 'min'
+ if is_msvc
+ warning_flags = ['/W3']
+ else
+ warning_flags = ['-Wall']
+ endif
+elif warning_level == 'max' or warning_level == 'fatal'
+ if is_msvc
+ warning_flags = ['/W4']
+ else
+ warning_flags = '-pedantic -Wall -Wextra -Wformat-security -Wsuggest-override -Wshadow
-Wno-long-long'.split()
+ endif
+ if warning_level == 'fatal'
+ if is_msvc
+ warning_flags += ['/WX']
+ else
+ warning_flags += ['-Werror']
+ endif
+ deprecations = 'G PANGO ATK GDK GDK_PIXBUF GTK GLIBMM ATKMM PANGOMM CAIROMM SIGCXX'.split()
+ foreach d : deprecations
+ warning_flags += '-D@0@_DISABLE_DEPRECATED'.format(d)
+ endforeach
+ endif
+endif
+
+warning_flags = cpp_compiler.get_supported_arguments(warning_flags)
+add_project_arguments(warning_flags, language: 'cpp')
+
+gui_app_ldflags = []
+
+# MSVC: Ignore warnings that aren't really harmful, but make those
+# that should not be overlooked stand out. For gtkmm applications
+# where we do not want a console window to show up with Visual Studio
+# builds, we must use '-entry:mainCRTStartup' in the linker flags,
+# otherwise the program will fail to link unless we defined a WinMain()
+# for them
+if is_msvc
+ foreach wd : ['/FImsvc_recommended_pragmas.h', '/wd4267', '/wd4530', '/wd4250', '/wd4251', '/wd4273',
'/wd4275', '/wd4805']
+ disabled_warning = cpp_compiler.get_supported_arguments(wd)
+ add_project_arguments(disabled_warning, language: 'cpp')
+ endforeach
+ gui_app_ldflags += '-entry:mainCRTStartup'
+endif
+
+subdir('tools/extra_defs_gen')
+subdir('MSVC_NMake/gendef')
+subdir('gdk')
+subdir('MSVC_NMake/gdkmm')
+subdir('gdk/gdkmm')
+subdir('gtk')
+subdir('MSVC_NMake/gtkmm')
+subdir('gtk/gtkmm')
+subdir('tests')
+subdir('demos/gtk-demo')
+subdir('docs/reference')
+
+if not meson.is_subproject()
+ # Add a ChangeLog file to the distribution directory.
+ # (add_dist_script() is not allowed in a subproject)
+ meson.add_dist_script(
+ python3.path(), dist_changelog_py,
+ project_source_root,
+ )
+ # Add build scripts to the distribution directory, and delete .gitignore
+ # files and an empty $MESON_DIST_ROOT/build/ directory.
+ meson.add_dist_script(
+ python3.path(), dist_build_scripts_py,
+ project_source_root,
+ 'untracked' / 'build_scripts',
+ )
+endif
+
+# Print a summary.
+real_maintainer_mode = ''
+if maintainer_mode_opt == 'if-git-build'
+ real_maintainer_mode = ' (@0@)'.format(maintainer_mode)
+endif
+
+real_build_documentation = ''
+if build_documentation_opt == 'if-maintainer-mode'
+ real_build_documentation = ' (@0@)'.format(build_documentation)
+endif
+
+summary = [
+ '',
+ '------',
+ meson.project_name() + ' ' + meson.project_version(),
+ '',
+ ' Maintainer mode: @0@@1@'.format(maintainer_mode_opt, real_maintainer_mode),
+ ' Compiler warnings: @0@'.format(warning_level),
+ ' Build deprecated API: @0@'.format(build_deprecated_api),
+ ' Build atkmm API: @0@'.format(build_atkmm_api),
+ 'Build HTML documentation: @0@@1@'.format(build_documentation_opt, real_build_documentation),
+ ' Build demo programs: @0@'.format(build_demos),
+ ' Build test programs: @0@'.format(build_tests),
+ 'Directories:',
+ ' prefix: @0@'.format(install_prefix),
+ ' includedir: @0@'.format(install_prefix / install_includedir),
+ ' includegtkmmdir: @0@'.format(install_prefix / install_includedir / gtkmm_pcname),
+ ' libdir: @0@'.format(install_prefix / install_libdir),
+ ' gdkmmconfigdir: @0@'.format(install_prefix / install_gdkmmconfigdir),
+ ' gtkmmconfigdir: @0@'.format(install_prefix / install_gtkmmconfigdir),
+ ' m4dir: @0@'.format(install_prefix / install_m4dir),
+ ' pkgconfigdir: @0@'.format(install_prefix / install_pkgconfigdir),
+ ' datadir: @0@'.format(install_prefix / install_datadir),
+ ' docdir: @0@'.format(install_prefix / install_docdir),
+ ' devhelpdir: @0@'.format(install_prefix / install_devhelpdir),
+]
+if maintainer_mode
+ summary += [
+ ' gmmprocdir: @0@'.format(gmmproc_dir),
+ ]
+endif
+summary += ['------']
+
+message('\n'.join(summary))
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..eabeaf86
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,16 @@
+option('maintainer-mode', type: 'combo', choices: ['false', 'if-git-build', 'true'],
+ value: 'if-git-build', description: 'Generate source code from .hg and .ccg files')
+option('warnings', type: 'combo', choices: ['no', 'min', 'max', 'fatal'], value: 'min',
+ description: 'Compiler warning level')
+option('dist-warnings', type: 'combo', choices: ['no', 'min', 'max', 'fatal'], value: 'fatal',
+ description: 'Compiler warning level when a tarball is created')
+option('build-deprecated-api', type: 'boolean', value: true,
+ description: 'Build deprecated API and include it in the library')
+option('build-atkmm-api', type: 'boolean', value: true,
+ description: 'Build atkmm API and include it in the library')
+option('build-documentation', type: 'combo', choices: ['false', 'if-maintainer-mode', 'true'],
+ value: 'if-maintainer-mode', description: 'Build and install the documentation')
+option('build-demos', type: 'boolean', value: true, description: 'Build demo programs')
+option('build-tests', type: 'boolean', value: true, description: 'Build test programs')
+option('gmmproc-dir', type: 'string', value: '',
+ description: 'Directory containing gmmproc and its PERL modules (for MSVC builds only)')
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 00000000..11717625
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,61 @@
+# tests
+
+# Input: gtkmm_dep, build_tests, gui_app_ldflags, gtkmm_extra_gendef_cpp_args
+# Output: -
+
+test_programs = [
+# [[dir-name], exe-name, [sources], GUI, execute]
+ [['builder'], 'test', ['main.cc'], true, false],
+ [['child_widget'], 'test', ['main.cc', 'testwindow.cc'], true, false],
+ [['child_widget2'], 'test', ['main.cc'], true, false],
+ [['child_widget_managed'], 'test', ['main.cc'], true, false],
+ [['delete_cpp_child'], 'test', ['main.cc'], true, false],
+ [['dialog_deletethis'], 'test', ['main.cc'], true, false],
+ [['gdk_rgba'], 'test', ['main.cc'], false, true],
+ [['main_with_options'], 'test', ['main.cc'], true, false],
+ [['object_move'], 'test', ['main.cc'], false, true],
+ [['property_notification'], 'test', ['main.cc'], true, false],
+ [['refcount_dialog'], 'test', ['main.cc'], true, false],
+ [['scrolledwindow'], 'test', ['main.cc'], true, false],
+ [['tree_model_iterator'], 'test', ['main.cc'], false, true],
+ [['wrap_existing'], 'test', ['main.cc'], true, false],
+]
+
+foreach ex : test_programs
+ dir = ''
+ foreach dir_part : ex[0]
+ dir = dir / dir_part
+ endforeach
+ ex_name = (dir / ex[1]).underscorify()
+ ex_sources = []
+ foreach src : ex[2]
+ ex_sources += dir / src
+ endforeach
+
+ exe_file = executable(ex_name, ex_sources,
+ dependencies: gtkmm_dep,
+ gui_app: ex[3],
+ build_by_default: build_tests,
+ link_args: ex[3] ? gui_app_ldflags : [],
+ cpp_args: gtkmm_extra_gendef_cpp_args,
+ install: false,
+ )
+
+ if ex[4]
+ test(ex_name, exe_file)
+ endif
+endforeach
+
+# An Autotools build also contains a test that is supposed to check all
+# docs/reference/html/*.html files with xmllint. It's omitted here because
+# 1. the test does not do anything since the wrong directory is searched,
+# 2. it's not clear why 'make check' or 'ninja test' in gtkmm shall fail
+# if Doxygen writes non-standard html files. (If the right directory is
+# searched, the test finds errors in at least one html file.)
+
+#test('test_validate_docs_html', python3,
+# args: [
+# meson.current_source_dir() / 'test_validate_docs_html.py',
+# project_build_root / 'docs' / 'reference' / 'html',
+# ],
+#)
diff --git a/tools/dummy-header.py b/tools/dummy-header.py
new file mode 100755
index 00000000..8c614645
--- /dev/null
+++ b/tools/dummy-header.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+# External command, intended to be called with custom_target() in meson.build.
+
+# dummy-header.py <output_file>
+
+import os
+import sys
+
+output_file = sys.argv[1]
+
+# A dummy header file is created if it does not exist, but it's never updated.
+if not os.path.isfile(output_file):
+ with open(output_file, 'w') as f:
+ f.write('// Dummy header file. Created and used by meson.build\n')
diff --git a/tools/extra_defs_gen/meson.build b/tools/extra_defs_gen/meson.build
new file mode 100644
index 00000000..486fefb6
--- /dev/null
+++ b/tools/extra_defs_gen/meson.build
@@ -0,0 +1,35 @@
+# tools/extra_defs_gen
+
+# Input: cpp_compiler, gdkmm_build_dep, gtkmm_build_dep, install_libdir,
+# gtkmm_pcname
+# Output: m4_files, install_m4dir
+
+glibmm_generate_extra_defs_dep = cpp_compiler.find_library(
+ 'glibmm_generate_extra_defs-2.66',
+)
+
+executable('generate_defs_gdk', 'generate_defs_gdk.cc',
+ dependencies: [gdkmm_build_dep, glibmm_generate_extra_defs_dep],
+ install: false,
+)
+
+executable('generate_defs_gtk', 'generate_defs_gtk.cc',
+ dependencies: [gtkmm_build_dep, glibmm_generate_extra_defs_dep],
+ install: false,
+)
+
+# Install m4 files for reuse by other *mm projects, when building from git.
+m4_basefiles = [
+ 'class_gtkobject.m4',
+ 'convert.m4',
+ 'convert_gdk.m4',
+ 'convert_gtk.m4',
+ 'convert_gtkmm.m4',
+]
+m4_files = []
+foreach file : m4_basefiles
+ m4_files += '..' / 'm4' / file
+endforeach
+m4_files = files(m4_files)
+install_m4dir = install_libdir / gtkmm_pcname / 'proc' / 'm4'
+install_data(m4_files, install_dir: install_m4dir)
diff --git a/untracked/README b/untracked/README
new file mode 100644
index 00000000..91dec5a7
--- /dev/null
+++ b/untracked/README
@@ -0,0 +1,40 @@
+untracked/README
+
+This directory contains files not tracked by a source code control program,
+such as git. (This README file is the exception.)
+
+The files can have one of two origins.
+
+1. Copied by the mm-common-get command.
+2. Generated when gtkmm is built.
+
+Files of type 2 exist here only if gtkmm is built with maintainer-mode=false,
+or the directory comes from a tarball.
+Files of both types exist here only if gtkmm is built with Meson,
+or the tarball is created with Meson.
+
+1. Files copied by mm-common-get
+--------------------------------
+untracked/docs/doc-install.pl
+ doc-postprocess.pl
+ doxygen-extra.css
+ tagfile-to-devhelp2.xsl
+untracked/build_scripts/check-dllexport-usage.py
+ dist-build-scripts.py
+ dist-changelog.py
+ doc-reference.py
+ generate-binding.py
+
+mm-common-get may copy more files, but they are not used by gtkmm.
+
+2. Generated files
+------------------
+untracked/gdk/gdkmm/*.h
+ *.cc
+ private/*_p.h
+untracked/gtk/gtkmm/*.h
+ *.cc
+ private/*_p.h
+untracked/docs/reference/gtkmm-4.0.devhelp2
+ gtkmm-4.0.tag
+ html/*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]