Bläddra i källkod

NodesetCompiler: Add ua_generate_nodeset CMake macro

This makes nodeset compilation easier by providing a wrapper macro.
Stefan Profanter 5 år sedan
förälder
incheckning
7d5be84376

+ 9 - 26
CMakeLists.txt

@@ -665,7 +665,7 @@ else()
     if(UA_ENABLE_PUBSUB)
         list(APPEND UA_FILE_DATATYPES ${PROJECT_SOURCE_DIR}/tools/schema/datatypes_pubsub.txt)
         if(UA_ENABLE_PUBSUB_INFORMATIONMODEL)
-            set(UA_FILE_NSPUBSUB --xml ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.NodeSet2.PubSubMinimal.xml)
+            set(UA_FILE_NSPUBSUB ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.NodeSet2.PubSubMinimal.xml)
         endif()
     endif()
 endif()
@@ -747,37 +747,20 @@ if(NOT UA_NODESET_ENCODE_BINARY_SIZE)
     set(UA_NODESET_ENCODE_BINARY_SIZE 32000)
 endif()
 
-# generated namespace 0
-add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.c
-                          ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.h
-                   PRE_BUILD
-                   COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                           --generate-ns0
-                           --internal-headers
-                           --encode-binary-size=${UA_NODESET_ENCODE_BINARY_SIZE}
-                           --ignore ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/NodeID_NS0_Base.txt
-                           --xml ${UA_FILE_NS0}
-                           ${UA_FILE_NSPUBSUB}
-                           ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0
-                   DEPENDS ${UA_FILE_NS0}
-                           ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                           ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                           ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                           ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                           ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                           ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                           ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py)
+ua_generate_nodeset(
+    NAME "ns0"
+    FILE "${UA_FILE_NS0}" "${UA_FILE_NSPUBSUB}"
+    INTERNAL
+    IGNORE "${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/NodeID_NS0_Base.txt"
+    ENCODE_BINARY_SIZE ${UA_NODESET_ENCODE_BINARY_SIZE}
+    DEPENDS_TARGET "open62541-generator-types"
+)
 
 # stack protector needs to be disabled for the huge ns0 file, otherwise it may take many minutes to compile the file.
 if(NOT MSVC)
     set_source_files_properties(${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.c PROPERTIES COMPILE_FLAGS -fno-stack-protector)
 endif()
 
-# we need a custom target to avoid that the generator is called concurrently and thus overwriting files while the other thread is compiling
-add_custom_target(open62541-generator-namespace DEPENDS
-        ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.c
-        ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.h)
-
 #####################
 # Build the Library #
 #####################

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 30 - 27
doc/nodeset_compiler.rst


+ 28 - 76
examples/nodeset/CMakeLists.txt

@@ -7,24 +7,12 @@
 ###################
 
 # generate namespace from XML file
-add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/example_nodeset.c
-                   ${PROJECT_BINARY_DIR}/src_generated/example_nodeset.h
-                   PRE_BUILD
-                   COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                   --types-array=UA_TYPES
-                   --existing ${UA_FILE_NS0}
-                   --xml ${PROJECT_SOURCE_DIR}/examples/nodeset/server_nodeset.xml
-                   ${PROJECT_BINARY_DIR}/src_generated/example_nodeset
-                   DEPENDS ${UA_FILE_NS0}
-                   ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                   ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                   ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                   ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                   ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                   ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                   ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py
-                   ${PROJECT_SOURCE_DIR}/examples/nodeset/server_nodeset.xml)
-
+ua_generate_nodeset(
+    NAME "example"
+    FILE "${PROJECT_SOURCE_DIR}/examples/nodeset/server_nodeset.xml"
+    DEPENDS_TYPES "UA_TYPES"
+    DEPENDS_NS    "${UA_FILE_NS0}"
+)
 
 # The .csv file can be created from within UaModeler or manually
 
@@ -35,9 +23,9 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/example_nodeset_id
                    DEPENDS ${PROJECT_SOURCE_DIR}/tools/generate_nodeid_header.py
                    ${PROJECT_SOURCE_DIR}/examples/nodeset/server_nodeset.csv)
 
