[openweave-core] Support shared library targets

Add sub-targets into the adaptation template so that targets can
explicitly depend on shared library variants of the adaptation library.
This additionally adds symbol visibility to the definitions of externs
and critical public classes.

Bug: 62320
Test: fx test weavestack-unittests
Test: fx test weavestack-adaptation-unittests
Change-Id: Iabe1aa137f9c58d258c2c3f50d2cf2ab59fbf29e
diff --git a/device-layer.gni b/device-layer.gni
index 576288a..1daec3e 100644
--- a/device-layer.gni
+++ b/device-layer.gni
@@ -3,9 +3,61 @@
 # found in the LICENSE file.
 import("//third_party/openweave-core/config.gni")
 
+# Builds OpenWeave with the given adaptation-layer sources. OpenWeave splits out
+# platform-specific code into //third_party/openweave-core/src/adaptation, which
+# may exist outside the tree. This template generates the following targets:
+#
+# target_name.sources:
+#   A source_set of implementation code, packaged with the headers.
+# target_name.headers:
+#   A source_set of headers only, including openweave-core and adaptation headers.
+# target_name.shared:
+#   A shared_library of implementation code, packaged with the headers.
+#
+# By default, depending on this target will return target_name.sources. Targets
+# can depend on the shared library explicitly, but must be aware that only headers
+# explicitly marked with NL_DLL_EXPORT will be visible.
 template("openweave_adaptation_layer") {
   top_builddir = rebase_path("//third_party/openweave-core")
-  source_set(target_name) {
+  _library_name = target_name
+
+  # Implementation sources must be defined in order to build.
+  assert(defined(invoker.sources), "Sources must be defined.")
+
+  # Create public_configs set for all sub-targets.
+  _public_configs = [
+    ":${target_name}.openweave_config",
+    "//third_party/openweave-core/src/include:public",
+  ]
+  if (defined(invoker.public_configs)) {
+    _public_configs += invoker.public_configs
+  }
+
+  # Create configs set for all sub-targets.
+  _configs = []
+  if (defined(invoker.configs)) {
+    _configs += invoker.configs
+  }
+
+  # Default target includes sources, components should depend on the sub-targets
+  # if only headers or a shared library is required.
+  group(target_name) {
+    public_deps = [ ":${_library_name}.sources" ]
+  }
+
+  target("source_set", "${_library_name}.headers") {
+    sources = filter_include(invoker.sources,
+                             [
+                               "*.h",
+                               "*.hpp",
+                             ])
+    public_deps = [ ":${_library_name}.public_deps" ]
+    public_configs = _public_configs
+    deps = [ ":${_library_name}.deps" ]
+    configs += _configs
+  }
+
+  target("source_set", "${_library_name}.sources") {
     sources = [
       "$top_builddir/src/adaptations/device-layer/DeviceControlServer.cpp",
       "$top_builddir/src/adaptations/device-layer/DeviceDescriptionServer.cpp",
@@ -36,37 +88,56 @@
       "$top_builddir/src/adaptations/device-layer/trait-support/weave/trait/locale/LocaleSettingsTrait.cpp",
       "$top_builddir/src/adaptations/device-layer/trait-support/weave/trait/telemetry/tunnel/TelemetryTunnelTrait.cpp",
     ]
-    public_configs = [
-      ":" + target_name + "_openweave_config",
-      "//third_party/openweave-core/src/include:public",
+    sources += filter_include(invoker.sources,
+                              [
+                                "*.cc",
+                                "*.cpp",
+                                "*.ipp",
+                              ])
+
+    public_deps = [
+      ":${_library_name}.headers",
+      ":${_library_name}.public_deps",
     ]
+    public_configs = _public_configs
+    deps = [ ":${_library_name}.deps" ]
+    configs += _configs
+  }
+
+  target("shared_library", "${_library_name}.shared") {
+    public_deps = [
+      ":${_library_name}.headers",
+      ":${_library_name}.public_deps",
+    ]
+    public_configs = _public_configs
+    deps = [
+      ":${_library_name}.deps",
+      ":${_library_name}.sources",
+    ]
+    configs += _configs
+
+    # Explicitly build the library with -fPIC.
+    configs += [ ":${_library_name}.linker_config" ]
+  }
+
+  group("${_library_name}.public_deps") {
     public_deps = [
       "//third_party/openweave-core/src/include:DeviceLayer_headers",
       "//third_party/openweave-core/src/include:common",
     ]
-    deps = []
-
-    # Implementation sources must be defined in order to build.
-    assert(defined(invoker.sources),
-           "Adaptation layer sources must be defined.")
-    sources += invoker.sources
-
-    # Merge any configs and deps from the invoker.
-    if (defined(invoker.configs)) {
-      configs += invoker.configs
-    }
-    if (defined(invoker.public_configs)) {
-      public_configs += invoker.public_configs
-    }
     if (defined(invoker.public_deps)) {
       public_deps += invoker.public_deps
     }
+  }
+
+  group("${_library_name}.deps") {
+    deps = []
     if (defined(invoker.deps)) {
       deps += invoker.deps
     }
   }
 
-  config(target_name + "_openweave_config") {
+  config("${_library_name}.openweave_config") {
     include_dirs = [
       "$top_builddir/src/adaptations/device-layer/include",
       "$top_builddir/src/adaptations/device-layer/trait-support",
@@ -75,4 +146,8 @@
       include_dirs += invoker.include_dirs
     }
   }
+
+  config("${_library_name}.linker_config") {
+    cflags = [ "-fPIC" ]
+  }
 }
diff --git a/src/adaptations/device-layer/Fuchsia/Logging.cpp b/src/adaptations/device-layer/Fuchsia/Logging.cpp
index c6b580a..c50628a 100644
--- a/src/adaptations/device-layer/Fuchsia/Logging.cpp
+++ b/src/adaptations/device-layer/Fuchsia/Logging.cpp
@@ -35,6 +35,7 @@
 namespace Weave {
 namespace Logging {
 
+NL_DLL_EXPORT
 void Log(uint8_t module, uint8_t category, const char * file, uint32_t line, const char * msg, va_list v)
 {
     if (IsCategoryEnabled(category))
@@ -74,6 +75,7 @@
     }
 }
 
+NL_DLL_EXPORT
 void Log(uint8_t module, uint8_t category, const char * msg, ...)
 {
     va_list vargs;
@@ -82,6 +84,7 @@
     va_end(vargs);
 }
 
+NL_DLL_EXPORT
 void Log(uint8_t module, uint8_t category, const char * file, uint32_t line, const char * msg, ...)
 {
     va_list vargs;
diff --git a/src/adaptations/device-layer/PersistedStorage.cpp b/src/adaptations/device-layer/PersistedStorage.cpp
index 9a7b37e..70e1df6 100644
--- a/src/adaptations/device-layer/PersistedStorage.cpp
+++ b/src/adaptations/device-layer/PersistedStorage.cpp
@@ -32,11 +32,13 @@
 
 using namespace ::nl::Weave::DeviceLayer;
 
+NL_DLL_EXPORT
 WEAVE_ERROR Read(Key key, uint32_t & value)
 {
     return ConfigurationMgr().ReadPersistedStorageValue(key, value);
 }
 
+NL_DLL_EXPORT
 WEAVE_ERROR Write(Key key, uint32_t value)
 {
     return ConfigurationMgr().WritePersistedStorageValue(key, value);
diff --git a/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.h b/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.h
index a80c9a6..d5c886a 100644
--- a/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.h
+++ b/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.h
@@ -43,7 +43,7 @@
  * parameter.
  */
 template<class ImplClass>
-class GenericConfigurationManagerImpl
+class NL_DLL_EXPORT GenericConfigurationManagerImpl
 {
 public:
 
diff --git a/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericPlatformManagerImpl.h b/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericPlatformManagerImpl.h
index 12733a9..5de012b 100644
--- a/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericPlatformManagerImpl.h
+++ b/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericPlatformManagerImpl.h
@@ -39,7 +39,7 @@
  * parameter.
  */
 template<class ImplClass>
-class GenericPlatformManagerImpl
+class NL_DLL_EXPORT GenericPlatformManagerImpl
 {
 protected:
 
diff --git a/src/lib/core/HostPortList.h b/src/lib/core/HostPortList.h
index 7151b54..c1f5db8 100644
--- a/src/lib/core/HostPortList.h
+++ b/src/lib/core/HostPortList.h
@@ -30,6 +30,7 @@
 #include <stdint.h>
 
 #include <Weave/Core/WeaveError.h>
+#include <Weave/Support/NLDLLUtil.h>
 
 namespace nl {
 namespace Weave {
@@ -43,7 +44,7 @@
  *    associated with the Weave Service Directory.
  *
  */
-class HostPortList
+class NL_DLL_EXPORT HostPortList
 {
  public:
     HostPortList(void);
diff --git a/src/lib/profiles/data-management/Current/SubscriptionEngine.h b/src/lib/profiles/data-management/Current/SubscriptionEngine.h
index 941c7a8..2ca6add 100644
--- a/src/lib/profiles/data-management/Current/SubscriptionEngine.h
+++ b/src/lib/profiles/data-management/Current/SubscriptionEngine.h
@@ -68,7 +68,7 @@
  * @brief This is a singleton hosting all WDM Next subscriptions, both client and publisher sides.
  *
  */
-class SubscriptionEngine
+class NL_DLL_EXPORT SubscriptionEngine
 {
 public:
     /**