build: meson support for openpower-pel extensions

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I4b45f71a3de4966fe3649480d4333806f201f405
diff --git a/config.h.meson b/config.h.meson
index 1b33374..bafd142 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -26,8 +26,10 @@
 
 #ifdef TESTCASE
 #define ERRLOG_PERSIST_PATH "/tmp/errors"
+#define EXTENSION_PERSIST_DIR "/tmp/extensions"
 #else
 #define ERRLOG_PERSIST_PATH "/var/lib/phosphor-logging/errors"
+#define EXTENSION_PERSIST_DIR "/var/lib/phosphor-logging/extensions"
 #endif
 
 static constexpr size_t ERROR_CAP = @error_cap@;
diff --git a/extensions/meson.build b/extensions/meson.build
new file mode 100644
index 0000000..8773dc4
--- /dev/null
+++ b/extensions/meson.build
@@ -0,0 +1,3 @@
+if not get_option('openpower-pel-extension').disabled()
+    subdir('openpower-pels')
+endif
diff --git a/extensions/openpower-pels/meson.build b/extensions/openpower-pels/meson.build
new file mode 100644
index 0000000..b00d0ad
--- /dev/null
+++ b/extensions/openpower-pels/meson.build
@@ -0,0 +1,134 @@
+libpldm_dep = dependency(
+    'libpldm',
+    fallback: ['pldm', 'libpldm_dep'],
+    default_options: ['libpldm-only=enabled', 'oem-ibm=enabled'],
+)
+
+if cpp.has_header('nlohmann/json.hpp')
+    nlohmann_json = declare_dependency()
+else
+    subproject('nlohmann-json')
+    nlohmann_json = declare_dependency(
+        include_directories: include_directories(
+            '../../subprojects/nlohmann-json/single_include',
+            '../../subprojects/nlohmann-json/single_include/nlohmann',
+        )
+    )
+endif
+
+python_inst = import('python').find_installation('python3')
+python_ver = python_inst.language_version()
+python_dep = python_inst.dependency()
+
+if cpp.has_header('CLI/CLI.hpp')
+    CLI11_dep = declare_dependency()
+else
+    CLI11_dep = dependency(
+        'CLI11',
+        fallback: [ 'CLI11', 'CLI11_dep' ],
+    )
+endif
+
+libpel_sources = files(
+    'ascii_string.cpp',
+    'bcd_time.cpp',
+    'callout.cpp',
+    'callouts.cpp',
+    'data_interface.cpp',
+    'device_callouts.cpp',
+    'extended_user_header.cpp',
+    'failing_mtms.cpp',
+    'fru_identity.cpp',
+    'generic.cpp',
+    'json_utils.cpp',
+    'log_id.cpp',
+    'mru.cpp',
+    'mtms.cpp',
+    'pce_identity.cpp',
+    'pel.cpp',
+    'pel_rules.cpp',
+    'pel_values.cpp',
+    'private_header.cpp',
+    'registry.cpp',
+    'section_factory.cpp',
+    'service_indicators.cpp',
+    'severity.cpp',
+    'user_header.cpp',
+)
+
+libpel_deps = [
+    libpldm_dep,
+    nlohmann_json,
+    sdbusplus_dep,
+    sdeventplus_dep,
+    pdi_dep,
+]
+
+libpel_lib = static_library(
+    'pel',
+    libpel_sources,
+    'paths.cpp', # paths is separate because it is overridden during test.
+    include_directories: include_directories('../..', '../../gen'),
+    dependencies: libpel_deps,
+)
+
+libpel_dep = declare_dependency(
+    include_directories: include_directories('.'),
+    link_with: libpel_lib,
+    dependencies: [
+        libpldm_dep,
+        nlohmann_json,
+        sdbusplus_dep,
+        sdeventplus_dep,
+        pdi_dep,
+    ],
+
+)
+
+log_manager_ext_deps += [
+    libpel_dep,
+    libpldm_dep,
+    nlohmann_json,
+]
+
+log_manager_ext_sources += files(
+    'entry_points.cpp',
+    'extended_user_data.cpp',
+    'host_notifier.cpp',
+    'manager.cpp',
+    'pldm_interface.cpp',
+    'repository.cpp',
+    'src.cpp',
+    'user_data.cpp',
+)
+
+install_data(
+    'registry/message_registry.json',
+    install_dir: get_option('datadir') / 'phosphor-logging/pels',
+)
+
+peltool_sources = files(
+    'extended_user_data.cpp',
+    'src.cpp',
+    'user_data.cpp',
+    'user_data_json.cpp',
+)
+
+peltool_deps = [
+    CLI11_dep,
+    python_dep,
+]
+
+executable(
+    'peltool',
+    'tools/peltool.cpp',
+    peltool_sources,
+    cpp_args: [ '-DPELTOOL' ],
+    link_args: [ '-lpython' + python_ver ],
+    include_directories: include_directories('../..'),
+    dependencies: [
+        peltool_deps,
+        libpel_dep,
+    ],
+    install: true,
+)
diff --git a/meson.build b/meson.build
index 6c968dc..f62a0c4 100644
--- a/meson.build
+++ b/meson.build
@@ -9,6 +9,7 @@
     version: '1.0.0',
 )
 