-add_example(server_nodeset server_nodeset.c ${PROJECT_BINARY_DIR}/src_generated/example_nodeset.c ${PROJECT_BINARY_DIR}/src_generated/example_nodeset_ids.h)
+add_example(server_nodeset server_nodeset.c ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_example.c ${PROJECT_BINARY_DIR}/src_generated/example_nodeset_ids.h)
 if(UA_COMPILE_AS_CXX)
-    set_source_files_properties(${PROJECT_BINARY_DIR}/src_generated/example_nodeset.c PROPERTIES LANGUAGE CXX)
+    set_source_files_properties(${PROJECT_BINARY_DIR}/src_generated/ua_namespace_example.c PROPERTIES LANGUAGE CXX)
 endif()
 
 ###################
@@ -56,60 +44,29 @@ if(UA_NAMESPACE_ZERO STREQUAL "FULL")
         FILES_BSD "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.Types.bsd"
     )
 
-
     # generate DI namespace
-    add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_di.c
-                       ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_di.h
-                       PRE_BUILD
-                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       --internal-headers
-                       --types-array=UA_TYPES
-                       --types-array=UA_TYPES_DI
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       --xml ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_di
-                       DEPENDS ${UA_FILE_NS0}
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       )
-    add_custom_target(open62541-generator-ns-di DEPENDS ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_di.c)
-    add_dependencies(open62541-generator-ns-di open62541-generator-types-di)
+    ua_generate_nodeset(
+        NAME "di"
+        FILE "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml"
+        TYPES_ARRAY "UA_TYPES_DI"
+        INTERNAL
+        DEPENDS_TYPES "UA_TYPES"
+        DEPENDS_NS    "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml"
+        DEPENDS_TARGET "open62541-generator-types-di"
+    )
 
     # generate PLCopen namespace which is using DI
