Browse Source

generate encoding inline functions into a separate header

Julius Pfrommer 9 years ago
parent
commit
e5f2af8a2d

+ 12 - 8
CMakeLists.txt

@@ -48,7 +48,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")
     # binary size reduction settings
     add_definitions(-ffunction-sections -fdata-sections -fno-stack-protector -fno-unwind-tables
                     -fno-asynchronous-unwind-tables -fno-math-errno -fmerge-all-constants -fno-ident)
-  if (APPLE)
+  if(APPLE)
       set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-dead_strip")
       set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
   else()
@@ -56,19 +56,18 @@ if(CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")
       set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
   endif()
   set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # cmake sets -rdynamic by default
-	if(NOT WIN32)
-     if(NOT CYGWIN)
+	if(NOT WIN32 AND NOT CYGWIN)
 	    add_definitions(-fvisibility=hidden -fPIC)
-      if (NOT APPLE)
-          set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none")
-      endif()
+      if(NOT APPLE)
+        # these settings reduce the binary size by ~2kb
+        set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none")
       endif()
 	endif()
     if(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR CMAKE_BUILD_TYPE STREQUAL "Release")
         set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -s")
         set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s")
     endif()
-    if (APPLE)
+    if(APPLE)
         set(CMAKE_MACOSX_RPATH 1)
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DARWIN_C_SOURCE=1")
     endif()
@@ -91,8 +90,10 @@ set(exported_headers ${PROJECT_BINARY_DIR}/src_generated/ua_config.h
                      ${PROJECT_SOURCE_DIR}/examples/logger_stdout.h)
 set(internal_headers ${PROJECT_SOURCE_DIR}/src/ua_util.h
                      ${PROJECT_SOURCE_DIR}/deps/queue.h
-                     ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated.h
                      ${PROJECT_SOURCE_DIR}/src/ua_types_encoding_binary.h
+                     ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated_encoding_binary.h
+                     ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated.h
+                     ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated_encoding_binary.h
                      ${PROJECT_SOURCE_DIR}/src/ua_securechannel.h
                      ${PROJECT_SOURCE_DIR}/src/server/ua_nodes.h
                      ${PROJECT_SOURCE_DIR}/src/ua_session.h
@@ -143,6 +144,7 @@ if(ENABLE_SUBSCRIPTIONS)
 
   add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.c
                             ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h
+                            ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated_encoding_binary.h
                      PRE_BUILD
                      COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_datatypes.py --enable-subscription-types=1 --typedescriptions ${PROJECT_SOURCE_DIR}/tools/schema/NodeIds.csv 0 ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.Types.bsd ${PROJECT_BINARY_DIR}/src_generated/ua_types
                      DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/generate_datatypes.py
@@ -151,6 +153,7 @@ if(ENABLE_SUBSCRIPTIONS)
 else()
 add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.c
                           ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h
+                          ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated_encoding_binary.h
                    PRE_BUILD
                    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_datatypes.py --typedescriptions ${PROJECT_SOURCE_DIR}/tools/schema/NodeIds.csv 0 ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.Types.bsd ${PROJECT_BINARY_DIR}/src_generated/ua_types
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/generate_datatypes.py
@@ -160,6 +163,7 @@ endif()
 
 add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated.c
                           ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated.h
+                          ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated_encoding_binary.h
                    PRE_BUILD
                    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_datatypes.py --ns0-types-xml ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.Types.bsd 1 ${PROJECT_SOURCE_DIR}/tools/schema/Custom.Opc.Ua.Transport.bsd ${PROJECT_BINARY_DIR}/src_generated/ua_transport
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/generate_datatypes.py

+ 2 - 0
src/client/ua_client.c

@@ -5,6 +5,8 @@
 #include "ua_securechannel.h"
 #include "ua_types_encoding_binary.h"
 #include "ua_transport_generated.h"
+#include "ua_types_generated_encoding_binary.h"
+#include "ua_transport_generated_encoding_binary.h"
 #include "ua_client_internal.h"
 
 typedef enum {

+ 3 - 3
src/server/ua_server_binary.c

@@ -1,11 +1,11 @@
 #include "ua_util.h"
 #include "ua_server_internal.h"
-#include "ua_types_encoding_binary.h"
-#include "ua_transport_generated.h"
 #include "ua_services.h"
-#include "ua_statuscodes.h"
 #include "ua_securechannel_manager.h"
 #include "ua_session_manager.h"
+#include "ua_types_generated_encoding_binary.h"
+#include "ua_transport_generated.h"
+#include "ua_transport_generated_encoding_binary.h"
 
 /** Max size of messages that are allocated on the stack */
 #define MAX_STACK_MESSAGE 65536

+ 1 - 0
src/server/ua_services_nodemanagement.c

@@ -4,6 +4,7 @@
 #include "ua_statuscodes.h"
 #include "ua_nodestore.h"
 #include "ua_session.h"
+#include "ua_types_generated_encoding_binary.h"
 
 #define COPY_STANDARDATTRIBUTES do {  \
     if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_DISPLAYNAME) {     \

+ 1 - 0
src/server/ua_services_session.c

@@ -1,6 +1,7 @@
 #include "ua_services.h"
 #include "ua_server_internal.h"
 #include "ua_session_manager.h"
+#include "ua_types_generated_encoding_binary.h"
 
 void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
                            const UA_CreateSessionRequest *request,

+ 1 - 0
src/ua_securechannel.c

@@ -2,6 +2,7 @@
 #include "ua_securechannel.h"
 #include "ua_session.h"
 #include "ua_types_encoding_binary.h"
+#include "ua_transport_generated_encoding_binary.h"
 
 void UA_SecureChannel_init(UA_SecureChannel *channel) {
     UA_MessageSecurityMode_init(&channel->securityMode);

+ 0 - 3
src/ua_util.h

@@ -3,9 +3,6 @@
 
 #include "ua_config.h"
 
- /* This activates the encoding definitions in the types_generated headers */
-#define UA_INTERNAL
-
 /*********************/
 /* Memory Management */
 /*********************/

+ 6 - 1
tools/amalgamate.py

@@ -58,7 +58,12 @@ if not is_c:
 else:
     file.write(u'''#ifndef UA_DYNAMIC_LINKING
 # define UA_DYNAMIC_LINKING
-#endif\n\n''')
+#endif
+
+#ifndef UA_INTERNAL
+#define UA_INTERNAL
+#endif
+\n''')
     file.write(u"#include \"" + outname + ".h\"\n")
 
 for fname in args.inputs:

+ 37 - 18
tools/generate_datatypes.py

@@ -187,11 +187,11 @@ class EnumerationType(object):
 static UA_INLINE void %s_init(%s *p) { UA_Int32_init((UA_Int32*)p); }
 static UA_INLINE void %s_delete(%s *p) { UA_Int32_delete((UA_Int32*)p); }
 static UA_INLINE void %s_deleteMembers(%s *p) { }
-static UA_INLINE UA_StatusCode %s_copy(const %s *src, %s *dst) { return UA_Int32_copy((const UA_Int32*)src, (UA_Int32*)dst); }
-#ifdef UA_INTERNAL
-static UA_INLINE UA_StatusCode %s_encodeBinary(const %s *src, UA_ByteString *dst, size_t *offset) { return UA_Int32_encodeBinary((const UA_Int32*)src, dst, offset); }
-static UA_INLINE UA_StatusCode %s_decodeBinary(const UA_ByteString *src, size_t *offset, %s *dst) { return UA_Int32_decodeBinary(src, offset, (UA_Int32*)dst); }
-#endif''' % tuple(itertools.repeat(self.name, 17))
+static UA_INLINE UA_StatusCode %s_copy(const %s *src, %s *dst) { return UA_Int32_copy((const UA_Int32*)src, (UA_Int32*)dst); }''' % tuple(itertools.repeat(self.name, 13))
+
+    def encoding_h(self, typeTableName):
+        return '''static UA_INLINE UA_StatusCode %s_encodeBinary(const %s *src, UA_ByteString *dst, size_t *offset) { return UA_Int32_encodeBinary((const UA_Int32*)src, dst, offset); }
+static UA_INLINE UA_StatusCode %s_decodeBinary(const UA_ByteString *src, size_t *offset, %s *dst) { return UA_Int32_decodeBinary(src, offset, (UA_Int32*)dst); }''' % tuple(itertools.repeat(self.name, 4))
 
 class OpaqueType(object):
     def __init__(self, name, description = ""):
@@ -222,11 +222,11 @@ class OpaqueType(object):
 static UA_INLINE void %s_init(%s *p) { UA_ByteString_init((UA_ByteString*)p); }
 static UA_INLINE void %s_delete(%s *p) { UA_ByteString_delete((UA_ByteString*)p); }
 static UA_INLINE void %s_deleteMembers(%s *p) { }
-static UA_INLINE UA_StatusCode %s_copy(const %s *src, %s *dst) { return UA_ByteString_copy((const UA_ByteString*)src, (UA_ByteString*)dst); }
-#ifdef UA_INTERNAL
-static UA_INLINE UA_StatusCode %s_encodeBinary(const %s *src, UA_ByteString *dst, size_t *offset) { return UA_ByteString_encodeBinary((UA_ByteString*)src, dst, offset); }
-static UA_INLINE UA_StatusCode %s_decodeBinary(const UA_ByteString *src, size_t *offset, %s *dst) { return UA_ByteString_decodeBinary(src, offset, (UA_ByteString*)dst); }
-#endif''' % tuple(itertools.repeat(self.name, 17))
+static UA_INLINE UA_StatusCode %s_copy(const %s *src, %s *dst) { return UA_ByteString_copy((const UA_ByteString*)src, (UA_ByteString*)dst); }''' % tuple(itertools.repeat(self.name, 13))
+
+    def encoding_h(self, typeTableName):
+        return '''static UA_INLINE UA_StatusCode %s_encodeBinary(const %s *src, UA_ByteString *dst, size_t *offset) { return UA_ByteString_encodeBinary((UA_ByteString*)src, dst, offset); }
+static UA_INLINE UA_StatusCode %s_decodeBinary(const UA_ByteString *src, size_t *offset, %s *dst) { return UA_ByteString_decodeBinary(src, offset, (UA_ByteString*)dst); }''' % tuple(itertools.repeat(self.name, 4))
 
 class StructMember(object):
     def __init__(self, name, memberType, isArray):
@@ -330,14 +330,14 @@ class StructType(object):
 static UA_INLINE void %s_init(%s *p) { UA_init(p, %s); }
 static UA_INLINE void %s_delete(%s *p) { UA_delete(p, %s); }
 static UA_INLINE void %s_deleteMembers(%s *p) { UA_deleteMembers(p, %s); }
-static UA_INLINE UA_StatusCode %s_copy(const %s *src, %s *dst) { return UA_copy(src, dst, %s); }
-#ifdef UA_INTERNAL
-static UA_INLINE UA_StatusCode %s_encodeBinary(const %s *src, UA_ByteString *dst, size_t *offset) { return UA_encodeBinary(src, %s, dst, offset); }
-static UA_INLINE UA_StatusCode %s_decodeBinary(const UA_ByteString *src, size_t *offset, %s *dst) { return UA_decodeBinary(src, offset, dst, %s); }
-#endif''' % \
+static UA_INLINE UA_StatusCode %s_copy(const %s *src, %s *dst) { return UA_copy(src, dst, %s); }''' % \
     tuple(list(itertools.chain(*itertools.repeat([self.name, self.name, "&"+typeTableName+"[" + typeTableName + "_" + self.name[3:].upper()+"]"], 4)))
-          + [self.name, self.name, self.name, "&"+typeTableName+"[" + typeTableName + "_" + self.name[3:].upper()+"]"]
-          + list(itertools.chain(*itertools.repeat([self.name, self.name, "&"+typeTableName+"[" + typeTableName + "_" + self.name[3:].upper()+"]"], 2))))
+          + [self.name, self.name, self.name, "&"+typeTableName+"[" + typeTableName + "_" + self.name[3:].upper()+"]"])
+
+    def encoding_h(self, typeTableName):
+        return '''static UA_INLINE UA_StatusCode %s_encodeBinary(const %s *src, UA_ByteString *dst, size_t *offset) { return UA_encodeBinary(src, %s, dst, offset); }
+static UA_INLINE UA_StatusCode %s_decodeBinary(const UA_ByteString *src, size_t *offset, %s *dst) { return UA_decodeBinary(src, offset, dst, %s); }''' % \
+    tuple(list(itertools.chain(*itertools.repeat([self.name, self.name, "&"+typeTableName+"[" + typeTableName + "_" + self.name[3:].upper()+"]"], 2))))
 
 def parseTypeDefinitions(xmlDescription, existing_types = OrderedDict()):
     '''Returns an ordered dict that maps names to types. The order is such that
@@ -480,9 +480,12 @@ if args.typedescriptions:
     typedescriptions = parseTypeDescriptions(args.typedescriptions, args.namespace_id)
 
 fh = open(args.outfile + "_generated.h",'w')
+fe = open(args.outfile + "_generated_encoding_binary.h",'w')
 fc = open(args.outfile + "_generated.c",'w')
 def printh(string):
     print(string, end='\n', file=fh)
+def printe(string):
+    print(string, end='\n', file=fe)
 def printc(string):
     print(string, end='\n', file=fc)
 
@@ -504,7 +507,7 @@ extern "C" {
 
 #include "ua_types.h"
 #ifdef UA_INTERNAL
-# include "ua_types_encoding_binary.h"
+#include "ua_types_encoding_binary.h"
 #endif'''
  + ('\n#include "ua_types_generated.h"\n' if args.namespace_id != 0 else '') + '''
 
@@ -545,6 +548,17 @@ printh('''
 #endif\n
 #endif /* %s_GENERATED_H_ */''' % outname.upper())
 
+printe('''/**
+* @file ''' + outname + '''_generated_encoding_binary.h
+*
+* @brief Binary encoding for autogenerated data types
+*
+* Generated from ''' + inname + ''' with script ''' + sys.argv[0] + '''
+* on host ''' + platform.uname()[1] + ''' by user ''' + getpass.getuser() + ''' at ''' + time.strftime("%Y-%m-%d %I:%M:%S") + '''
+*/\n
+#include "ua_types_encoding_binary.h"
+#include "''' + outname + '''_generated.h"''')
+
 printc('''/**
 * @file ''' + outname + '''_generated.c
 *
@@ -569,6 +583,10 @@ for t in values:
     else:
         td = None
     printc(t.typelayout_c(args.namespace_id == 0, td, outname) + ",")
+    if not type(t) == BuiltinType:
+        printe("")
+        printe("/* " + t.name + " */")
+        printe(t.encoding_h(outname.upper()))
 printc("};\n")
 # if args.typedescriptions:
 #     printc('const UA_UInt32 *' + outname.upper() + '_IDS = (UA_UInt32[]){')
@@ -577,4 +595,5 @@ printc("};\n")
 #     printc("};")
 
 fh.close()
+fe.close()
 fc.close()