+cpp = meson.get_compiler('cpp')
 python_prog = find_program('python3')
 
 # Get sdbusplus dependency.
@@ -26,9 +27,14 @@
 endif
 
 # Get PDI and sdeventplus dependency.
+pdi_vars = []
+if not get_option('openpower-pel-extension').disabled()
+    pdi_vars += [ 'data_org_open_power=true' ]
+endif
 pdi_dep = dependency(
     'phosphor-dbus-interfaces',
     fallback: ['phosphor-dbus-interfaces', 'phosphor_dbus_interfaces_dep'],
+    default_options: pdi_vars,
 )
 sdeventplus_dep = dependency(
     'sdeventplus',
@@ -111,6 +117,11 @@
 )
 
 subdir('phosphor-logging')
+
+log_manager_ext_sources = []
+log_manager_ext_deps = []
+
+subdir('extensions')
 subdir('phosphor-rsyslog-config')
 
 # Build libphosphor-logging.
@@ -151,6 +162,7 @@
 # Generate daemon.
 log_manager_sources = [
     generated_sources,
+    elog_errors_gen,
     elog_lookup_gen,
     elog_process_gen,
     files(
@@ -163,16 +175,21 @@
         'util.cpp',
     )
 ]
+log_manager_deps = [
+    cereal_dep,
+    pdi_dep,
+    sdbusplus_dep,
+    sdeventplus_dep,
+]
 executable('phosphor-log-manager',
     log_manager_sources,
+    log_manager_ext_sources,
     'log_manager_main.cpp',
     include_directories: include_directories('gen'),
     link_with: libphosphor_logging,
     dependencies: [
-        cereal_dep,
-        pdi_dep,
-        sdbusplus_dep,
-        sdeventplus_dep
+        log_manager_deps,
+        log_manager_ext_deps,
     ],
     install: true,
 )
diff --git a/meson_options.txt b/meson_options.txt
index de37d35..d27f124 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,4 +1,10 @@
 option('tests', type: 'feature', description: 'Build tests')
+option(
+    'openpower-pel-extension',
+    type: 'feature',
+    description: 'Create PELs',
+    value: 'disabled'
+)
 
 option('yamldir', type: 'string', description: 'Path to YAML')
 option(
diff --git a/subprojects/CLI11.wrap b/subprojects/CLI11.wrap
new file mode 100644
index 0000000..e695a9d
--- /dev/null
+++ b/subprojects/CLI11.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/CLIUtils/CLI11.git
+revision = HEAD
diff --git a/subprojects/nlohmann-json.wrap b/subprojects/nlohmann-json.wrap
new file mode 100644
index 0000000..9096612
--- /dev/null
+++ b/subprojects/nlohmann-json.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/nlohmann/json.git
+revision = HEAD
diff --git a/subprojects/pldm.wrap b/subprojects/pldm.wrap
new file mode 100644
index 0000000..a49a2eb
--- /dev/null
+++ b/subprojects/pldm.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/openbmc/pldm.git
+revision = HEAD
diff --git a/test/meson.build b/test/meson.build
index 19c81f2..1538b7f 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -19,6 +19,10 @@
   endif
 endif
 
+if not get_option('openpower-pel-extension').disabled()
+    subdir('openpower-pels')
+endif
+
 tests = [
     'elog_quiesce_test',
     'elog_update_ts_test',
@@ -45,12 +49,9 @@
                 '-DTESTCASE_' + t.underscorify(),
             ],
             dependencies: [
-                cereal_dep,
                 gmock_dep,
                 gtest_dep,
-                pdi_dep,
-                sdbusplus_dep,
-                sdeventplus_dep,
+                log_manager_deps,
             ],
             include_directories: include_directories('..', '../gen'),
         )
