[IOT-2013] Windows: export C RD APIs from octbstack.dll
authorDan Mihai <Daniel.Mihai@microsoft.com>
Mon, 10 Apr 2017 23:57:41 +0000 (16:57 -0700)
committerMike Fenelon <mike.fenelon@microsoft.com>
Mon, 17 Apr 2017 22:16:26 +0000 (22:16 +0000)
Windows currently has several different copies of the implementation
for these APIs. Other platforms are using a single copy of shared
library resource_directory, in each process/app.

It's better to avoid differences across platforms, because otherwise
changes tested on one platform might not work on the other platforms.

Note that the C++ APIs for resource_directory clients remain inside
the static resource_directory.lib, so there can be multiple copies of
the C++ API implementation in each Windows process.

Change-Id: I07683359c265989d9921cd28da6ccd83d30f06af
Signed-off-by: Dan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/18775
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Mike Fenelon <mike.fenelon@microsoft.com>
build_common/windows/SConscript
resource/csdk/resource-directory/SConscript
resource/csdk/resource-directory/src/RDClient.cpp
resource/csdk/stack/SConscript
resource/csdk/stack/octbstack_product.def
resource/csdk/stack/octbstack_rd_client.def [new file with mode: 0644]
resource/csdk/stack/octbstack_rd_server.def [new file with mode: 0644]

index 172b72f..81ea3cf 100644 (file)
@@ -41,17 +41,16 @@ if env['CC'] == 'cl':
 
     env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 
-    # Work around [IOT-1986]
-    # During some Windows multi-threaded builds, SCons/Python/Pywin32 appear to try
-    # linking with oc.lib while another SCons thread started executing InstallTarget()
-    # for this static LIB, but didn't finish yet. That behavior results in linker errors.
-    # Work around this issue by linking with the source of InstallTarget(), rather
-    # than the target.
+    # Work around [IOT-1986]\r
+    # During some Windows multi-threaded builds, SCons/Python/Pywin32 appear to try\r
+    # linking with these static libraries while another SCons thread started executing\r
+    # InstallTarget() for this static LIB, but didn't finish yet. That behavior results\r
+    # in linker errors. Work around this issue by linking with the source of InstallTarget(),\r
+    # rather than the target.\r
     env.PrependUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource', 'src')])
-    
-    # Similar link issue described above [IOT-1986] is also observed when linking oc_logger.lib.
     env.PrependUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource', 'oc_logger')])
-    
+    env.PrependUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource', 'csdk', 'resource-directory')])
+
     env.AppendUnique(PATH = os.environ['PATH'])
     env['PDB'] = '${TARGET.base}.pdb'
     env.Append(LINKFLAGS=['/PDB:${TARGET.base}.pdb'])