-    add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_plc.c
-                       ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_plc.h
-                       PRE_BUILD
-                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       --internal-headers
-                       --types-array=UA_TYPES
-                       --types-array=UA_TYPES_DI
-                       # PLCopen has no specific type definition, thus use the default UA_TYPES to ignore it
-                       --types-array=UA_TYPES
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       --xml ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/PLCopen/Opc.Ua.Plc.NodeSet2.xml
-                       ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_plc
-                       DEPENDS ${UA_FILE_NS0}
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/PLCopen/Opc.Ua.Plc.NodeSet2.xml
-                       )
-    add_custom_target(open62541-generator-ns-plc DEPENDS ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_plc.c)
-    add_dependencies(open62541-generator-ns-plc open62541-generator-ns-di)
+    ua_generate_nodeset(
+        NAME "plc"
+        FILE "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/PLCopen/Opc.Ua.Plc.NodeSet2.xml"
+        INTERNAL
+        DEPENDS_TYPES
+            "UA_TYPES" "UA_TYPES_DI"
+        DEPENDS_NS
+            "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml"
+            "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml"
+        DEPENDS_TARGET "open62541-generator-ns-di"
+    )
 
     add_example(server_nodeset_plcopen server_nodeset_plcopen.c
                 ${PROJECT_BINARY_DIR}/src_generated/ua_types_di_generated.c
@@ -118,9 +75,4 @@ if(UA_NAMESPACE_ZERO STREQUAL "FULL")
     add_dependencies(server_nodeset_plcopen open62541-generator-ns-plc)
     target_include_directories(server_nodeset_plcopen PRIVATE ${PROJECT_SOURCE_DIR}/src) # needs an internal header
 
-    if(UA_COMPILE_AS_CXX)
-        set_source_files_properties(${PROJECT_BINARY_DIR}/src_generated/ua_types_di_generated.c PROPERTIES LANGUAGE CXX)
-        set_source_files_properties(${PROJECT_BINARY_DIR}/src_generated/ua_namespace_di.c PROPERTIES LANGUAGE CXX)
-        set_source_files_properties(${PROJECT_BINARY_DIR}/src_generated/ua_namespace_plc.c PROPERTIES LANGUAGE CXX)
-    endif()
 endif()

+ 2 - 2
examples/nodeset/server_nodeset.c

@@ -6,7 +6,7 @@
 
 /* Files example_namespace.h and example_namespace.c are created from server_nodeset.xml in the
  * /src_generated directory by CMake */
-#include "example_nodeset.h"
+#include "ua_namespace_example.h"
 #include "example_nodeset_ids.h"
 
 UA_Boolean running = true;
@@ -25,7 +25,7 @@ int main(int argc, char** argv) {
 
     UA_StatusCode retval;
     /* create nodes from nodeset */
-    if(example_nodeset(server) != UA_STATUSCODE_GOOD) {
+    if(ua_namespace_example(server) != UA_STATUSCODE_GOOD) {
         UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not add the example nodeset. "
         "Check previous output for any error.");
         retval = UA_STATUSCODE_BADUNEXPECTEDERROR;

+ 36 - 105
tests/nodeset-compiler/CMakeLists.txt

@@ -1,33 +1,6 @@
 file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/src_generated/tests")
 include_directories("${PROJECT_BINARY_DIR}/src_generated/tests")
 
-macro(generate_dataset xml source)
-    add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/tests/${source}.c
-                              ${PROJECT_BINARY_DIR}/src_generated/tests/${source}.h
-                       PRE_BUILD
-                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                               --types-array=UA_TYPES
-                               --existing ${UA_FILE_NS0}
-                               --xml ${xml}
-                               ${PROJECT_BINARY_DIR}/src_generated/tests/${source}
-                       DEPENDS ${UA_FILE_NS0} ${xml}
-                               ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                               ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                               ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                               ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                               ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                               ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                               ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py)
-endmacro()
-
-# Check ObjectType
-generate_dataset(${PROJECT_SOURCE_DIR}/tests/nodeset-compiler/objecttype.xml check_nodeset_objecttype_generated)
-add_executable(check_nodeset_objecttype check_nodeset_objecttype.c
-               ${PROJECT_BINARY_DIR}/src_generated/tests/check_nodeset_objecttype_generated.c
-               $<TARGET_OBJECTS:open62541-object> $<TARGET_OBJECTS:open62541-testplugins>)
-target_link_libraries(check_nodeset_objecttype ${LIBS})
-add_test_valgrind(nodeset_objecttype ${TESTS_BINARY_DIR}/check_nodeset_objecttype)
-
 ###############################################
 # Test Companion Specs that need the full NS0 #
 ###############################################
@@ -55,85 +28,43 @@ if(UA_NAMESPACE_ZERO STREQUAL "FULL")
     )
 
     # generate DI namespace
-    add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_di.c
-                       ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_di.h
-                       PRE_BUILD
-                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       --internal-headers
-                       --types-array=UA_TYPES
-                       --types-array=UA_TYPES_DI
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       --xml ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_di
-                       DEPENDS ${UA_NAMESPACE0_XML}
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       )
-    add_custom_target(open62541-generator-tests-ns-di DEPENDS ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_di.c)
-    add_dependencies(open62541-generator-tests-ns-di open62541-generator-tests-types-di)
+    ua_generate_nodeset(
+        NAME "tests-di"
+        FILE "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml"
+        TYPES_ARRAY "UA_TYPES_DI"
+        INTERNAL
+        DEPENDS_TYPES "UA_TYPES"
+        DEPENDS_NS    "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml"
+        DEPENDS_TARGET "open62541-generator-tests-types-di"
+    )
+
+    # generate PLCopen namespace which is using DI
+    ua_generate_nodeset(
+        NAME "tests-adi"
+        FILE "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/ADI/Opc.Ua.Adi.NodeSet2.xml"
+        TYPES_ARRAY "UA_TYPES_ADI"
+        INTERNAL
+        DEPENDS_TYPES
+        "UA_TYPES" "UA_TYPES_DI"
+        DEPENDS_NS
+        "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml"
+        "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml"
+        DEPENDS_TARGET "open62541-generator-ns-tests-di" "open62541-generator-tests-types-adi"
+    )
 
