merge binaries bmcweb and bmcwebd

Solution to reduce compressed rofs size.

Conclusion: The compiler is better at reducing binary size than the rofs
compression is at deduplicating sections of already compiled binaries,
in the case of bmcweb.

What's been changed?

`bmcweb` and `bmcwebd` have been merged into `bmcweb`.
The webserver can be started with `bmcweb daemon`.

Commands used to check size

```
wc -c build/s8030/tmp/work/*-openbmc-linux-gnueabi/obmc-phosphor-image/1.0/obmc-phosphor-image-1.0/static/image-rofs

wc -c build/s8030/tmp/deploy/images/s8030/image-rofs

xz -c build/s8030/tmp/work/*-openbmc-linux-gnueabi/obmc-phosphor-image/1.0/rootfs/bin/bmcweb | wc -c

xz -c build/s8030/tmp/work/*-openbmc-linux-gnueabi/obmc-phosphor-image/1.0/rootfs/usr/libexec/bmcwebd | wc -c
```

Base commit used for testing:
`2169e896448fac1b59c57516b381492e4b2161c7`

Results:

Before patch:
```
image-rofs compressed size:
25526272 build/s8030/tmp/work/s8030-openbmc-linux-gnueabi/obmc-phosphor-image/1.0/obmc-phosphor-image-1.0/static/image-rofs
rootfs
25526272 build/s8030/tmp/deploy/images/s8030/image-rofs
bmcweb cli
95424
bmcwebd
1016004
```

After patch:
```
image-rofs compressed size:
25477120 build/s8030/tmp/work/s8030-openbmc-linux-gnueabi/obmc-phosphor-image/1.0/obmc-phosphor-image-1.0/static/image-rofs
rootfs
25477120 build/s8030/tmp/deploy/images/s8030/image-rofs
bmcweb cli
96
bmcwebd
1059556
```

Calculating the difference in compressed rofs

25526272 - 25477120 = 49152

which is around 0.2% in terms of the total image but around 4.6% in
terms of bmcwebd binary.

Tested: on yosemite4 qemu

`bmcweb` cli interactions work as before.

```
root@yosemite4:~# bmcweb --help
BMCWeb CLI
Usage: bmcweb [OPTIONS] SUBCOMMAND

Options:
  -h,--help                   Print this help message and exit

Subcommands:
  loglevel                    Set bmcweb log level
  daemon                      Run webserver
root@yosemite4:~# bmcweb loglevel info
<6>[webserver_cli.cpp:97] logging level changed to: INFO
root@yosemite4:~# bmcweb loglevel
level is required
Run with --help for more information.
root@yosemite4:~# bmcweb loglevel debug
<6>[webserver_cli.cpp:97] logging level changed to: DEBUG
```

systemd service still working
```
root@yosemite4:~# systemctl status bmcweb
● bmcweb.service - Start bmcweb server
     Loaded: loaded (/usr/lib/systemd/system/bmcweb.service; enabled; preset: enabled)
     Active: active (running) since Thu 2025-04-03 13:35:45 PDT; 5 months 15 days ago
```

Change-Id: Ib5dde568ac1c12c5414294ed96404c6a69417424
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/config/bmcweb.service.in b/config/bmcweb.service.in
index 7d7a085..7ea392f 100644
--- a/config/bmcweb.service.in
+++ b/config/bmcweb.service.in
@@ -1,12 +1,12 @@
 [Unit]
-Description=Start bmcwebd server
+Description=Start bmcweb server
 
 Wants=network.target
 After=network.target
 
 [Service]
 ExecReload=kill -s HUP $MAINPID
-ExecStart=@MESON_INSTALL_PREFIX@/libexec/bmcwebd
+ExecStart=@MESON_INSTALL_PREFIX@/bin/bmcweb daemon
 Type=simple
 WorkingDirectory=/home/root
 SyslogLevelPrefix=true
diff --git a/docs/TESTING.md b/docs/TESTING.md
index 111d61a..ee4184e 100644
--- a/docs/TESTING.md
+++ b/docs/TESTING.md
@@ -29,7 +29,7 @@
 - Reduce binary size by stripping it when ready for testing
 
   ```sh
-  arm-openbmc-linux-gnueabi-strip bmcwebd
+  arm-openbmc-linux-gnueabi-strip bmcweb
   ```
 
   **Note:** Stripping is not required and having the debug symbols could be
@@ -39,7 +39,7 @@
 - Copy your bmcweb daemon you want to test to /tmp/ in QEMU
 
   ```sh
-  scp -P 2222 bmcwebd root@127.0.0.1:/tmp/
+  scp -P 2222 bmcweb root@127.0.0.1:/tmp/
   ```
 
   **Special Notes:** The address and port shown here (127.0.0.1 and 2222)
@@ -70,13 +70,13 @@
 - Remove the existing bmcweb daemon from the filesystem in QEMU
 
   ```sh
-  rm /usr/libexec/bmcwebd
+  rm /usr/bin/bmcweb
   ```
 
 - Link to your new bmcweb daemon in /tmp/
 
   ```sh
-  ln -sf /tmp/bmcwebd /usr/libexec/bmcwebd
+  ln -sf /tmp/bmcweb /usr/bin/bmcweb
   ```
 
 - Test your changes. bmcweb will be started automatically upon your first REST
diff --git a/meson.build b/meson.build
index 96a9383..205ee90 100644
--- a/meson.build
+++ b/meson.build
@@ -66,8 +66,6 @@
     ),
 ]
 
-incdir_cli = include_directories('http', 'include')
-
 # Add compiler arguments
 boost_flags = ['-Wno-unused-parameter']
 nghttp2_flags = []
