meson support: create meson.build files

This commit contains the meson.build files necessary to build the
project and unit tests. The normal procedure is to run the command
'meson build' followed by ninja -C build. Additionally, service files
are copied to remove autoconf-style naming convention (they cannot be
  removed before autoconf files are removed).

Signed-off-by: Mike Capps <mikepcapps@gmail.com>
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I6cf8f5c1c923a198ad2fb4638843645479fd0498
diff --git a/.gitignore b/.gitignore
index 0b4cff4..59ede25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,6 @@
 *_test

 libtool

 *.service

+build*/

+subprojects/*

+!subprojects/*.wrap

diff --git a/README.md b/README.md
index c35ebb6..9c23c26 100755
--- a/README.md
+++ b/README.md
@@ -27,25 +27,25 @@
   * To disable from building, provide the `--disable-control` flag at
   *configure* time:
   ```
-  ./configure ${CONFIGURE_FLAGS} --disable-control
+  meson build -Ddisable-control
   ```
 * [Fan Presence Detection](#fan-presence-detection)
-  * To disable from building, provide the `--disable-presence` flag at
+  * To disable from building, provide the `-Ddisable-presence` flag at
   *configure* time:
   ```
-  ./configure ${CONFIGURE_FLAGS} --disable-presence
+  meson build -Ddisable-presence
   ```
 * [Fan Monitoring](#fan-monitoring)
-  * To disable from building, provide the `--disable-monitor` flag at
+  * To disable from building, provide the `-Ddisable-monitor` flag at
   *configure* time:
   ```
-  ./configure ${CONFIGURE_FLAGS} --disable-monitor
+  meson build -Ddisable-monitor
   ```
 * [Cooling Type](#cooling-type)
-  * To disable from building, provide the `--disable-cooling-type` flag at
+  * To disable from building, provide the `-Ddisable-cooling-type` flag at
   *configure* time:
   ```
-  ./configure ${CONFIGURE_FLAGS} --disable-cooling-type
+  meson build -Ddisable-cooling-type
   ```
 
 The following applications must be enabled at *configure* time to be built:
@@ -53,7 +53,7 @@
   * To enable building this, provide the `--enable-sensor-monitor` flag at
   *configure* time:
   ```
-  ./configure ${CONFIGURE_FLAGS} --enable-sensor-monitor
+  meson build -Denable-sensor-monitor
   ```
 
 To clean the repository run `./bootstrap.sh clean`.
diff --git a/control/functor.hpp b/control/functor.hpp
index 59e15df..da5ffe1 100644
--- a/control/functor.hpp
+++ b/control/functor.hpp
@@ -102,7 +102,7 @@
      * Extract the property from the PropertiesChanged
      * message and run the handler function.
      */