diff --git a/test/openpower-pels/meson.build b/test/openpower-pels/meson.build
new file mode 100644
index 0000000..3527bed
--- /dev/null
+++ b/test/openpower-pels/meson.build
@@ -0,0 +1,109 @@
+openpower_pels = {
+    'additional_data': {},
+    'ascii_string': {},
+    'bcd_time': {},
+    'device_callouts': {},
+    'event_logger': {},
+    'extended_user_data': {},
+    'extended_user_header': {},
+    'failing_mtms': {},
+    'fru_identity': {},
+    'generic_section': {},
+    'host_notifier': {
+        'sources': [
+            '../../extensions/openpower-pels/host_notifier.cpp',
+            '../../extensions/openpower-pels/repository.cpp',
+        ],
+    },
+    'json_utils': {},
+    'log_id': {},
+    'mru': {},
+    'mtms': {},
+    'pce_identity': {},
+    'pel_manager': {
+        'sources': [
+            '../../elog_entry.cpp',
+            '../../elog_serialize.cpp',
+            '../../extensions.cpp',
+            '../../log_manager.cpp',
+            elog_lookup_gen,
+            elog_process_gen,
+            generated_sources,
+            log_manager_ext_sources,
+        ],
+        'deps': [ cereal_dep ],
+    },
+    'pel_rules': {},
+    'pel': {},
+    'pel_values': {},
+    'private_header': {},
+    'real_pel': {},
+    'registry': {},
+    'repository': {
+        'sources': [
+            '../../extensions/openpower-pels/repository.cpp',
+        ],
+    },
+    'section_header': {},
+    'service_indicators': {},
+    'severity': {},
+    'src': {},
+    'src_callout': {},
+    'src_callouts': {},
+    'stream': {},
+    'user_data': {},
+    'user_header': {},
+}
+
+# Build a common shared library for all openpower tests of all the widely
+# used sources under test.
+openpower_test_lib = static_library(
+    'openpower_test_lib',
+    'pel_utils.cpp',
+    'paths.cpp',
+    libpel_sources,
+    peltool_sources,
+    '../../util.cpp',
+    cpp_args: [
+        '-DTESTCASE=openpower_test_lib',
+    ],
+    include_directories: include_directories(
+        '../../',
+        '../../gen',
+    ),
+    dependencies: [
+        libpel_deps,
+        peltool_deps,
+    ],
+)
+
+foreach t : openpower_pels.keys()
+    test(
+        'test_openpower_pels_' + t.underscorify(),
+        executable(
+            'test-openpower-pels-' + t.underscorify(),
+            t + '_test.cpp',
+            openpower_pels.get(t).get('sources', []),
+            link_with: [
+                openpower_test_lib,
+                libphosphor_logging,
+            ],
+            link_args: [ '-lpython' + python_ver ],
+            cpp_args: [
+                '-DTESTCASE=' + t.underscorify(),
+                '-DTESTCASE_' + t.underscorify(),
+            ],
+            dependencies: [
+                gtest_dep,
+                gmock_dep,
+                libpel_deps,
+                peltool_deps,
+                openpower_pels.get(t).get('deps', []),
+            ],
+            include_directories: include_directories(
+                '../../',
+                '../../gen',
+            ),
+        )
+    )
+endforeach
diff --git a/test/openpower-pels/pel_test.cpp b/test/openpower-pels/pel_test.cpp
index 3631b50..49b8e96 100644
--- a/test/openpower-pels/pel_test.cpp
+++ b/test/openpower-pels/pel_test.cpp
@@ -420,9 +420,13 @@
     std::string jsonString{d.begin(), d.end()};
     auto json = nlohmann::json::parse(jsonString);
 
-    // Ensure the 'Process Name' entry contains 'pel_test'
+    // Ensure the 'Process Name' entry contains the name of this test
+    // executable.
     auto name = json["Process Name"].get<std::string>();
-    EXPECT_NE(name.find("pel_test"), std::string::npos);
+    auto found = (name.find("pel_test") != std::string::npos) ||
+                 (name.find("test-openpower-pels-pel") != std::string::npos);
+    EXPECT_TRUE(found);
+    // @TODO(stwcx): remove 'pel_test' when removing autotools.
 
     auto version = json["BMC Version ID"].get<std::string>();
     EXPECT_EQ(version, "ABCD1234");