build: enable meson build

Add meson build support.  Autotools support will be removed in
the future once the consuming meta-phosphor recipes are updated.

This should be feature complete relative to the previous autotools
support.

Additionally, support is added for using sdbusplus as a subproject
in the event that users do not have sdbusplus installed.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ic2c0129bda11cf10aaa557c2fd6403e2ed2cd8dd
diff --git a/.gitignore b/.gitignore
index aaaec40..92622d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+build*/
+subprojects/*/
+
 # Template from:
 # https://github.com/github/gitignore/blob/master/Autotools.gitignore
 
diff --git a/README.md b/README.md
index f131ce0..3344887 100644
--- a/README.md
+++ b/README.md
@@ -2,15 +2,24 @@
 YAML descriptors of standard D-Bus interfaces.
 The format is described by the [sdbusplus binding generation tool sdbus++][].
 
-Only the xyz/openbmc_project interfaces are built by default.
+## Building
 
-Enable the OpenPower D-Bus interfaces with:
-```
---enable-openpower-dbus-interfaces
-```
-Enable IBM D-Bus interfaces with:
-```
---enable-ibm-dbus-interfaces
-```
+This project can be built with `meson`.  The typical `meson` workflow is:
+`meson builddir && ninja -C builddir`.
+
+Due to the limited code generation methods available in meson today, changes
+to YAML files are not tracked by `meson` and do not automatically cause a new
+recompile.  Subsequent runs when making YAML changes will require running
+`ninja reconfigure` in order to regenerate the code files from the YAML.
+
+## Configuration
+
+Only the xyz/openbmc_project interfaces are built by default.  Other interfaces
+can be enabled by meson options:
+
+- com/ibm - `-Ddata_com_ibm=true`
+- org/open_power - `-Ddata_org_open_power=true`
+
+## References
 
 [sdbusplus binding generation tool sdbus++]: https://github.com/openbmc/sdbusplus/blob/master/README.md#binding-generation-tool
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..d2bb5cd
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,123 @@
+project('phosphor-dbus-interfaces', 'cpp',
+    meson_version: '>= 0.54.1',
+    default_options: [
+        'buildtype=debugoptimized',
+        'cpp_std=c++17',
+        'warning_level=3',
+        'werror=true',
+    ],
+    version: '1.0.0',
+)
+# meson_version >= 0.54.1 is necessary because that is the first place meson
+# generates unique object filenames for two files with the same `basename`.
+# Many sdbus++ generated files have `basename` collisions because they are
+# named like `.../server.cpp`.  Prior to this version, meson would create a
+# ninja recipe for a single `server.o` file.
+
+# Get sdbusplus dependency.
+sdbusplus_dep = dependency('sdbusplus', required: false)
+if sdbusplus_dep.found()
+    sdbusplusplus_prog = find_program('sdbus++')
+    sdbusgen_prog = find_program('sdbus++-gendir')
+else
+    sdbusplus_proj = subproject('sdbusplus', required: true)
+    sdbusplus_dep = sdbusplus_proj.get_variable('sdbusplus_dep')
+    sdbusplusplus_prog = sdbusplus_proj.get_variable('sdbusplusplus_prog')
+    sdbusgen_prog = sdbusplus_proj.get_variable('sdbusgen_prog')
+endif
+
+realpath_prog = find_program('realpath')
+
+# Parse options to determine appropriate subdirectories to support.
+selected_subdirs = []
+if get_option('data_com_ibm')
+    selected_subdirs += 'com/ibm'
+endif
+if get_option('data_org_open_power')
+    selected_subdirs += 'org/open_power'
+endif
+if get_option('data_xyz_openbmc_project')
+    selected_subdirs += 'xyz/openbmc_project'
+endif
+
+# Install the selected YAML files.
+foreach d : selected_subdirs
+    install_subdir(
+        d,
+        install_dir: get_option('datadir') / 'phosphor-dbus-yaml/yaml' / d,
+        strip_directory: true,
+    )
+endforeach
+
+# If libphosphor_dbus was not enabled, exit out from here.  We installed
+# the YAML which is all we are asked to do.
+if not get_option('libphosphor_dbus')
+    subdir_done()
+endif
+
+# Generate all the sdbus++ files from the selected subdirectories.
+generated_root = meson.current_build_dir() / 'gen-out'
+generated_files = run_command(
+        sdbusgen_prog,
+        '--list-all',
+        '--tool', sdbusplusplus_prog,
+        '--output', generated_root,
+        selected_subdirs,
+        check: true,
+).stdout().strip().split('\n')
+
+# Parse through the list from sdbus++-gendir and put into sets.
+generated_headers = []
+generated_cpp = []
+generated_cpp_fullpath = []
+generated_others = []
+
+foreach f : generated_files
+    rel_path = run_command(
+        realpath_prog,
+        '--relative-to', generated_root,
+        f,
+    ).stdout().strip().split('\n')[-1]
+
+    if f.endswith('.hpp')
+        generated_headers += rel_path
+    elif f.endswith('.cpp')
+        generated_cpp += rel_path
+        generated_cpp_fullpath += f
+    else
+        generated_others += rel_path
+    endif
+endforeach
+
+# Install the generated header files.
+install_subdir(
+    generated_root,
+    exclude_files: [ generated_cpp, generated_others ],
+    install_dir: get_option('includedir'),
+    strip_directory: true,
+)
+
+# Install the generated markdown files.
+install_subdir(
+    generated_root,
+    exclude_files: [ generated_headers, generated_cpp ],
+    install_dir: get_option('datadir') / meson.project_name(),
+    strip_directory: true,
+)
+
+# Define and build libphosphor_dbus.so from the C++ files.
+libphosphor_dbus = library(
+    'phosphor_dbus',
+    files(generated_cpp_fullpath),
+    include_directories: include_directories('gen-out'),
+    dependencies: sdbusplus_dep,
+    version: meson.project_version(),
+    install: true,
+)
+
+import('pkgconfig').generate(
+    libraries: libphosphor_dbus,
+    name: meson.project_name(),
+    version: meson.project_version(),
+    description: 'Generated sdbusplus bindings for phosphor-dbus-interfaces'
+)
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..929055d
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,4 @@
+option('libphosphor_dbus', type: 'boolean', value: true)
+option('data_com_ibm', type: 'boolean', value: false)
+option('data_org_open_power', type: 'boolean', value: false)
+option('data_xyz_openbmc_project', type: 'boolean', value: true)
diff --git a/subprojects/sdbusplus.wrap b/subprojects/sdbusplus.wrap
new file mode 100644
index 0000000..d470130
--- /dev/null
+++ b/subprojects/sdbusplus.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/openbmc/sdbusplus.git
+revision = HEAD