-    void operator()(sdbusplus::bus_t& bus, sdbusplus::message_t& msg,
+    void operator()(sdbusplus::bus_t&, sdbusplus::message_t& msg,
                     Zone& zone) const
     {
         if (msg)
@@ -403,7 +403,7 @@
      * Extract the name owner from the NameOwnerChanged
      * message and run the handler function.
      */
-    void operator()(sdbusplus::bus_t& bus, sdbusplus::message_t& msg,
+    void operator()(sdbusplus::bus_t&, sdbusplus::message_t& msg,
                     Zone& zone) const
     {
         if (msg)
diff --git a/control/main.cpp b/control/main.cpp
index 90f8e5c..201f7b0 100644
--- a/control/main.cpp
+++ b/control/main.cpp
@@ -16,14 +16,13 @@
 #include "config.h"
 
 #ifndef CONTROL_USE_JSON
-#include "../utils/flight_recorder.hpp"
 #include "argument.hpp"
 #include "manager.hpp"
 #else
+#include "../utils/flight_recorder.hpp"
 #include "json/manager.hpp"
 #endif
 
-#include "event.hpp"
 #include "sdbusplus.hpp"
 #include "sdeventplus.hpp"
 
diff --git a/control/meson.build b/control/meson.build
new file mode 100644
index 0000000..5225b0c
--- /dev/null
+++ b/control/meson.build
@@ -0,0 +1,107 @@
+
+include_dirs=[
+    '.',
+    '..'
+]
+
+deps=[
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep,
+    sdeventplus_dep
+]
+
+sources = ['main.cpp']
+
+if conf.has('CONTROL_USE_JSON')
+    deps += json_dep
+    include_dirs += [
+        './json',
+        './json/actions',
+        './json/triggers'
+    ]
+    sources += [
+        'json/dbus_zone.cpp',
+        'json/event.cpp',
+        'json/fan.cpp',
+        'json/group.cpp',
+        'json/manager.cpp',
+        'json/profile.cpp',
+        'json/zone.cpp',
+        'json/actions/count_state_floor.cpp',
+        'json/actions/count_state_target.cpp',
+        'json/actions/default_floor.cpp',
+        'json/actions/get_managed_objects.cpp',
+        'json/actions/mapped_floor.cpp',
+        'json/actions/missing_owner_target.cpp',
+        'json/actions/net_target_decrease.cpp',
+        'json/actions/net_target_increase.cpp',
+        'json/actions/override_fan_target.cpp',
+        'json/actions/pcie_card_floors.cpp',
+        'json/actions/request_target_base.cpp',
+        'json/actions/set_parameter_from_group_max.cpp',
+        'json/actions/timer_based_actions.cpp',
+        'json/utils/flight_recorder.cpp',
+        'json/utils/modifier.cpp',
+        'json/utils/pcie_card_metadata.cpp',
+        'json/triggers/init.cpp',
+        'json/triggers/parameter.cpp',
+        'json/triggers/signal.cpp',
+        'json/triggers/timer.cpp'
+    ]
+else
+    fan_zone_defs_cpp_dep = custom_target(
+        'fan_zone_defs.cpp',
+        input: files(
+            './gen-fan-zone-defs.py',
+            conf.get_unquoted('FAN_DEF_YAML_FILE'),
+            conf.get_unquoted('FAN_ZONE_YAML_FILE'),
+            conf.get_unquoted('ZONE_EVENTS_YAML_FILE'),
+            conf.get_unquoted('ZONE_CONDITIONS_YAML_FILE')
+        ),
+        command: [
+            python_prog, '@INPUT0@',
+            '-f','@INPUT1@',
+            '-z','@INPUT2@',
+            '-e','@INPUT3@',
+            '-c','@INPUT4@',
+            '-o', 'control'
+        ],
+        output: 'fan_zone_defs.cpp'
+    )
+
+    sources += [
+        'actions.cpp',
+        'argument.cpp',
+        'fan.cpp',
+        fan_zone_defs_cpp_dep,
+        'manager.cpp',
+        'preconditions.cpp',
+        'triggers.cpp',
+        'utility.cpp',
+        'zone.cpp'
+    ]
+
+endif
+
+phosphor_fan_control_include_directories = include_directories(include_dirs)
+phosphor_fan_control = executable(
+    'phosphor-fan-control',
+    sources,
+    dependencies:deps,
+    implicit_include_directories: false,
+    include_directories: phosphor_fan_control_include_directories,
+    install: true
+)
+
+fanctl = executable(
+  'fanctl',
+  'fanctl.cpp',
+      dependencies: [
+          cli11_dep,
+          fmt_dep,
+          sdbusplus_dep
+      ],
+  include_directories: phosphor_fan_control_include_directories,
+  install: true
+)
diff --git a/control/service_files/json/phosphor-fan-control@.service b/control/service_files/json/phosphor-fan-control@.service
new file mode 100644
index 0000000..5085590
--- /dev/null
+++ b/control/service_files/json/phosphor-fan-control@.service
@@ -0,0 +1,6 @@
+[Unit]
+Description=Phosphor Fan Control Daemon
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-control
diff --git a/control/service_files/yaml/phosphor-fan-control-init@.service b/control/service_files/yaml/phosphor-fan-control-init@.service
new file mode 100644
index 0000000..c012be8
--- /dev/null
+++ b/control/service_files/yaml/phosphor-fan-control-init@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Phosphor Fan Control Initialization
+Wants=obmc-power-on@%i.target
+After=obmc-power-on@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-control --init
+SyslogIdentifier=phosphor-fan-control
+
+[Install]
+WantedBy=obmc-chassis-poweron@%i.target
diff --git a/control/service_files/yaml/phosphor-fan-control@.service b/control/service_files/yaml/phosphor-fan-control@.service
new file mode 100644
index 0000000..693363a
--- /dev/null
+++ b/control/service_files/yaml/phosphor-fan-control@.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Phosphor Fan Control Daemon
+Conflicts=obmc-chassis-powered-off@%i.target
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-control --control
+SyslogIdentifier=phosphor-fan-control
+
+[Install]
+RequiredBy=obmc-fan-control-ready@%i.target
diff --git a/cooling-type/meson.build b/cooling-type/meson.build
new file mode 100644
index 0000000..a8a4577
--- /dev/null
+++ b/cooling-type/meson.build
@@ -0,0 +1,27 @@
+phosphor_fan_sensor_monitor_include_directories = include_directories(
+    '.',
+    '..'
+)
+
+source=[
+    'argument.cpp',
+    'cooling_type.cpp',
+    'cooling_type.hpp',
+    'main.cpp'
+]
+
+deps=[
+    libevdev_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdeventplus_dep
+]
+
+phosphor_fan_cooling_type = executable(
+    'phosphor-cooling-type',
+    source,
+    dependencies: deps,
+    implicit_include_directories: false,
+    include_directories: ['..'],
+    install: true
+)
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..42d1eae
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,203 @@
+project(
+    'phosphor-fan-presence',
+    'cpp',
+    default_options: [
+        'warning_level=3',
+        'werror=true',
+        'cpp_std=c++20',
+        'buildtype=debugoptimized',
+        'prefix=/usr'
+    ],
+    license: 'Apache-2.0',
+    version: '1.0',
+    meson_version: '>=0.57.0',
+)
+
+python_prog = find_program('python3', native: true)
+
+cpp = meson.get_compiler('cpp')
+
+cli11_dep = dependency('cli11', required: false)
+
+if not meson.get_compiler('cpp').has_header_symbol(
+    'CLI/CLI.hpp',
+    'CLI::App',
+    dependencies: cli11_dep,
+    required: false)
+    cli11_proj = subproject('cli11', required:false)
+    assert(cli11_proj.found(), 'CLI11 is required')
+    cli11_dep = cli11_proj.get_variable('CLI11_dep')
+endif
+
+fmt_dep = dependency('fmt')
+json_dep = declare_dependency()
+
+phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
+phosphor_logging_dep = dependency('phosphor-logging')
+sdbusplus_dep = dependency('sdbusplus')
+sdeventplus_dep = dependency('sdeventplus')
+stdplus_dep = dependency('stdplus')
+systemd_dep = dependency('systemd')
+
+if(get_option('tests').enabled())
+    gmock_dep = dependency('gmock', disabler: true)
+    gtest_dep = dependency('gtest', main: true, disabler: true, required: false)
+
+    if not gtest_dep.found() or not gmock_dep.found()
+        gtest_proj = import('cmake').subproject('googletest', required: false)
+        if gtest_proj.found()
+            gtest_dep = declare_dependency(
+                dependencies: [
+                    dependency('threads'),
+                    gtest_proj.dependency('gtest'),
+                    gtest_proj.dependency('gtest_main'),
+                ]
+            )
+            gmock_dep = gtest_proj.dependency('gmock')
+        else
+            assert(
+                not get_option('tests').enabled(),
+                'Googletest is required if tests are enabled'
+            )
+        endif
+    endif
+    subdir('test')
+endif
+
+
+servicedir = systemd_dep.get_variable('systemdsystemunitdir')
+usr_share_dir = '/usr/share/phosphor-fan-presence'
+
+conf = configuration_data()
+
+# Control
+conf.set_quoted(
+    'CONTROL_PERSIST_ROOT_PATH', get_option('control-persist-root-path'))
+conf.set_quoted(
+    'CONTROL_BUSNAME', get_option('control-busname'))
+conf.set_quoted(
+    'CONTROL_OBJPATH', get_option('control-objpath'))
+conf.set_quoted(
+    'CONTROL_PERSIST_ROOT_PATH', get_option('control-persist-root-path'))
+
+conf.set_quoted(
+    'FAN_DEF_YAML_FILE', get_option('fan-def-yaml-file'))
+conf.set_quoted(
+    'FAN_ZONE_YAML_FILE', get_option('fan-zone-yaml-file'))
+conf.set_quoted(
+    'ZONE_EVENTS_YAML_FILE', get_option('zone-events-yaml-file'))
+conf.set_quoted(
+    'ZONE_CONDITIONS_YAML_FILE', get_option('zone-conditions-yaml-file'))
+
+# Monitor
+conf.set(
+    'NUM_MONITOR_LOG_ENTRIES', get_option('num-monitor-log-entries'))
+conf.set_quoted(
+    'THERMAL_ALERT_BUSNAME', get_option('thermal-alert-busname'))
+conf.set_quoted(
+    'THERMAL_ALERT_OBJPATH', get_option('thermal-alert-objpath'))
+conf.set_quoted(
+    'FAN_MONITOR_YAML_FILE', get_option('fan-monitor-yaml-file'))
+
+# Fan control can be in YAML mode when everything else is in JSON mode
+control_conf_type = 'yaml'
+if get_option('json-config').enabled() and get_option('json-control').enabled()
+    control_conf_type = 'json'
+endif
+
+# JSON-or-YAML (all programs)
+if get_option('json-config').enabled()
+    conf.set('PRESENCE_USE_JSON', '')
+    if control_conf_type == 'json'
+        conf.set('CONTROL_USE_JSON', '')
+    endif
+    conf.set('MONITOR_USE_JSON', '')
+
+    if not cpp.has_header('nlohmann/json.hpp')
+        json_dep = dependency('nlohmann_json')
+    endif
+    conf_type = 'json'
+else
+    conf_type = 'yaml'
+endif
+
+conf.set(
+    'NUM_PRESENCE_LOG_ENTRIES', get_option('num-presence-log-entries'))
+conf.set_quoted(
+    'PRESENCE_YAML_FILE', get_option('presence-config'))
+
+# Sensor
+if get_option('enable-host-state').enabled()
+    conf.set('ENABLE_HOST_STATE', '')
+endif
+
+conf.set_quoted(
+    'SENSOR_MONITOR_PERSIST_ROOT_PATH', get_option('sensor-monitor-root-path'))
+conf.set(
+    'SHUTDOWN_ALARM_HARD_SHUTDOWN_DELAY_MS', get_option('sensor-monitor-hard-shutdown-delay'))
+conf.set(
+    'SHUTDOWN_ALARM_SOFT_SHUTDOWN_DELAY_MS', get_option('sensor-monitor-soft-shutdown-delay'))
+
+configure_file(output: 'config.h', configuration: conf)
+
+# Service: [name,[svcfiles]]
+services = []
+
+if get_option('control-service').enabled()
+    subdir('control')
+    service_files = ['phosphor-fan-control@.service']
+    if control_conf_type == 'yaml'
+        service_files += 'phosphor-fan-control-init@.service'
+    endif
+    services += [['control', service_files]]
+endif
+
+if get_option('monitor-service').enabled()
+    subdir('monitor')
+    service_files = ['phosphor-fan-monitor@.service']
+    if not get_option('json-config').enabled()
+        service_files += 'phosphor-fan-monitor-init@.service'
+    endif
+    services += [['monitor', service_files]]
+endif
+
+if get_option('cooling-type-service').enabled()
+    libevdev_dep = dependency('libevdev')
+    subdir('cooling-type')
+endif
+
+if get_option('presence-service').enabled()
+    libevdev_dep = dependency('libevdev')
+    subdir('presence')
+    services += [['presence', ['phosphor-fan-presence-tach@.service']]]
+endif
+
+if get_option('sensor-monitor-service').enabled()
+    subdir('sensor-monitor')
+    install_data('sensor-monitor/service_files/sensor-monitor.service',
+        install_dir: servicedir)
+endif
+
+foreach service : services
+    this_conf_type = conf_type
+
+    if service[0] == 'control'
+        this_conf_type = control_conf_type
+    endif
+
+    foreach service_file : service[1]
+        install_data(service[0] / 'service_files' / this_conf_type / service_file,
+                     install_dir: servicedir)
+    endforeach
+
+    if this_conf_type == 'json'
+        fs = import('fs')
+        dir = meson.current_source_dir() / service[0] / 'config_files' / get_option('machine-name')
+        if fs.is_dir(dir)
+            install_subdir(service[0] / 'config_files' / get_option('machine-name'),
+                          install_dir: usr_share_dir / service[0],
+                          strip_directory: true)
+        endif
+    endif
+endforeach
+
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..6687422
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,136 @@
+
+option(
+    'tests', type: 'feature', value: 'enabled', description: 'Build tests.',
+)
+
+option(
+    'json-config', type: 'feature', value: 'enabled',
+    description: 'Use json at runtime to configure fan packages.'
+)
+
+option(
+    'machine-name', type: 'string', value: '',
+    description: 'Machine name being built. Used to install the proper JSON config files.'
+)
+
+# Control
+
+option(
+    'control-service', type: 'feature', value: 'enabled',
+    description: 'Build fan control service.'
+)
+
+option(
+    'json-control', type: 'feature', value: 'enabled',
+    description: 'Disable JSON based fan control even if json-config is enabled.'
+)
+
+option(
+    'control-busname', type: 'string', value: 'xyz.openbmc_project.Control.Thermal',
+    description: 'Application\'s D-Bus busname to own.'
+)
+
+option(
+    'control-objpath', type: 'string', value: '/xyz/openbmc_project/control/thermal',
+    description: 'Application\'s root D-Bus object path.'
+)
+
+option(
+    'control-persist-root-path', type: 'string', value: '/var/lib/phosphor-fan-presence/control',
+    description: 'Base location to persist zone property states'
+)
+
+option(
+    'fan-def-yaml-file', type: 'string', value: 'example/fans.yaml',
+    description: 'Build time fan configuration file'
+)
+option(
+    'fan-zone-yaml-file', type: 'string', value: 'example/zones.yaml',
+    description: 'Build time fan configuration file'
+)
+option(
+    'zone-events-yaml-file', type: 'string', value: 'example/events.yaml',
+    description: 'Build time fan configuration file'
+)
+option(
+    'zone-conditions-yaml-file', type: 'string', value: 'example/zone_conditions.yaml',
+    description: 'Build time fan configuration file'
+)
+
+# Monitor
+
+option(
+    'monitor-service', type: 'feature', value: 'enabled',
+    description: 'Build fan monitor service'
+)
+
+option(
+    'fan-monitor-yaml-file', type: 'string', value: 'example/monitor.yaml',
+    description: 'Location of the config file'
+)
+
+option(
+    'num-monitor-log-entries', type: 'integer', value: 75,
+    description: 'Maximum number of entries in the monitor log.'
+)
+
+option(
+    'thermal-alert-busname', type: 'string', value: 'xyz.openbmc_project.Thermal.Alert',
+    description: 'Application\'s D-Bus busname to own.'
+)
+
+option(
+    'thermal-alert-objpath', type: 'string', value: '/xyz/openbmc_project/alerts/thermal_fault_alert',
+    description: 'Application\'s root D-Bus object path.'
+)
+
+# Presence
+
+option(
+    'presence-service', type: 'feature', value: 'enabled',
+    description: 'Build fan presence service.'
+)
+
+option(
+    'presence-config', type: 'string', value: 'example/example.yaml',
+    description: 'Location of the config file'
+)
+
+option(
+    'num-presence-log-entries', type: 'integer', value: 50,
+    description: 'Maximum number of entries in the presence log.'
+)
+
+# Sensor Monitor
+
+option(
+    'sensor-monitor-service', type: 'feature', value: 'enabled',
+    description: 'Build sensor monitor.'
+)
+
+option(
+    'sensor-monitor-root-path', type: 'string', value: '/xyz/openbmc_project/alerts/thermal_fault_alert',
+    description: 'Application\'s root D-Bus object path.'
+)
+
+option(
+    'sensor-monitor-hard-shutdown-delay', type: 'integer', value: 23000,
+    description: 'Milliseconds to delay the alarm before hard shutdown.'
+)
+
+option(
+    'sensor-monitor-soft-shutdown-delay', type: 'integer', value: 900000,
+    description: 'Milliseconds to delay the alarm before soft shutdown.'
+)
+
+# Other
+
+option(
+    'cooling-type-service', type: 'feature', value: 'disabled',
+    description: 'Build cooling-type package.'
+)
+
+option(
+    'enable-host-state', type: 'feature', value: 'disabled',
+    description: 'Enable host state.'
+)
diff --git a/monitor/meson.build b/monitor/meson.build
new file mode 100644
index 0000000..d708cca
--- /dev/null
+++ b/monitor/meson.build
@@ -0,0 +1,59 @@
+phosphor_fan_monitor_include_directories = include_directories(
+    '.',
+    '..'
+)
+
+sources=[
+    'argument.cpp',
+    'conditions.cpp',
+    'fan.cpp',
+    'fan_error.cpp',
+    'json_parser.cpp',
+    'logging.cpp',
+    'main.cpp',
+    'power_interface.cpp',
+    'system.cpp',
+    'tach_sensor.cpp',
+    '../hwmon_ffdc.cpp'
+]
+
+deps=[
+    json_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep,
+    sdeventplus_dep
+]
+
+# Only needed for YAML config
+if get_option('json-config').disabled()
+    fan_monitor_defs_cpp_dep = custom_target(
+        'fan_monitor_defs.cpp',
+        input: files(
+            './gen-fan-monitor-defs.py',
+            conf.get_unquoted('FAN_MONITOR_YAML_FILE'),
+        ),
+        command: [
+            python_prog, '@INPUT0@',
+            '-m','@INPUT1@',
+            '-o','monitor'
+        ],
+        output: 'fan_monitor_defs.cpp'
+    )
+
+    sources += fan_monitor_defs_cpp_dep
+endif
+
+phosphor_fan_monitor = executable(
+    'phosphor-fan-monitor',
+    sources,
+    dependencies: deps,
+    implicit_include_directories: false,
+    include_directories: phosphor_fan_monitor_include_directories,
+    install: true
+)
+
+if(get_option('tests').enabled())
+    subdir('test')
+endif
+
diff --git a/monitor/service_files/json/phosphor-fan-monitor@.service b/monitor/service_files/json/phosphor-fan-monitor@.service
new file mode 100644
index 0000000..34dc600
--- /dev/null
+++ b/monitor/service_files/json/phosphor-fan-monitor@.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Phosphor Fan Monitor Daemon
+After=mapper-wait@-xyz-openbmc_project-inventory.service
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-monitor
diff --git a/monitor/service_files/yaml/phosphor-fan-monitor-init@.service b/monitor/service_files/yaml/phosphor-fan-monitor-init@.service
new file mode 100644
index 0000000..41c0b3e
--- /dev/null
+++ b/monitor/service_files/yaml/phosphor-fan-monitor-init@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Phosphor Fan Monitor Initialization
+Wants=obmc-power-on@%i.target
+After=obmc-power-on@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-monitor --init
+SyslogIdentifier=phosphor-fan-monitor
+
+[Install]
+WantedBy=obmc-chassis-poweron@%i.target
diff --git a/monitor/service_files/yaml/phosphor-fan-monitor@.service b/monitor/service_files/yaml/phosphor-fan-monitor@.service
new file mode 100644
index 0000000..0819e7c
--- /dev/null
+++ b/monitor/service_files/yaml/phosphor-fan-monitor@.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Phosphor Fan Monitor Daemon
+Conflicts=obmc-chassis-powered-off@%i.target
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-monitor --monitor
+SyslogIdentifier=phosphor-fan-monitor
+
+[Install]
+RequiredBy=obmc-fan-control-ready@%i.target
diff --git a/monitor/test/meson.build b/monitor/test/meson.build
new file mode 100644
index 0000000..4955691
--- /dev/null
+++ b/monitor/test/meson.build
@@ -0,0 +1,40 @@
+phosphor_fan_monitor_test_include_directories = include_directories(
+    '../..'
+)
+
+test_deps=[
+    fmt_dep,
+    gmock_dep,
+    gtest_dep,
+    json_dep,
+    phosphor_logging_dep,
+    sdeventplus_dep
+]
+
+test_sources=[
+    files(
+        '../logging.cpp',
+    )
+]
+
+test(
+    'power_off_cause',
+    executable(
+        'power_off_cause',
+        'power_off_cause_test.cpp',
+        dependencies:test_deps,
+        implicit_include_directories: false,
+        include_directories: [phosphor_fan_monitor_test_include_directories]
+    )
+)
+
+test(
+    'power_off_rule_test',
+    executable(
+        'power_off_rule_test',
+        sources:test_sources,
+        dependencies: test_deps,
+        implicit_include_directories: false,
+        include_directories: phosphor_fan_monitor_test_include_directories,
+    )
+)
diff --git a/presence/meson.build b/presence/meson.build
new file mode 100644
index 0000000..d3028d6
--- /dev/null
+++ b/presence/meson.build
@@ -0,0 +1,57 @@
+
+phosphor_fan_presence_include_directories = include_directories(
+    '.',
+    '..'
+)
+
+sources=[
+    'anyof.cpp',
+    'error_reporter.cpp',
+    'fallback.cpp',
+    'fan.cpp',
+    'get_power_state.cpp',
+    'gpio.cpp',
+    'json_parser.cpp',
+    'logging.cpp',
+    'psensor.cpp',
+    'tach.cpp',
+    'tach_detect.cpp'
+]
+
+deps=[
+    libevdev_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep,
+    sdeventplus_dep
+]
+
+# Only needed for YAML config
+if get_option('json-config').disabled()
+    generated_hpp_dep = custom_target(
+        'generated.hpp',
+        input: files(
+            './pfpgen.py',
+            conf.get_unquoted('PRESENCE_YAML_FILE')
+        ),
+        command: [
+            python_prog, '@INPUT0@',
+            'generate-cpp',
+            '-i', '@INPUT1@'
+        ],
+        capture: true,
+        output: 'generated.hpp'
+    )
+
+    sources += generated_hpp_dep
+endif
+
+phosphor_fan_presence = executable(
+    'phosphor-fan-presence-tach',
+    sources,
+    dependencies : deps,
+    implicit_include_directories: false,
+    include_directories: phosphor_fan_presence_include_directories,
+    install: true
+)
+
diff --git a/presence/service_files/json/phosphor-fan-presence-tach@.service b/presence/service_files/json/phosphor-fan-presence-tach@.service
new file mode 100644
index 0000000..5cad843
--- /dev/null
+++ b/presence/service_files/json/phosphor-fan-presence-tach@.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Phosphor Fan Presence Tach Daemon
+After=mapper-wait@-xyz-openbmc_project-inventory.service
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-presence-tach
diff --git a/presence/service_files/yaml/phosphor-fan-presence-tach@.service b/presence/service_files/yaml/phosphor-fan-presence-tach@.service
new file mode 100644
index 0000000..33c2408
--- /dev/null
+++ b/presence/service_files/yaml/phosphor-fan-presence-tach@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Phosphor Fan Presence Tach Daemon
+Wants=obmc-power-on@%i.target
+After=obmc-power-on@%i.target
+Conflicts=obmc-chassis-powered-off@%i.target
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/bin/phosphor-fan-presence-tach
+SyslogIdentifier=phosphor-fan-presence-tach
+
+[Install]
+RequiredBy=obmc-chassis-poweron@%i.target
diff --git a/presence/test/fallbacktest.cpp b/presence/test/fallbacktest.cpp
index daa0b50..de4a54d 100644
--- a/presence/test/fallbacktest.cpp
+++ b/presence/test/fallbacktest.cpp
@@ -15,7 +15,7 @@
 {
 namespace presence
 {
-void setPresence(const Fan& fan, bool newState)
+void setPresence(const Fan&, bool newState)
 {
     if (newState)
     {
@@ -68,7 +68,7 @@
     // Validate a single sensor.
     // Validate on->off->on.
     pstate = -1;
-    Fan fan{"/path", "name"};
+    Fan fan{"/path", "name", 0};
     TestSensor ts;
     ts._present = true;
     std::vector<std::reference_wrapper<PresenceSensor>> sensors{ts};
@@ -99,7 +99,7 @@
     // Validate both sensors on->off->on
 
     pstate = -1;
-    Fan fan{"/path", "name"};
+    Fan fan{"/path", "name", 0};
     TestSensor ts1, ts2;
     ts1._present = true;
     ts2._present = true;
diff --git a/presence/test/meson.build b/presence/test/meson.build
new file mode 100644
index 0000000..15de777
--- /dev/null
+++ b/presence/test/meson.build
@@ -0,0 +1,20 @@
+
+test_include_directories = include_directories(
+    '../..'
+)
+
+test_deps=[
+    gmock_dep,
+    gtest_dep,
+]
+
+test(
+    'logger_test',
+    executable(
+        'logger_test',
+        'fallbacktest.cpp',
+        dependencies:test_deps,
+        implicit_include_directories: false,
+        include_directories: [test_include_directories]
+    )
+)
diff --git a/sensor-monitor/meson.build b/sensor-monitor/meson.build
new file mode 100644
index 0000000..64f8b16
--- /dev/null
+++ b/sensor-monitor/meson.build
@@ -0,0 +1,25 @@
+phosphor_fan_sensor_monitor_include_directories = include_directories(
+    '.',
+    '..'
+)
+
+source=[
+    'main.cpp',
+    'shutdown_alarm_monitor.cpp',
+    'threshold_alarm_logger.cpp'
+]
+
+deps=[
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdeventplus_dep
+]
+
+phosphor_fan_sensor_monitor = executable(
+    'sensor-monitor',
+    source,
+    dependencies: deps,
+    implicit_include_directories: false,
+    include_directories: ['..'],
+    install: true
+)
diff --git a/sensor-monitor/service_files/sensor-monitor.service b/sensor-monitor/service_files/sensor-monitor.service
new file mode 100644
index 0000000..8c952ae
--- /dev/null
+++ b/sensor-monitor/service_files/sensor-monitor.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Sensor Monitor
+Wants=xyz.openbmc_project.Logging.service
+After=xyz.openbmc_project.Logging.service
+Wants=obmc-mapper.target
+After=obmc-mapper.target
+
+[Service]
+Restart=always
+ExecStart=/usr/bin/sensor-monitor
+
+[Install]
+WantedBy=multi-user.target
diff --git a/subprojects/cli11.wrap b/subprojects/cli11.wrap
new file mode 100644
index 0000000..f0ce3da
--- /dev/null
+++ b/subprojects/cli11.wrap
@@ -0,0 +1,4 @@
+[wrap-git]
+url = https://github.com/CLIUtils/CLI11
+revision = HEAD
+
diff --git a/subprojects/evdev.wrap b/subprojects/evdev.wrap
new file mode 100644
index 0000000..7c40bbb
--- /dev/null
+++ b/subprojects/evdev.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/freedesktop/libevdev
+revision = HEAD
+
+[provide]
+libevdev =  dep_libevdev
diff --git a/subprojects/fmt.wrap b/subprojects/fmt.wrap
new file mode 100644
index 0000000..63869be
--- /dev/null
+++ b/subprojects/fmt.wrap
@@ -0,0 +1,12 @@
+[wrap-file]
+directory = fmt-8.1.1
+source_url = https://github.com/fmtlib/fmt/archive/8.1.1.tar.gz
+source_filename = fmt-8.1.1.tar.gz
+source_hash = 3d794d3cf67633b34b2771eb9f073bde87e846e0d395d254df7b211ef1ec7346
+patch_filename = fmt_8.1.1-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/fmt_8.1.1-1/get_patch
+patch_hash = 6035a67c7a8c90bed74c293c7265c769f47a69816125f7566bccb8e2543cee5e
+
+[provide]
+fmt = fmt_dep
+
diff --git a/subprojects/nlohmann_json.wrap b/subprojects/nlohmann_json.wrap
new file mode 100644
index 0000000..0aa1389
--- /dev/null
+++ b/subprojects/nlohmann_json.wrap
@@ -0,0 +1,12 @@
+[wrap-file]
+directory = nlohmann_json-3.9.1
+lead_directory_missing = true
+source_url = https://github.com/nlohmann/json/releases/download/v3.9.1/include.zip
+source_filename = nlohmann_json-3.9.1.zip
+source_hash = 6bea5877b1541d353bd77bdfbdb2696333ae5ed8f9e8cc22df657192218cad91
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/nlohmann_json/3.9.1/1/get_zip
+patch_filename = nlohmann_json-3.9.1-1-wrap.zip
+patch_hash = 1774e5506fbe3897d652f67e41973194b948d2ab851cf464a742f35f160a1435
+
+[provide]
+nlohmann_json = nlohmann_json_dep
diff --git a/subprojects/phosphor-dbus-interfaces.wrap b/subprojects/phosphor-dbus-interfaces.wrap
new file mode 100644
index 0000000..346aa0c
--- /dev/null
+++ b/subprojects/phosphor-dbus-interfaces.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-dbus-interfaces.git
+revision = HEAD
+
+[provide]
+phosphor-dbus-interfaces = phosphor_dbus_interfaces_dep
diff --git a/subprojects/phosphor-logging.wrap b/subprojects/phosphor-logging.wrap
new file mode 100644
index 0000000..b88f58e
--- /dev/null
+++ b/subprojects/phosphor-logging.wrap
@@ -0,0 +1,7 @@
+[wrap-git]
+url = https://github.com/openbmc/phosphor-logging.git
+revision = HEAD
+
+[provide]
+phosphor-logging = phosphor_logging_dep
+
diff --git a/subprojects/sdbusplus.wrap b/subprojects/sdbusplus.wrap
new file mode 100644
index 0000000..7b076d0
--- /dev/null
+++ b/subprojects/sdbusplus.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/sdbusplus.git
+revision = HEAD
+
+[provide]
+sdbusplus = sdbusplus_dep
diff --git a/subprojects/sdeventplus.wrap b/subprojects/sdeventplus.wrap
new file mode 100644
index 0000000..f871ac0
--- /dev/null
+++ b/subprojects/sdeventplus.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/sdeventplus.git
+revision = HEAD
+
+[provide]
+sdeventplus = sdeventplus_dep
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000..5e2d7b0
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,25 @@
+
+test_include_directories = include_directories(
+    '..'
+)
+
+test_deps=[
+    fmt_dep,
+    gmock_dep,
+    gtest_dep,
+    json_dep,
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+    sdbusplus_dep
+]
+
+test(
+    'logger_test',
+    executable(
+        'logger_test',
+        'logger_test.cpp',
+        dependencies:test_deps,
+        implicit_include_directories: false,
+        include_directories: [test_include_directories]
+    )
+)