-    # generate ADI namespace which is using DI
-    add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_adi.c
-                       ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_adi.h
-                       PRE_BUILD
-                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       --internal-headers
-                       --types-array=UA_TYPES
-                       --types-array=UA_TYPES_DI
-                       --types-array=UA_TYPES_ADI
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       --xml ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/ADI/Opc.Ua.Adi.NodeSet2.xml
-                       ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_adi
-                       DEPENDS ${UA_NAMESPACE0_XML}
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/ADI/Opc.Ua.Adi.NodeSet2.xml
-                       )
-    add_custom_target(open62541-generator-tests-ns-adi DEPENDS ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_adi.c)
-    add_dependencies(open62541-generator-tests-ns-adi open62541-generator-tests-types-adi open62541-generator-tests-ns-di)
 
     # generate PLCopen namespace which is using DI
-    add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_plc.c
-                       ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_plc.h
-                       PRE_BUILD
-                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       --internal-headers
-                       --types-array=UA_TYPES
-                       --types-array=UA_TYPES_DI
-                       # PLCopen has no specific type definition, thus use the default UA_TYPES to ignore it
-                       --types-array=UA_TYPES
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml
-                       --existing ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       --xml ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/PLCopen/Opc.Ua.Plc.NodeSet2.xml
-                       ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_plc
-                       DEPENDS ${UA_NAMESPACE0_XML}
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
-                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml
-                       ${PROJECT_SOURCE_DIR}/deps/ua-nodeset/PLCopen/Opc.Ua.Plc.NodeSet2.xml
-                       )
-    add_custom_target(open62541-generator-tests-ns-plc DEPENDS ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_plc.c)
-    add_dependencies(open62541-generator-tests-ns-plc open62541-generator-tests-ns-di)
+    ua_generate_nodeset(
+        NAME "tests-plc"
+        FILE "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/PLCopen/Opc.Ua.Plc.NodeSet2.xml"
+        INTERNAL
+        DEPENDS_TYPES
+        "UA_TYPES" "UA_TYPES_DI"
+        DEPENDS_NS
+        "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml"
+        "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xml"
+        DEPENDS_TARGET "open62541-generator-ns-di"
+    )
 
     add_executable(check_nodeset_compiler_adi check_nodeset_compiler_adi.c
                    ${PROJECT_BINARY_DIR}/src_generated/tests/ua_types_di_generated.c
@@ -141,7 +72,7 @@ if(UA_NAMESPACE_ZERO STREQUAL "FULL")
                    ${PROJECT_BINARY_DIR}/src_generated/tests/ua_types_adi_generated.c
                    ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_adi.c
                    $<TARGET_OBJECTS:open62541-object> $<TARGET_OBJECTS:open62541-testplugins>)
-    add_dependencies(check_nodeset_compiler_adi open62541-generator-tests-ns-adi)
+    add_dependencies(check_nodeset_compiler_adi open62541-generator-ns-tests-adi)
     target_link_libraries(check_nodeset_compiler_adi ${LIBS})
     add_test_valgrind(nodeset_compiler_adi ${TESTS_BINARY_DIR}/check_nodeset_compiler_adi)
 
@@ -150,7 +81,7 @@ if(UA_NAMESPACE_ZERO STREQUAL "FULL")
                    ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_di.c
                    ${PROJECT_BINARY_DIR}/src_generated/tests/ua_namespace_plc.c
                    $<TARGET_OBJECTS:open62541-object> $<TARGET_OBJECTS:open62541-testplugins>)
-    add_dependencies(check_nodeset_compiler_plc open62541-generator-tests-ns-plc)
+    add_dependencies(check_nodeset_compiler_plc open62541-generator-ns-tests-plc)
     target_link_libraries(check_nodeset_compiler_plc ${LIBS})
     add_test_valgrind(nodeset_compiler_plc ${TESTS_BINARY_DIR}/check_nodeset_compiler_plc)
 endif()

+ 0 - 45
tests/nodeset-compiler/check_nodeset_objecttype.c

