Move to meson build configuration

cmake is Deprecated

Signed-off-by: John Chung <john.chung@arm.com>
Change-Id: I9d08b087828aa5a16f601785dcb7868704ec73a3
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 86b3b81..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-project(CPERParse)
-include(FetchContent)
-include(GoogleTest)
-if (BUILD_PYTHON_LIBS)
-  include(FindSWIG)
-  include(UseSWIG)
-  find_package(PythonLibs 3 REQUIRED)
-  find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} REQUIRED)
-endif()
-
-# GoogleTest requires at least C++14.
-set(CMAKE_CXX_STANDARD 14)
-
-# Output into subdirectories /lib and /bin.
-set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
-
-# Fetch json-c from git repository.
-FetchContent_Declare(
-  json-c
-  GIT_REPOSITORY https://github.com/json-c/json-c.git
-  GIT_TAG        9021cdcdd01fc9dbcbe1f06391848c2ac915212f # 0.15
-)
-
-# Fetch b64-c from git repository.
-FetchContent_Declare(
-  b64-c
-  GIT_REPOSITORY https://github.com/jwerle/b64.c.git
-  GIT_TAG        c33188cd541f19b072ee4988d8224ea6c964bed1 # 9/2/2021
-)
-
-# Fetch GoogleTest from git repository.
-FetchContent_Declare(
-  googletest
-  GIT_REPOSITORY https://github.com/google/googletest.git
-  GIT_TAG release-1.12.1
-)
-FetchContent_MakeAvailable(json-c b64-c googletest)
-
-# Add library and test executable.
-file(GLOB SectionSources sections/*.c)
-file(GLOB EDKSources edk/*.c)
-file(GLOB GeneratorSectionSources generator/sections/*.c)
-add_library(cper-parse STATIC 
-  cper-parse.c 
-  ir-parse.c 
-  cper-utils.c 
-  common-utils.c
-  json-schema.c 
-  ${SectionSources} 
-  ${EDKSources}
-)
-add_library(cper-generate STATIC 
-  generator/cper-generate.c 
-  generator/gen-utils.c 
-  common-utils.c
-  ${GeneratorSectionSources} 
-  ${EDKSources}
-)
-add_executable(cper-convert cli-app/cper-convert.c)
-add_executable(cper-generate-cli 
-  generator/cper-generate-cli.c
-  ${EDKSources}
-)
-add_executable(cper-tests 
-  tests/ir-tests.cpp 
-  tests/test-utils.cpp
-  generator/cper-generate.c
-  generator/gen-utils.c 
-  sections/cper-section.c
-  ${GeneratorSectionSources} 
-  ${EDKSources}
-)
-
-# Linking, compile & property setup for targets.
-target_link_libraries(cper-tests cper-parse json-c GTest::gtest_main)
-target_link_libraries(cper-parse json-c b64c)
-target_link_libraries(cper-convert cper-parse)
-target_link_libraries(cper-generate-cli cper-generate)
-target_compile_options(cper-parse PRIVATE -Wno-address-of-packed-member)
-target_compile_options(cper-tests PRIVATE -fpermissive)
-set_target_properties(cper-generate-cli PROPERTIES OUTPUT_NAME "cper-generate")
-
-# Copy required specification JSON for command line application.
-add_custom_command(TARGET cper-convert POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory bin/specification)
-add_custom_command(TARGET cper-convert POST_BUILD COMMAND cp -r specification/json/* bin/specification)
-
-# Add tests to GoogleTest.
-#gtest_discover_tests(cper-tests WORKING_DIRECTORY bin/)
-
-# Generate Python bindings with SWIG.
-if (BUILD_PYTHON_LIBS)
-  include_directories(cperparse_pylib ${PYTHON_INCLUDE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
-  swig_add_library(cperparse_pylib 
-    TYPE STATIC
-    LANGUAGE python
-    SOURCES cper-parse.i
-    OUTPUT_DIR lib/
-  )
-  swig_link_libraries(cperparse_pylib 
-    cper-parse
-    json-c
-    ${PYTHON_LIBRARIES}
-  )
-endif()
\ No newline at end of file
diff --git a/README.md b/README.md
index 339a0e4..e161acc 100644
--- a/README.md
+++ b/README.md
@@ -2,38 +2,22 @@
 This repository specifies a structure for representing UEFI CPER records (as described in UEFI Specification Appendix N) in a human-readable JSON format, in addition to a library which can readily convert back and forth between the standard CPER binary format and the specified structured JSON.
 
 ## Prerequisites
-Before building this library and its associated tools, you must have CMake (>=3.10) and SWIG installed, with the following CMake modules available:
-- `FetchContent`
-- `GoogleTest`
-- `FindSWIG`
-- `UseSWIG`
-
-If you are building the Python bindings, you should also have Python3 and associated libraries installed for the purposes of building the Python bindings.
+Before building this library and its associated tools, you must have meson (>=1.1.1)
 
 ## Building
-This project uses CMake (>=3.10). To build for native architecture, simply run:
+This project uses Meson (>=1.1.1). To build for native architecture, simply run:
 ```
-cmake .
-make
-```
-A static library file for the parsing library will be written to `lib/`, and test executables will be written to `bin/`. To build the Python bindings in addition to all C libraries, add the argument `-DBUILD_PYTHON_LIBS` to your `cmake` command.
-
-### Cross Compilation
-To cross compile for ARM/AArch64 architecture from x86, instead use the below commands (ensure `cmake clean .` beforehand).
-You will need either the `arm-linux-gnueabi` or `aarch64-linux-gnu` toolchain installed.
-```bash
-cmake -DCMAKE_TOOLCHAIN_FILE="toolchains/arm-toolchain.cmake" -S. -Bbin # arm-linux-gnueabi
-cmake -DCMAKE_TOOLCHAIN_FILE="toolchains/aarch64-toolchain.cmake" -S. -Bbin # aarch64-linux-gnu
-make
+meson setup build
+ninji -C build
 ```
 
 ## Usage
-This project comes with several binaries to help you deal with CPER binary and CPER-JSON. The first of these is `cper-convert`, which is a command line tool that can be found in `bin/`. With this, you can convert to and from CPER and CPER-JSON through the command line. An example usage scenario is below:
+This project comes with several binaries to help you deal with CPER binary and CPER-JSON. The first of these is `cper-convert`, which is a command line tool that can be found in `build/`. With this, you can convert to and from CPER and CPER-JSON through the command line. An example usage scenario is below:
 ```
 cper-convert to-cper samples/cper-json-test-arm.json --out cper.dump
 cper-convert to-json cper.generated.dump
 ```
-Another tool bundled with this repository is `cper-generate`, found in `bin/`. This allows you to generate pseudo-random valid CPER records with sections of specified types for testing purposes. An example use of the program is below:
+Another tool bundled with this repository is `cper-generate`, found in `build/`. This allows you to generate pseudo-random valid CPER records with sections of specified types for testing purposes. An example use of the program is below:
 ```
 cper-generate --out cper.generated.dump --sections generic ia32x64
 ```
@@ -45,11 +29,9 @@
 void ir_to_cper(json_object* ir, FILE* out);
 ```
 
-This library also has Python bindings generated on build, which are placed at `lib/cperparse.py`. The static library `_cperparse_pylib.a` (as well as the C file `cper-parsePYTHON_wrap.c`) are generated specifically for the purpose of wrapping types for the Python library, and should not be used as a standard static C library.
-
 ## Specification
 The specification for this project's CPER-JSON format can be found in `specification/`, defined in both JSON Schema format and also as a LaTeX document.
 Specification for the CPER binary format can be found in [UEFI Specification Appendix N](https://uefi.org/sites/default/files/resources/UEFI_Spec_2_9_2021_03_18.pdf) (2021/03/18).
 
 ## Usage Examples
-This library is utilised in a proof of concept displaying CPER communication between a SatMC and OpenBMC board, including a conversion into CPER JSON for logging that utilises this library. You can find information on how to reproduce the prototype at the [scripts repository](https://gitlab.arm.com/server_management/cper-poc-scripts), and example usage of the library itself at the [pldm](https://gitlab.arm.com/server_management/pldm) repository.
\ No newline at end of file
+This library is utilised in a proof of concept displaying CPER communication between a SatMC and OpenBMC board, including a conversion into CPER JSON for logging that utilises this library. You can find information on how to reproduce the prototype at the [scripts repository](https://gitlab.arm.com/server_management/cper-poc-scripts), and example usage of the library itself at the [pldm](https://gitlab.arm.com/server_management/pldm) repository.
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..a379481
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,161 @@
+project(
+  'libcper', ['c', 'cpp'],
+  version: '0.1',
+  meson_version: '>=1.1.1',
+  default_options: [
+    'c_std=c18',
+    'cpp_std=c++23',
+    'tests=' + (meson.is_subproject() ? 'disabled' : 'enabled'),
+    'werror=true',
+    'warning_level=2',
+  ])
+
+project_description = 'libcper library'
+
+SectionSources = files(
+  'sections/cper-section-arm.c',
+  'sections/cper-section.c',
+  'sections/cper-section-ccix-per.c',
+  'sections/cper-section-cxl-component.c',
+  'sections/cper-section-cxl-protocol.c',
+  'sections/cper-section-dmar-generic.c',
+  'sections/cper-section-dmar-iommu.c',
+  'sections/cper-section-dmar-vtd.c',
+  'sections/cper-section-firmware.c',
+  'sections/cper-section-generic.c',
+  'sections/cper-section-ia32x64.c',
+  'sections/cper-section-ipf.c',
+  'sections/cper-section-memory.c',
+  'sections/cper-section-pci-bus.c',
+  'sections/cper-section-pci-dev.c',
+  'sections/cper-section-pcie.c'
+)
+
+EDKSources = files(
+  'edk/Cper.c'
+)
+
+GeneratorSectionSources = files(
+  'generator/sections/gen-section-arm.c',
+  'generator/sections/gen-section.c',
+  'generator/sections/gen-section-ccix-per.c',
+  'generator/sections/gen-section-cxl-component.c',
+  'generator/sections/gen-section-cxl-protocol.c',
+  'generator/sections/gen-section-dmar.c',
+  'generator/sections/gen-section-firmware.c',
+  'generator/sections/gen-section-generic.c',
+  'generator/sections/gen-section-ia32x64.c',
+  'generator/sections/gen-section-memory.c',
+  'generator/sections/gen-section-pci-bus.c',
+  'generator/sections/gen-section-pci-dev.c',
+  'generator/sections/gen-section-pcie.c'
+)
+
+cmake = import('cmake')
+
+json_c_dep = dependency(
+              'json-c',
+              required: true,
+              fallback : ['json-c', 'json_c_dep'])
+
+libb64 = dependency('base64', required: false)
+if not libb64.found()
+  opt_var = cmake.subproject_options()
+  opt_var.add_cmake_defines({
+        'BUILD_SHARED_LIBS': true,
+        'BASE64_WITH_AVX': false,
+        'BASE64_WITH_AVX2': false,
+        'BASE64_WITH_AVX512': false,
+        'BASE64_WITH_SSSE3': false,
+        'BASE64_WITH_SSE41': false,
+        'BASE64_WITH_SSE42': false})
+
+  libb64_ex = cmake.subproject('libb64', options: opt_var)
+  libb64 = libb64_ex.dependency('base64')
+endif
+
+libcper_parse_sources = [
+  'cper-parse.c',
+  'ir-parse.c',
+  'cper-utils.c',
+  'common-utils.c',
+  'json-schema.c'
+]
+
+libcper_include = ['.']
+
+libcper_parse = library(
+  'cper-parse',
+  libcper_parse_sources,
+  SectionSources,
+  EDKSources,
+  version: meson.project_version(),
+  include_directories:include_directories(libcper_include),
+  c_args: '-Wno-address-of-packed-member',
+  dependencies: [
+    json_c_dep,
+    libb64,
+  ],
+  install: true,
+  install_dir: get_option('libdir')
+)
+libcper_parse = declare_dependency(
+  include_directories: include_directories(libcper_include),
+  link_with: libcper_parse
+)
+
+
+libcper_generate_sources = [
+  'generator/cper-generate.c',
+  'generator/gen-utils.c',
+  'common-utils.c'
+]
+
+libcper_generate = library(
+  'cper-generate',
+  libcper_generate_sources,
+  GeneratorSectionSources,
+  version: meson.project_version(),
+  include_directories:include_directories(libcper_include),
+  dependencies: [
+    libcper_parse,
+    json_c_dep,
+    libb64,
+  ],
+  install: true,
+  install_dir: get_option('libdir')
+)
+libcper_generate = declare_dependency(
+  include_directories: include_directories(libcper_include),
+  link_with: libcper_generate
+)
+
+executable(
+  'cper-convert',
+  'cli-app/cper-convert.c',
+  include_directories:include_directories(libcper_include),
+  dependencies: [
+    libcper_parse,
+    json_c_dep,
+  ],
+  install: true
+)
+
+executable(
+  'cper-generate',
+  'generator/cper-generate-cli.c',
+  EDKSources,
+  include_directories:include_directories(libcper_include),
+  dependencies: [
+    libcper_generate,
+  ],
+  install: true
+)
+
+run_command('cp', '-r', 'specification/json/', meson.current_build_dir())
+run_command('mv', meson.current_build_dir() / 'json', meson.current_build_dir() / 'specification')
+
+if get_option('tests').allowed()
+  subdir('tests')
+endif
+
diff --git a/meson.options b/meson.options
new file mode 100644
index 0000000..0fc2767
--- /dev/null
+++ b/meson.options
@@ -0,0 +1 @@
+option('tests', type: 'feature', description: 'Build tests')
diff --git a/subprojects/googletest.wrap b/subprojects/googletest.wrap
new file mode 100644
index 0000000..56da9ef
--- /dev/null
+++ b/subprojects/googletest.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/google/googletest
+revision = HEAD
diff --git a/subprojects/json-c.wrap b/subprojects/json-c.wrap
new file mode 100644
index 0000000..577f30b
--- /dev/null
+++ b/subprojects/json-c.wrap
@@ -0,0 +1,13 @@
+[wrap-file]
+directory = json-c-0.16
+source_url = https://s3.amazonaws.com/json-c_releases/releases/json-c-0.16.tar.gz
+source_filename = json-c-0.16.tar.gz
+source_hash = 8e45ac8f96ec7791eaf3bb7ee50e9c2100bbbc87b8d0f1d030c5ba8a0288d96b
+patch_filename = json-c_0.16-4_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/json-c_0.16-4/get_patch
+patch_hash = 05c831dc8ea0a4e0fa05391a7cf40df05077d5e1700c5b586b1878f6f3903026
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/json-c_0.16-4/json-c-0.16.tar.gz
+wrapdb_version = 0.16-4
+
+[provide]
+json-c = json_c_dep
diff --git a/subprojects/libb64.wrap b/subprojects/libb64.wrap
new file mode 100644
index 0000000..3797ca7
--- /dev/null
+++ b/subprojects/libb64.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/aklomp/base64
+revision = 8bdda2d47caf8b066999c5bd01069e55bcd0d396
+
+[provide]
+libb64 = libb64_dep
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000..0d381a6
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,46 @@
+gtest = dependency('gtest', main: true, disabler: true, required: false)
+gmock = dependency('gmock', disabler: true, required: false)
+if not gtest.found() or not gmock.found()
+    gtest_proj = import('cmake').subproject('googletest', required: false)
+    if gtest_proj.found()
+        gtest = declare_dependency(
+            dependencies: [
+                dependency('threads'),
+                gtest_proj.dependency('gtest'),
+                gtest_proj.dependency('gtest_main'),
+            ]
+        )
+        gmock = gtest_proj.dependency('gmock')
+    else
+        assert(
+            not get_option('tests').allowed(),
+            'Googletest is required if tests are enabled'
+        )
+    endif
+endif
+
+sources = [
+  'ir-tests.cpp',
+  'test-utils.cpp',
+]
+
+test_include_dirs = ['.', '..']
+
+run_command('cp', '-r', '../specification/json/', meson.current_build_dir())
+run_command('mv', meson.current_build_dir() / 'json', meson.current_build_dir() / 'specification')
+
+tests = ['cper-tests']
+
+test('test-cper-tests',
+      executable('cper-tests',
+                  sources,
+                  implicit_include_directories: false,
+                  include_directories:include_directories(test_include_dirs),
+                  cpp_args: '-fpermissive',
+                  dependencies: [
+                    libcper_parse,
+                    libcper_generate,
+                    json_c_dep,
+                    gtest,
+                    gmock])
+)