@@ -210,7 +208,6 @@
 # Find the dependency modules, if not found use meson wrap to get them
 # automatically during the configure step
 bmcweb_dependencies = []
-bmcweb_cli_dependencies = []
 
 pam = cxx.find_library('pam', required: true)
 atomic = cxx.find_library('atomic', required: true)
@@ -252,7 +249,6 @@
 
 sdbusplus = dependency('sdbusplus')
 bmcweb_dependencies += sdbusplus
-bmcweb_cli_dependencies += sdbusplus
 
 cli11 = dependency('CLI11', required: false, include_type: 'system')
 if not cli11.found()
@@ -260,8 +256,7 @@
     cli11 = cli11_proj.get_variable('CLI11_dep')
     cli11 = cli11.as_system('system')
 endif
-bmcweb_cli_dependencies += cli11
-
+bmcweb_dependencies += cli11
 
 tinyxml = dependency(
     'tinyxml2',
@@ -316,7 +311,6 @@
 
 if boost.found()
     bmcweb_dependencies += [boost]
-    bmcweb_cli_dependencies += [boost]
 else
     cmake = import('cmake')
     opt = cmake.subproject_options()
@@ -345,14 +339,12 @@
     foreach boost_lib : boost_libs
         boost_lib_instance = boost.dependency('boost_' + boost_lib).as_system()
         bmcweb_dependencies += [boost_lib_instance]
-        bmcweb_cli_dependencies += [boost_lib_instance]
     endforeach
 endif
 
 systemd_system_unit_dir = systemd.get_variable('systemd_system_unit_dir')
 
 bindir = get_option('prefix') + '/' + get_option('bindir')
-libexec = get_option('prefix') + '/' + get_option('libexecdir')
 
 summary(
     {
@@ -369,7 +361,6 @@
 # Config subdirectory
 subdir('config')
 bmcweb_dependencies += conf_h_dep
-bmcweb_cli_dependencies += conf_h_dep
 
 test_sources = []
 subdir('features')
@@ -407,6 +398,7 @@
     'src/json_html_serializer.cpp',
     'src/ossl_random.cpp',
     'src/ssl_key_handler.cpp',
+    'src/webserver_cli.cpp',
     'src/webserver_run.cpp',
 )
 
@@ -417,25 +409,15 @@
     dependencies: bmcweb_dependencies,
 )
 
-# Generate the bmcwebd daemon
+# Generate the bmcweb daemon
 executable(
-    'bmcwebd',
+    'bmcweb',
     'src/webserver_main.cpp',
     include_directories: incdir,
     dependencies: bmcweb_dependencies,
     link_with: bmcweblib,
     link_args: '-Wl,--gc-sections',
     install: true,
-    install_dir: libexec,
-)
-
-# Generate the bmcweb CLI application
-executable(
-    'bmcweb',
-    ['src/webserver_cli.cpp', 'src/boost_asio.cpp'],
-    include_directories: incdir_cli,
-    dependencies: bmcweb_cli_dependencies,
-    install: true,
     install_dir: bindir,
 )
 
diff --git a/src/webserver_cli.cpp b/src/webserver_cli.cpp
index 58fbacb..a4ad819 100644
--- a/src/webserver_cli.cpp
+++ b/src/webserver_cli.cpp
@@ -1,7 +1,11 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
+
+#include "webserver_cli.hpp"
+
 #include "boost_formatters.hpp"
 #include "logging.hpp"
+#include "webserver_run.hpp"
 
 #include <CLI/CLI.hpp>
 #include <boost/asio/io_context.hpp>
@@ -46,18 +50,14 @@
     return help;
 }
 
-int main(int argc, char** argv) noexcept(false)
+static int loglevelMain(std::string& loglevel);
+
+int cliMain(int argc, char** argv) noexcept(false)
 {
-    CLI::App app("BMCWeb SetLogLevel CLI");
+    CLI::App app("BMCWeb CLI");
 
     cliLogLevel("INFO");
 
-    // Define sdbus interfaces:
-    std::string service = "xyz.openbmc_project.bmcweb";
-    std::string path = "/xyz/openbmc_project/bmcweb";
-    std::string iface = "xyz.openbmc_project.bmcweb";
-    std::string method = "SetLogLevel";
-
     std::string loglevel;
     app.require_subcommand(1);
 
@@ -69,8 +69,31 @@
         ->required()
         ->check(levelValidator);
 
+    CLI::App* daemon = app.add_subcommand("daemon", "Run webserver");
+
     CLI11_PARSE(app, argc, argv)
 
+    if (daemon->parsed())
+    {
+        return run();
+    }
+
+    if (sub->parsed())
+    {
+        return loglevelMain(loglevel);
+    }
+
+    return 0;
+}
+
+static int loglevelMain(std::string& loglevel)
+{
+    // Define sdbus interfaces:
+    std::string service = "xyz.openbmc_project.bmcweb";
+    std::string path = "/xyz/openbmc_project/bmcweb";
+    std::string iface = "xyz.openbmc_project.bmcweb";
+    std::string method = "SetLogLevel";
+
     std::transform(loglevel.begin(), loglevel.end(), loglevel.begin(),
                    ::toupper);
     // Set up dbus connection:
diff --git a/src/webserver_cli.hpp b/src/webserver_cli.hpp
new file mode 100644
index 0000000..0fe47af
--- /dev/null
+++ b/src/webserver_cli.hpp
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+
+int cliMain(int argc, char** argv) noexcept(false);
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 51d6576..159ec80 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
-#include "webserver_run.hpp"
 
-int main(int /*argc*/, char** /*argv*/) noexcept(false)
+#include "webserver_cli.hpp"
+
+int main(int argc, char** argv) noexcept(false)
 {
-    return run();
+    return cliMain(argc, argv);
 }