@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "open62541.h"
-#include "check_nodeset_objecttype_generated.h"
-#include "check.h"
-
-static UA_Server *server = NULL;
-static UA_ServerConfig *config = NULL;
-
-static void setup(void) {
-    config = UA_ServerConfig_new_default();
-    server = UA_Server_new(config);
-    UA_StatusCode retval = check_nodeset_objecttype_generated(server);
-    ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
-}
-
-static void teardown(void) {
-    UA_Server_delete(server);
-    UA_ServerConfig_delete(config);
-}
-
-START_TEST(checkObjectTypeExists) {
-    UA_NodeClass nc = UA_NODECLASS_UNSPECIFIED;
-    UA_StatusCode retval = UA_Server_readNodeClass(server, UA_NODEID_NUMERIC(2, 1001), &nc);
-    ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
-    ck_assert_int_eq(nc, UA_NODECLASS_OBJECTTYPE);
-} END_TEST
-
-int main(void) {
-    Suite *s = suite_create("XML-Generated ObjectType");
-    TCase *tc_objecttype = tcase_create("objecttype tests");
-    tcase_add_checked_fixture(tc_objecttype, setup, teardown);
-    tcase_add_test(tc_objecttype, checkObjectTypeExists);
-    suite_add_tcase(s, tc_objecttype);
-
-    SRunner *sr = srunner_create(s);
-    srunner_set_fork_status(sr, CK_NOFORK);
-    srunner_run_all(sr, CK_NORMAL);
-    int number_failed = srunner_ntests_failed(sr);
-    srunner_free(sr);
-
-    return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}

+ 0 - 61
tests/nodeset-compiler/objecttype.xml

@@ -1,61 +0,0 @@
-<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" xmlns:s1="http://yourorganisation.org/test/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-    <NamespaceUris>
-        <Uri>http://yourorganisation.org/test/</Uri>
-    </NamespaceUris>
-    <Aliases>
-        <Alias Alias="Double">i=11</Alias>
-        <Alias Alias="Organizes">i=35</Alias>
-        <Alias Alias="HasModellingRule">i=37</Alias>
-        <Alias Alias="HasTypeDefinition">i=40</Alias>
-        <Alias Alias="HasSubtype">i=45</Alias>
-        <Alias Alias="HasComponent">i=47</Alias>
-    </Aliases>
-    <!-- Following object has only references to nodes defined after itself -->
-    <UAObject NodeId="ns=1;i=5001" BrowseName="1:testInstance">
-        <DisplayName>testInstance</DisplayName>
-        <References>
-            <Reference ReferenceType="Organizes" IsForward="false">ns=1;i=5002</Reference>
-            <Reference ReferenceType="HasTypeDefinition">ns=1;i=1001</Reference>
-            <Reference ReferenceType="HasComponent">ns=1;i=6002</Reference>
-        </References>
-    </UAObject>
-    <UAObject NodeId="ns=1;i=5002" BrowseName="1:testFolder">
-        <DisplayName>testFolder</DisplayName>
-        <References>
-            <Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
-            <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
-        </References>
-    </UAObject>
-    <UAObjectType NodeId="ns=1;i=1001" BrowseName="1:testType">
-        <DisplayName>testType</DisplayName>
-        <References>
-            <Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
-            <Reference ReferenceType="HasComponent">ns=1;i=6001</Reference>
-        </References>
-    </UAObjectType>
-    <UAVariable DataType="Double" ParentNodeId="ns=1;i=1001" NodeId="ns=1;i=6001" BrowseName="1:Var1" UserAccessLevel="3" AccessLevel="3">
-        <DisplayName>Var1</DisplayName>
-        <References>
-            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
-            <Reference ReferenceType="HasModellingRule">i=78</Reference>
-            <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=1001</Reference>
-        </References>
-        <Value>
-            <uax:Double>42.0</uax:Double>
-        </Value>
-    </UAVariable>
-    <UAVariable ParentNodeId="ns=1;i=5001" NodeId="ns=1;i=6002" BrowseName="1:Var1" DataType="i=7" UserAccessLevel="3" AccessLevel="3">
-        <DisplayName>Var2</DisplayName>
-        <References>
-            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
-            <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=5001</Reference>
-        </References>
-        <Value>
-            <ListOfUInt32 xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
-                <uax:UInt32>1</uax:UInt32>
-                <uax:UInt32>2</uax:UInt32>
-                <uax:UInt32>3</uax:UInt32>
-            </ListOfUInt32>
-        </Value>
-    </UAVariable>
-</UANodeSet>