index 4bae87b..af6d3ff 100755 (executable)
@@ -58,6 +58,9 @@ rd_env.PrependUnique(LIBS = ['octbstack', 'oc', 'oc_logger', 'connectivity_abstr
 
 if target_os not in ['windows']:
     rd_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x'])
+else:
+    # Non-Windows platforms find the boost headers under /usr/include or similar path.\r
+    rd_env.AppendUnique(CPPPATH = ['#/extlibs/boost/boost'])
 
 if target_os == 'android':
     rd_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
@@ -75,27 +78,38 @@ else:
 # Source files and Targets
 ######################################################################
 RD_SRC_DIR = 'src/'
-rd_src = []
+rd_src_c = []
+rd_src_cpp = []
 
 if 'SERVER' in rd_mode:
-    rd_src += [
+    rd_src_c += [
         RD_SRC_DIR + 'internal/rd_database.c',
         RD_SRC_DIR + 'rd_server.c',
         ]
     if target_os not in ['linux', 'tizen', 'windows'] :
-        rd_src += [ '../../../extlibs/sqlite3/sqlite3.c' ]
+        rd_src_c += [ '../../../extlibs/sqlite3/sqlite3.c' ]
 
 if 'CLIENT' in rd_mode:
-    rd_src += [RD_SRC_DIR + 'rd_client.c',]
-    if target_os not in ['arduino','darwin','ios', 'windows', 'winrt']:
-        rd_src += [ RD_SRC_DIR + 'RDClient.cpp',]
+    rd_src_c += [RD_SRC_DIR + 'rd_client.c',]
+
+rd_src_all = rd_src_c
+
+if target_os not in ['arduino','darwin','ios']:
+    rd_src_cpp += [ RD_SRC_DIR + 'RDClient.cpp']
+    if 'CLIENT' in rd_mode:
+        rd_src_all += rd_src_cpp
 
-if target_os not in ['arduino', 'darwin', 'ios', 'windows', 'winrt']:
-    rdsdk_shared = rd_env.SharedLibrary('resource_directory', rd_src)
-    rdsdk_static = rd_env.StaticLibrary('resource_directory', rd_src)
+if target_os not in ['arduino', 'darwin', 'ios', 'msys_nt', 'windows']:
+    rdsdk_shared = rd_env.SharedLibrary('resource_directory', rd_src_all)
+    rdsdk_static = rd_env.StaticLibrary('resource_directory', rd_src_all)
     rdsdk = Flatten([rdsdk_static, rdsdk_shared])
-else :
-    rdsdk = rd_env.StaticLibrary('resource_directory', rd_src)
+elif target_os in ['msys_nt', 'windows']:
+    rdsdk_c = rd_env.StaticLibrary('resource_directory_internal', rd_src_c)
+    rdsdk_cpp = rd_env.StaticLibrary('resource_directory', rd_src_cpp)
+    rdsdk = Flatten([rdsdk_c, rdsdk_cpp])
+else:
+    rdsdk = rd_env.StaticLibrary('resource_directory', rd_src_all)
+
 rd_env.InstallTarget(rdsdk, 'resource_directory')
 rd_env.UserInstallTargetLib(rdsdk, 'resource_directory')
 
index 9d0397a..94b5e8e 100644 (file)
@@ -22,8 +22,6 @@
 #include <mutex>
 
 #ifdef RD_CLIENT
-#include "RDClient.h"
-#include "rd_client.h"
 
 #include "OCApi.h"
 #include "OCRepresentation.h"
@@ -33,6 +31,9 @@
 #include "OCException.h"
 #include "ocpayload.h"
 
+#include "RDClient.h"
+#include "rd_client.h"
+
 using namespace OC;
 
 
index 1fe098f..beff618 100644 (file)
@@ -113,24 +113,43 @@ if target_os not in ['windows', 'msys_nt']:
     liboctbstack_env.AppendUnique(LIBS = ['m'])
 else:
     liboctbstack_env.AppendUnique(CCFLAGS=['/W4', '/WX'])
+
     # octbstack.def specifies the list of functions exported by octbstack.dll.
     liboctbstack_env.Replace(WINDOWS_INSERT_DEF = ['1'])
 
+    if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
+        # On Windows:
+        # - octbstack.dll is exporting resource_directory C APIs
+        # - resource_directory.lib contains just the implementation of the C++ RD APIs
+        liboctbstack_env.PrependUnique(LIBS = ['resource_directory_internal'])
+
+    if 'CLIENT' in rd_mode:
+        liboctbstack_env.Textfile(target = 'octbstack_temp1.def', source = [File('octbstack_product.def'), File('octbstack_rd_client.def')])
+    else:
+        liboctbstack_env.Textfile(target = 'octbstack_temp1.def', source = [File('octbstack_product.def')])
+
+    if 'SERVER' in rd_mode:
+        liboctbstack_env.Textfile(target = 'octbstack_temp2.def', source = [File('octbstack_temp1.def'), File('octbstack_rd_server.def')])
+    else:
+        liboctbstack_env.Textfile(target = 'octbstack_temp2.def', source = [File('octbstack_temp1.def')])
+
     if env.get('SECURED') != '1':
-        liboctbstack_env.Textfile(target = 'octbstack.def', source = [File('octbstack_product.def')])
+        liboctbstack_env.Textfile(target = 'octbstack.def', source = [File('octbstack_temp2.def')])
     else:
         # octbstack.dll is exporting ocpmapi APIs on Windows - there is no ocpmapi.dll.
         liboctbstack_env.PrependUnique(LIBS = ['ocpmapi'])
 
+        liboctbstack_env.Textfile(target = 'octbstack_temp3.def', source = [File('octbstack_temp2.def'), File('octbstack_product_secured.def')])
+
         if with_tcp == True:
-            liboctbstack_env.Textfile(target = 'octbstack_temp.def', source = [File('octbstack_product.def'), File('octbstack_product_with_tcp.def')])
+            liboctbstack_env.Textfile(target = 'octbstack_temp4.def', source = [File('octbstack_temp3.def'), File('octbstack_product_with_tcp.def')])
         else:
-            liboctbstack_env.Textfile(target = 'octbstack_temp.def', source = [File('octbstack_product.def')])
+            liboctbstack_env.Textfile(target = 'octbstack_temp4.def', source = [File('octbstack_temp3.def')])
 
         if env.get('MULTIPLE_OWNER') == '1':
-            liboctbstack_env.Textfile(target = 'octbstack.def', source = [File('octbstack_temp.def'), File('octbstack_product_secured.def'), File('octbstack_product_secured_mot.def')])
+            liboctbstack_env.Textfile(target = 'octbstack.def', source = [File('octbstack_temp4.def'), File('octbstack_product_secured_mot.def')])
         else:
-            liboctbstack_env.Textfile(target = 'octbstack.def', source = [File('octbstack_temp.def'), File('octbstack_product_secured.def')])
+            liboctbstack_env.Textfile(target = 'octbstack.def', source = [File('octbstack_temp4.def')])
 
 if target_os in ['tizen', 'linux']:
     liboctbstack_env.ParseConfig("pkg-config --cflags --libs uuid")
index fe4bc35..ff8952b 100644 (file)
@@ -64,9 +64,6 @@ OCNotifyListOfObservers
 OCPayloadDestroy
 OCPresencePayloadCreate
 OCProcess
-OCRDDatabaseDiscoveryPayloadCreate
-OCRDDatabaseGetStorageFilename
-OCRDDatabaseSetStorageFilename
 OCRegisterPersistentStorageHandler
 OCRepPayloadAddInterface
 OCRepPayloadAddResourceType
diff --git a/resource/csdk/stack/octbstack_rd_client.def b/resource/csdk/stack/octbstack_rd_client.def
new file mode 100644 (file)
index 0000000..0e322c9
--- /dev/null
@@ -0,0 +1,7 @@
+; APIs used when RD_MODE includes CLIENT
+
+OCRDDelete
+OCRDDeleteWithDeviceId
+OCRDDiscover
+OCRDPublish
+OCRDPublishWithDeviceId
diff --git a/resource/csdk/stack/octbstack_rd_server.def b/resource/csdk/stack/octbstack_rd_server.def
new file mode 100644 (file)
index 0000000..8cdba70
--- /dev/null
@@ -0,0 +1,11 @@
+; APIs used when RD_MODE includes SERVER
+
+OCRDDatabaseInit
+OCRDDatabaseClose
+OCRDDatabaseDeleteResources
+OCRDDatabaseDiscoveryPayloadCreate
+OCRDDatabaseGetStorageFilename
+OCRDDatabaseSetStorageFilename
+OCRDDatabaseStoreResources
+OCRDStart
+OCRDStop