meson: add alternative build system

Enable meson build for the pldm project (by default). The autotools
support will be eventually removed. This change is aligned with other
OpenBMC repos, and besides for pldm meson seems to be significantly
faster (see times below to build and run tests on an x86 OpenBMC sdk).

time sh -c './bootstrap.sh ; ./configure ${CONFIGURE_FLAGS}
--enable-oe-sdk --enable-oem-ibm ; make ; make check'
real    3m49.495s

time sh -c 'meson -Doe-sdk=enabled -Dtests=enabled -Doem-ibm=enabled
build/ ; ninja -C build test'
real    0m14.940s

With the currently used warning level in the meson config (the highest
level is used), certain warnings had to be fixed in this commit
(warnings are treated as errors).

Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Change-Id: I9022417c8fa218d3c2c2f786502caa815af2f832
diff --git a/.gitignore b/.gitignore
index 8172a1b..762460a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,3 +81,7 @@
 /test/libpldmresponder_file_io_test
 /test/libpldmresponder_pdr_state_effecter_test
 /test/libpldmresponder_bios_table_test
+
+# meson
+/build
+/builddir
diff --git a/README.md b/README.md
index e9cfc14..7701316 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,16 @@
+# To Build
+Need `meson` and `ninja`. Alternatively, source an OpenBMC ARM/x86 SDK.
+```
+meson build && ninja -C build
+```
+## To run unit tests
+Tests can be run in the CI docker container, or with an OpenBMC x86 sdk(see
+below for x86 steps).
+```
+meson -Doe-sdk=enabled -Dtests=enabled build
+ninja -C build test
+```
+
 # Code Organization
 At a high-level, code in this repository belongs to one of the following three
 components.
diff --git a/libpldm/meson.build b/libpldm/meson.build
new file mode 100644
index 0000000..680608f
--- /dev/null
+++ b/libpldm/meson.build
@@ -0,0 +1,47 @@
+headers = [
+  'base.h',
+  'pldm_types.h',
+  'platform.h',
+  'bios.h',
+  'states.h',
+]
+
+sources = [
+  'base.c',
+  'platform.c',
+  'bios.c'
+]
+
+libpldm_headers = ['.', '..']
+
+if get_option('oem-ibm').enabled()
+  headers += [
+    '../oem/ibm/libpldm/file_io.h'
+  ]
+  sources += [
+    '../oem/ibm/libpldm/file_io.c'
+  ]
+  libpldm_headers += ['../oem/ibm']
+endif
+
+install_headers(
+  headers,
+  subdir: 'libpldm')
+
+libpldm = library(
+  'libpldm',
+  sources,
+  implicit_include_directories: false,
+  include_directories: include_directories(libpldm_headers),
+  version: meson.project_version(),
+  install: true)
+
+libpldm = declare_dependency(
+  include_directories: include_directories(libpldm_headers),
+  link_with: libpldm)
+
+import('pkgconfig').generate(
+  name: 'libpldm',
+  description: 'PLDM protocol encode/decode C lib',
+  version: meson.project_version(),
+  libraries: libpldm)
diff --git a/libpldmresponder/base.cpp b/libpldmresponder/base.cpp
index d0c3551..3b480ad 100644
--- a/libpldmresponder/base.cpp
+++ b/libpldmresponder/base.cpp
@@ -47,7 +47,7 @@
 
 } // namespace base
 
-Response getPLDMTypes(const pldm_msg* request, size_t payloadLength)
+Response getPLDMTypes(const pldm_msg* request, size_t /*payloadLength*/)
 {
     // DSP0240 has this as a bitfield8[N], where N = 0 to 7
     std::array<bitfield8_t, 8> types{};
@@ -146,7 +146,7 @@
     return response;
 }
 
-Response getTID(const pldm_msg* request, size_t payloadLength)
+Response getTID(const pldm_msg* request, size_t /*payloadLength*/)
 {
     // assigned 1 to the bmc as the PLDM terminus
     uint8_t tid = 1;
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index 392f58a..c88a25c 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -57,7 +57,7 @@
 
 } // namespace utils
 
