main: now seeks out shared library handlers are load-time

phosphor-ipmi-blobs now detects blob handlers compiled into shared
libraries on the BMC and loads them at start-up when it's loaded by
phosphor-host-ipmid.

Change-Id: Ib1b6b8f75aa544a263d37f71e133a9a188704de3
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/Makefile.am b/Makefile.am
index 9027e47..2c31b57 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,11 +1,5 @@
 AM_DEFAULT_SOURCE_EXT = .cpp
 
-HANDLERS =
-
-if ENABLE_EXAMPLE
-HANDLERS += example/example.cpp
-endif
-
 libblobcmdsdir = ${libdir}/ipmid-providers
 libblobcmds_LTLIBRARIES = libblobcmds.la
 libblobcmds_la_SOURCES = main.cpp \
@@ -13,8 +7,7 @@
 			 manager.cpp \
 			 process.cpp \
 			 crc.cpp \
-			 utils.cpp \
-			 $(HANDLERS)
+			 utils.cpp
 
 libblobcmds_la_LDFLAGS = $(SYSTEMD_LIBS) \
 			 $(LIBADD_DLOPEN) \
@@ -29,4 +22,14 @@
 	blobs-ipmid/blobs.hpp \
 	blobs-ipmid/manager.hpp
 
+# Always build but only installed if you add the item:
+# BLOBIPMI_PROVIDER_LIBRARY += "libexample.so"
+libexampledir = ${libdir}/blob-providers
+libexample_LTLIBRARIES = libexample.la
+libexample_la_SOURCES = example/example.cpp
+libexample_la_LDFLAGS = $(PHOSPHOR_LOGGING_LIBS) \
+			-version-info 0:0:0 -shared
+libexample_la_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS) \
+			 -flto
+
 SUBDIRS = . test
diff --git a/configure.ac b/configure.ac
index 21fcde9..efdd0b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,16 +55,6 @@
     AC_SUBST([OESDK_TESTCASE_FLAGS], [$testcase_flags])
 )
 
-# Do you want to include the example blob handler?
-AC_ARG_ENABLE([example],
-    AS_HELP_STRING([--enable-example], [Enable example blob handler])
-)
-AM_CONDITIONAL(ENABLE_EXAMPLE, [test "x$enable_example" = "xyes"])
-AS_IF([test "x$enable_example" = "xyes"],
-    [AC_DEFINE(ENABLE_EXAMPLE, [1], [Build and install the example handler.])],
-    [AC_DEFINE(ENABLE_EXAMPLE, [0], [Do not build and install the example handler.])]
-)
-
 # Create configured output
 AC_CONFIG_FILES([Makefile test/Makefile])
 AC_OUTPUT
diff --git a/example/example.cpp b/example/example.cpp
index 66c8227..9209798 100644
--- a/example/example.cpp
+++ b/example/example.cpp
@@ -1,13 +1,18 @@
 #include "example/example.hpp"
 
 #include <algorithm>
+#include <blobs-ipmid/manager.hpp>
 #include <cstring>
+#include <memory>
+#include <phosphor-logging/log.hpp>
 #include <string>
 #include <vector>
 
 namespace blobs
 {
 
+using namespace phosphor::logging;
+
 constexpr char ExampleBlobHandler::supportedPath[];
 
 ExampleBlob* ExampleBlobHandler::getSession(uint16_t id)
@@ -165,4 +170,15 @@
     return false;
 }
 
+void setupExampleHandler() __attribute__((constructor));
+
+void setupExampleHandler()
+{
+    BlobManager* manager = getBlobManager();
+    if (!manager->registerHandler(std::make_unique<ExampleBlobHandler>()))
+    {
+        log<level::ERR>("Failed to register Example Handler");
+    }
+}
+
 } // namespace blobs
diff --git a/main.cpp b/main.cpp
index e0828db..f897fda 100644
--- a/main.cpp
+++ b/main.cpp
@@ -18,6 +18,7 @@
 
 #include "ipmi.hpp"
 #include "process.hpp"
+#include "utils.hpp"
 
 #include <host-ipmid/ipmid-api.h>
 
@@ -26,10 +27,6 @@
 #include <host-ipmid/oemrouter.hpp>
 #include <memory>
 
-#if ENABLE_EXAMPLE
-#include "example/example.hpp"
-#endif
-
 /* TODO: Swap out once https://gerrit.openbmc-project.xyz/12743 is merged */
 namespace oem
 {
@@ -63,6 +60,9 @@
                               dataLen);
 }
 
+/* TODO: this should come from the makefile or recipe... */
+constexpr auto expectedHandlerPath = "/usr/lib/blobs-ipmid";
+
 void setupBlobGlobalHandler() __attribute__((constructor));
 
 void setupBlobGlobalHandler()
@@ -75,9 +75,7 @@
     oemRouter->registerHandler(oem::obmcOemNumber, oem::blobTransferCmd,
                                handleBlobCommand);
 
-#if ENABLE_EXAMPLE
-    BlobManager* manager = getBlobManager();
-    manager->registerHandler(std::move(std::make_unique<ExampleBlobHandler>()));
-#endif
+    /* Install handlers. */
+    loadLibraries(expectedHandlerPath);
 }
 } // namespace blobs