+ 151 - 0
tools/cmake/macros.cmake

@@ -164,4 +164,155 @@ function(ua_generate_datatypes)
                       ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_handling.h
                       ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated_encoding_binary.h
                       )
+
+    if(UA_COMPILE_AS_CXX)
+        set_source_files_properties(${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c PROPERTIES LANGUAGE CXX)
+    endif()
+endfunction()
+
+
+# --------------- Generate Nodeset ---------------------
+#
+# Generates C code for the given NodeSet2.xml file.
+# This C code can be used to initialize the server.
+#
+# The resulting files will be put into OUTPUT_DIR with the names:
+# - ua_namespace_NAME.c
+# - ua_namespace_NAME.h
+#
+# The resulting cmake target will be named like this:
+#   open62541-generator-ns-${NAME}
+#
+# The following arguments are accepted:
+#   Options:
+#
+#   [INTERNAL]      Optional argument. If given, then the generated node set code will use internal headers.
+#
+#   Arguments taking one value:
+#
+#   NAME            Full name of the generated files, e.g. ua_types_di
+#   [TYPES_ARRAY]   Optional name of the types array containing the custom datatypes of this node set.
+#   [OUTPUT_DIR]    Optional target directory for the generated files. Default is '${PROJECT_BINARY_DIR}/src_generated'
+#   [ENCODE_BINARY_SIZE]    Optional array size for binary encoding extension objects.
+#   [IGNORE]        Optional file containing a list of node ids which should be ignored. The file should have one id per line.
+#
+#   Arguments taking multiple values:
+#
+#   FILE            Path to the NodeSet2.xml file. Multiple values can be passed. These nodesets will be combined into one output.
+#   [DEPENDS_TYPES]   Optional list of types array which match with the DEPENDS_NS node sets. e.g. 'UA_TYPES;UA_TYPES_DI'
+#   [DEPENDS_NS]      Optional list of NodeSet2.xml files which are a dependency of this node set.
+#   [DEPENDS_TARGET]  Optional list of CMake targets this nodeset depends on.
+#
+#
+function(ua_generate_nodeset)
+
+    set(options INTERNAL )
+    set(oneValueArgs NAME TYPES_ARRAY OUTPUT_DIR ENCODE_BINARY_SIZE IGNORE)
+    set(multiValueArgs FILE DEPENDS_TYPES DEPENDS_NS DEPENDS_TARGET)
+    cmake_parse_arguments(PARSE_ARGV 0 UA_GEN_NS "${options}" "${oneValueArgs}"
+                          "${multiValueArgs}")
+
+
+
+    # ------ Argument checking -----
+    if(NOT UA_GEN_NS_NAME OR "${UA_GEN_NS_NAME}" STREQUAL "")
+        message(FATAL_ERROR "ua_generate_nodeset function requires a value for the NAME argument")
+    endif()
+
+    if(NOT UA_GEN_NS_FILE OR "${UA_GEN_NS_FILE}" STREQUAL "")
+        message(FATAL_ERROR "ua_generate_nodeset function requires a value for the FILE argument")
+    endif()
+
+    # Set default value for output dir
+    if(NOT UA_GEN_NS_OUTPUT_DIR)
+        set(UA_GEN_NS_OUTPUT_DIR ${PROJECT_BINARY_DIR}/src_generated)
+    endif()
+
+    list(LENGTH UA_GEN_NS_DEPENDS_TYPES DEPENDS_TYPES_LEN)
+    list(LENGTH UA_GEN_NS_DEPENDS_NS DEPENDS_NS_LEN)
+
+    if(NOT DEPENDS_TYPES_LEN EQUAL DEPENDS_NS_LEN)
+        message(FATAL_ERROR "ua_generate_nodeset parameters DEPENDS_NS and DEPENDS_TYPES must have the same number of list elements")
+    endif()
+
+    # ------ Add custom command and target -----
+
+    set(GEN_INTERNAL_HEADERS "")
+    if (UA_GEN_NS_INTERNAL)
+        set(GEN_INTERNAL_HEADERS "--internal-headers")
+    endif()
+
+    set(GEN_NS0 "")
+    set(TARGET_SUFFIX "ns-${UA_GEN_NS_NAME}")
+    set(FILE_SUFFIX "_${UA_GEN_NS_NAME}")
+
+    if ("${UA_GEN_NS_NAME}" STREQUAL "ns0")
+        set(GEN_NS0 "--generate-ns0")
+        set(TARGET_SUFFIX "namespace")
+        set(FILE_SUFFIX "0")
+    endif()
+
+    set(GEN_IGNORE "")
+    if (UA_GEN_NS_IGNORE)
+        set(GEN_IGNORE "--ignore=${UA_GEN_NS_IGNORE}")
+    endif()
+
+    set(GEN_BIN_SIZE "")
+    if (UA_GEN_NS_ENCODE_BINARY_SIZE OR "${UA_GEN_NS_ENCODE_BINARY_SIZE}" STREQUAL "0")
+        set(GEN_BIN_SIZE "--encode-binary-size=${UA_GEN_NS_ENCODE_BINARY_SIZE}")
+    endif()
+
+
+    set(TYPES_ARRAY_LIST "")
+    foreach(f ${UA_GEN_NS_DEPENDS_TYPES})
+        set(TYPES_ARRAY_LIST ${TYPES_ARRAY_LIST} "--types-array=${f}")
+    endforeach()
+    if(UA_GEN_NS_TYPES_ARRAY)
+        set(TYPES_ARRAY_LIST ${TYPES_ARRAY_LIST} "--types-array=${UA_GEN_NS_TYPES_ARRAY}")
+    endif()
+
+    set(DEPENDS_FILE_LIST "")
+    foreach(f ${UA_GEN_NS_DEPENDS_NS})
+        set(DEPENDS_FILE_LIST ${DEPENDS_FILE_LIST} "--existing=${f}")
+    endforeach()
+    set(FILE_LIST "")
+    foreach(f ${UA_GEN_NS_FILE})
+        set(FILE_LIST ${FILE_LIST} "--xml=${f}")
+    endforeach()
+
+    add_custom_command(OUTPUT ${UA_GEN_NS_OUTPUT_DIR}/ua_namespace${FILE_SUFFIX}.c
+                       ${UA_GEN_NS_OUTPUT_DIR}/ua_namespace${FILE_SUFFIX}.h
+                       PRE_BUILD
+                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
+                       ${GEN_INTERNAL_HEADERS}
+                       ${GEN_NS0}
+                       ${GEN_BIN_SIZE}
+                       ${GEN_IGNORE}
+                       ${TYPES_ARRAY_LIST}
+                       ${DEPENDS_FILE_LIST}
+                       ${FILE_LIST}
+                       ${PROJECT_BINARY_DIR}/src_generated/ua_namespace${FILE_SUFFIX}
+                       DEPENDS
+                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset_compiler.py
+                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodes.py
+                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/nodeset.py
+                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/datatypes.py
+                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541.py
+                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_nodes.py
+                       ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/backend_open62541_datatypes.py
+                       ${UA_GEN_NS_FILE}
+                       ${UA_GEN_NS_DEPENDS_NS}
+                       )
+
+    add_custom_target(open62541-generator-${TARGET_SUFFIX}
+                      DEPENDS
+                      ${PROJECT_BINARY_DIR}/src_generated/ua_namespace${FILE_SUFFIX}.c
+                      ${PROJECT_BINARY_DIR}/src_generated/ua_namespace${FILE_SUFFIX}.h)
+    if (UA_GEN_NS_DEPENDS_TARGET)
+        add_dependencies(open62541-generator-${TARGET_SUFFIX} ${UA_GEN_NS_DEPENDS_TARGET})
+    endif()
+
+    if(UA_COMPILE_AS_CXX)
+        set_source_files_properties(${UA_GEN_NS_OUTPUT_DIR}/ua_namespace${FILE_SUFFIX}.c PROPERTIES LANGUAGE CXX)
+    endif()
 endfunction()