-Response getDateTime(const pldm_msg* request, size_t payloadLength)
+Response getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
 {
     uint8_t seconds = 0;
     uint8_t minutes = 0;
@@ -138,8 +138,9 @@
  *  @param[in] instanceID - instance ID to identify the command
  *  @param[in] biosJsonDir - path where the BIOS json files are present
  */
-Response getBIOSStringTable(BIOSTable& BIOSStringTable, uint32_t transferHandle,
-                            uint8_t transferOpFlag, uint8_t instanceID,
+Response getBIOSStringTable(BIOSTable& BIOSStringTable,
+                            uint32_t /*transferHandle*/,
+                            uint8_t /*transferOpFlag*/, uint8_t instanceID,
                             const char* biosJsonDir)
 {
     Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
@@ -601,8 +602,9 @@
  */
 Response getBIOSAttributeTable(BIOSTable& BIOSAttributeTable,
                                const BIOSTable& BIOSStringTable,
-                               uint32_t transferHandle, uint8_t transferOpFlag,
-                               uint8_t instanceID, const char* biosJsonDir)
+                               uint32_t /*transferHandle*/,
+                               uint8_t /*transferOpFlag*/, uint8_t instanceID,
+                               const char* biosJsonDir)
 {
     Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
                       0);
@@ -667,14 +669,14 @@
  *  @param[in] transferOpFlag - flag to indicate which part of data being
  * transferred
  *  @param[in] instanceID - instance ID to identify the command
- *  @param[in] biosJsonDir -  path where the BIOS json files are present
  */
 Response getBIOSAttributeValueTable(BIOSTable& BIOSAttributeValueTable,
                                     const BIOSTable& BIOSAttributeTable,
                                     const BIOSTable& BIOSStringTable,
-                                    uint32_t& transferHandle,
-                                    uint8_t& transferOpFlag, uint8_t instanceID,
-                                    const char* biosJsonDir)
+                                    uint32_t& /*transferHandle*/,
+                                    uint8_t& /*transferOpFlag*/,
+                                    uint8_t instanceID,
+                                    const char* /*biosJsonDir*/)
 {
     Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
                       0);
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
new file mode 100644
index 0000000..c63685c
--- /dev/null
+++ b/libpldmresponder/meson.build
@@ -0,0 +1,34 @@
+deps = [
+  dependency('phosphor-dbus-interfaces'),
+  dependency('phosphor-logging'),
+  dependency('sdbusplus'),
+  libpldm
+]
+
+sources = [
+  'base.cpp',
+  'bios.cpp',
+  'bios_table.cpp',
+  'bios_parser.cpp',
+  'pdr.cpp',
+  'effecters.cpp',
+  'utils.cpp',
+  '../registration.cpp'
+]
+
+if get_option('oem-ibm').enabled()
+  sources += [
+    '../oem/ibm/libpldmresponder/file_io.cpp',
+    '../oem/ibm/libpldmresponder/file_table.cpp'
+  ]
+endif
+
+libpldmresponder = library(
+  'libpldmresponder',
+  sources,
+  version: meson.project_version(),
+  dependencies: deps,
+  install: true)
+
+libpldmresponder = declare_dependency(
+  link_with: libpldmresponder)
diff --git a/libpldmresponder/pdr.hpp b/libpldmresponder/pdr.hpp
index 71d8aee..c9df51f 100644
--- a/libpldmresponder/pdr.hpp
+++ b/libpldmresponder/pdr.hpp
@@ -47,6 +47,8 @@
 class Repo
 {
   public:
+    virtual ~Repo() = default;
+
     /** @brief Add a new entry to the PDR
      *
      *  @param[in] entry - new PDR entry
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..b71e83c
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,48 @@
+project('pldm', ['c', 'cpp'],
+        version: '0.1', meson_version: '>=0.49.0',
+        default_options: [
+          'warning_level=3',
+          'default_library=shared',
+          'werror=true',
+          'cpp_std=c++17'
+        ])
+
+# Wno-psabi reduces the number of "Note:" messages when cross-compiling some STL
+# stuff for ARM. See https://stackoverflow.com/questions/48149323/strange-gcc-warning-when-compiling-qt-project
+# Basically, gcc 6 and gcc 7 are not ABI compatible, but since the whole OpenBMC
+# project uses the same compiler, we can safely ignmore these info notes.
+add_project_arguments('-Wno-psabi', language: 'cpp')
+
+conf_data = configuration_data()
+conf_data.set_quoted('BIOS_JSONS_DIR', '/etc/default/obmc/pldm/bios')
+conf_data.set_quoted('BIOS_TABLES_DIR', '/var/lib/pldm/bios')
+if get_option('oem-ibm').enabled()
+  conf_data.set_quoted('FILE_TABLE_JSON', '/etc/default/obmc/pldm/fileTable.json')
+  add_global_arguments('-DOEM_IBM', language : 'c')
+  add_global_arguments('-DOEM_IBM', language : 'cpp')
+endif
+configure_file(output: 'config.h',
+  configuration: conf_data
+)
+
+subdir('libpldm')
+subdir('libpldmresponder')
+subdir('tool')
+
+deps = [
+  libpldm,
+  libpldmresponder,
+  dependency('sdbusplus')
+]
+
+executable(
+  'pldmd',
+  'pldmd.cpp',
+  implicit_include_directories: false,
+  dependencies: deps,
+  install: true,
+  install_dir: get_option('bindir'))
+
+if get_option('tests').enabled()
+  subdir('test')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..32e9547
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,3 @@
+option('tests', type: 'feature', description: 'Build tests')
+option('oe-sdk', type: 'feature', description: 'Enable OE SDK')
+option('oem-ibm', type: 'feature', description: 'Enable IBM OEM PLDM')
diff --git a/oem/ibm/test/libpldmresponder_fileio_test.cpp b/oem/ibm/test/libpldmresponder_fileio_test.cpp
index c132895..83b0cc0 100644
--- a/oem/ibm/test/libpldmresponder_fileio_test.cpp
+++ b/oem/ibm/test/libpldmresponder_fileio_test.cpp
@@ -26,8 +26,8 @@
     return 0;
 }
 
-int sd_journal_send_with_location(const char* file, const char* line,
-                                  const char* func, const char* format, ...)
+int sd_journal_send_with_location(const char* /*file*/, const char* /*line*/,
+                                  const char* /*func*/, const char* format, ...)
 {
     logs.push_back(format);
     return 0;
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000..93135fd
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,42 @@
+if get_option('oe-sdk').enabled()
+  # Setup OE SYSROOT
+  OECORE_TARGET_SYSROOT = run_command('sh', '-c', 'echo $OECORE_TARGET_SYSROOT').stdout().strip()
+  if OECORE_TARGET_SYSROOT == ''
+      error('Unable to get $OECORE_TARGET_SYSROOT, check your environment.')
+  endif
+  message('OE_SYSROOT: ' + OECORE_TARGET_SYSROOT)
+  rpath = ':'.join([OECORE_TARGET_SYSROOT + '/lib', OECORE_TARGET_SYSROOT + '/usr/lib'])
+  ld_so = run_command('sh', '-c', 'find ' + OECORE_TARGET_SYSROOT + '/lib/ld-*.so | sort -r -n | head -n1').stdout().strip()
+  dynamic_linker = ['-Wl,-dynamic-linker,' + ld_so]
+else
+  dynamic_linker = []
+endif
+
+gtest = dependency('gtest', main: true, disabler: true, required: true)
+gmock = dependency('gmock', disabler: true, required: true)
+
+tests = [
+  'libpldm_base_test',
+  'libpldm_platform_test',
+  'libpldmresponder_base_test',
+  'libpldm_bios_test',
+  'libpldmresponder_bios_test',
+  'libpldmresponder_pdr_state_effecter_test',
+  'libpldmresponder_bios_table_test'
+]
+
+if get_option('oem-ibm').enabled()
+  tests += [
+    '../oem/ibm/test/libpldm_fileio_test',
+    '../oem/ibm/test/libpldmresponder_fileio_test'
+  ]
+endif
+
+foreach t : tests
+  test(t, executable(t.underscorify(), t + '.cpp',
+                     implicit_include_directories: false,
+                     link_args: dynamic_linker,
+                     build_rpath: get_option('oe-sdk').enabled() ? rpath : '',
+                     dependencies: [libpldm, libpldmresponder, gtest, gmock]),
+       workdir: meson.current_source_dir())
+endforeach
diff --git a/tool/meson.build b/tool/meson.build
new file mode 100644
index 0000000..8d83bda
--- /dev/null
+++ b/tool/meson.build
@@ -0,0 +1,13 @@
+sources = [
+  'pldm_cmd_helper.cpp',
+  'pldm_base_cmd.cpp',
+  'pldmtool.cpp'
+]
+
+executable(
+  'pldmtool',
+  sources,
+  implicit_include_directories: false,
+  dependencies: libpldm,
+  install: true,
+  install_dir: get_option('bindir'))
diff --git a/tool/pldm_base_cmd.cpp b/tool/pldm_base_cmd.cpp
index aa5b668..3ebd123 100644
--- a/tool/pldm_base_cmd.cpp
+++ b/tool/pldm_base_cmd.cpp
@@ -14,7 +14,7 @@
  * Main function that handles the GetPLDMTypes response callback via mctp
  *
  */
-void getPLDMTypes(vector<std::string>&& args)
+void getPLDMTypes(vector<std::string>&& /*args*/)
 {
     // Create and encode the request message
     vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +