Browse Source

CMake: Correctly handle generation macros when installed

Stefan Profanter 5 years ago
parent
commit
05d4cd4f45

+ 75 - 38
CMakeLists.txt

@@ -6,7 +6,13 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake")
 find_package(PythonInterp REQUIRED)
 find_package(Git)
 include(AssignSourceGroup)
-include(macros)
+
+# Set when installed via make install
+set(open62541_TOOLS_DIR ${PROJECT_SOURCE_DIR}/tools)
+set(open62541_NODESET_DIR ${PROJECT_SOURCE_DIR}/deps/ua-nodeset)
+
+include(macros_internal)
+include(macros_public)
 
 #############################
 # Compiled binaries folders #
@@ -730,12 +736,11 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_statuscodes.h
                 ${UA_FILE_STATUSCODES})
 
 # Header containing defines for all NodeIds
-add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids.h
-        PRE_BUILD
-        COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_nodeid_header.py
-        ${UA_FILE_NODEIDS}  ${PROJECT_BINARY_DIR}/src_generated/ua_nodeids NS0
-        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/generate_nodeid_header.py
-        ${UA_FILE_NODEIDS})
+ua_generate_nodeid_header(
+    NAME "ua_nodeids"
+    ID_PREFIX "NS0"
+    FILE_CSV "${UA_FILE_NODEIDS}"
+)
 
 # we need a custom target to avoid that the generator is called concurrently and
 # thus overwriting files while the other thread is compiling
@@ -949,9 +954,48 @@ add_custom_target(cpplint cpplint
 
 set(cmake_configfile_install ${LIB_INSTALL_DIR}/cmake/open62541)
 set(target_install_dest_name "${cmake_configfile_install}/open62541Targets.cmake")
-set(open62541_tools_dir share/open62541/tools)
-set(open62541_deps_dir include/open62541/deps)
-set(open62541_include_dir include/open62541)
+set(macros_install_dest_name "${cmake_configfile_install}/open62541Macros.cmake")
+set(open62541_install_tools_dir share/open62541/tools)
+set(open62541_install_nodeset_dir share/open62541/tools/ua-nodeset)
+set(open62541_install_include_dir include/open62541)
+
+# This list of components allows to define a find_package requirement.
+# E.g.:
+# find_package(open62541 0.4.0 REQUIRED COMPONENTS Events Methods FullNamespace)
+set(open62541_enabled_components "")
+if(UA_NAMESPACE_ZERO STREQUAL "FULL")
+    list(APPEND open62541_enabled_components "FullNamespace")
+endif()
+if(UA_ENABLE_METHODCALLS)
+    list(APPEND open62541_enabled_components "Methods")
+endif()
+if(UA_ENABLE_SUBSCRIPTIONS)
+    list(APPEND open62541_enabled_components "Subscriptions")
+endif()
+if(UA_ENABLE_PUBSUB)
+    list(APPEND open62541_enabled_components "PubSub")
+endif()
+if(UA_ENABLE_ENCRYPTION)
+    list(APPEND open62541_enabled_components "Encryption")
+endif()
+if(UA_ENABLE_AMALGAMATION)
+    list(APPEND open62541_enabled_components "Amalgamation")
+endif()
+if(UA_ENABLE_HISTORIZING)
+    list(APPEND open62541_enabled_components "Historizing")
+endif()
+if(UA_ENABLE_SUBSCRIPTIONS_EVENTS)
+    list(APPEND open62541_enabled_components "Events")
+endif()
+if(UA_ENABLE_MULTITHREADING)
+    list(APPEND open62541_enabled_components "Multithreading")
+endif()
+if(UA_ENABLE_DISCOVERY)
+    list(APPEND open62541_enabled_components "Discovery")
+endif()
+if(UA_ENABLE_DISCOVERY_MULTICAST)
+    list(APPEND open62541_enabled_components "DiscoveryMulticast")
+endif()
 
 # export library (either static or shared depending on BUILD_SHARED_LIBS)
 install(TARGETS open62541
@@ -959,13 +1003,18 @@ install(TARGETS open62541
         LIBRARY DESTINATION ${LIB_INSTALL_DIR}
         ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
         RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}
-        INCLUDES DESTINATION include/open62541 ${open62541_deps_dir})
+        INCLUDES DESTINATION include/open62541 include)
 
 include(CMakePackageConfigHelpers)
-configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/open62541-config.cmake.in"
-                              "${CMAKE_CURRENT_BINARY_DIR}/cmake/open62541-config.cmake"
+configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/open62541Config.cmake.in"
+                              "${CMAKE_CURRENT_BINARY_DIR}/cmake/open62541Config.cmake"
                               INSTALL_DESTINATION "${cmake_configfile_install}"
-                              PATH_VARS target_install_dest_name open62541_tools_dir)
+                              PATH_VARS target_install_dest_name
+                                        macros_install_dest_name
+                                        open62541_install_tools_dir
+                                        open62541_install_nodeset_dir
+                                        open62541_enabled_components
+                              )
 
 set(open62541_VERSION)
 get_target_property(open62541_VERSION open62541 VERSION)
@@ -978,10 +1027,15 @@ install(EXPORT open62541Targets
         FILE open62541Targets.cmake
         DESTINATION "${cmake_configfile_install}")
 
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/open62541-config.cmake"
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/open62541Config.cmake"
               "${CMAKE_CURRENT_BINARY_DIR}/open62541ConfigVersion.cmake"
         DESTINATION "${cmake_configfile_install}")
 
+install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/macros_public.cmake"
+        DESTINATION "${cmake_configfile_install}"
+        RENAME "open62541Macros.cmake"
+        )
+
 
 if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
     install(FILES "${PROJECT_BINARY_DIR}/src_generated/open62541.pc"
@@ -997,38 +1051,21 @@ set(UA_install_tools_files "tools/generate_datatypes.py"
     "tools/generate_nodeid_header.py"
     "tools/generate_statuscode_descriptions.py")
 
-install(DIRECTORY ${UA_install_tools_dirs} DESTINATION ${open62541_tools_dir} USE_SOURCE_PERMISSIONS)
-install(FILES ${UA_install_tools_files} DESTINATION ${open62541_tools_dir})
+install(DIRECTORY ${UA_install_tools_dirs} DESTINATION ${open62541_install_tools_dir} USE_SOURCE_PERMISSIONS)
+install(FILES ${UA_install_tools_files} DESTINATION ${open62541_install_tools_dir})
 
+install(FILES ${PROJECT_BINARY_DIR}/open62541.h DESTINATION include)
 # Export amalgamated header open62541.h which is generated due to build of open62541-object
-if(UA_ENABLE_AMALGAMATION)
-    install(FILES ${PROJECT_BINARY_DIR}/open62541.h DESTINATION include)
-else()
+if(NOT UA_ENABLE_AMALGAMATION)
     # Assume no files have identical names and place everything in the include folder
     install(FILES ${internal_headers}
                   ${exported_headers}
                   ${default_plugin_headers}
                   ${historizing_default_plugin_headers}
-            DESTINATION ${open62541_include_dir})
+            DESTINATION ${open62541_install_include_dir})
 endif()
 
-##########################
-# Packaging (DEB/RPM)    #
-##########################
-# invoke via `make package`
-
-set(CPACK_GENERATOR "TGZ;DEB;RPM")
-set(CPACK_PACKAGE_VENDOR "open62541 team")
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OPC UA implementation")
-set(CPACK_PACKAGE_DESCRIPTION "open62541 is a C-based library (linking with C++ projects is possible) with all necessary tools to implement dedicated OPC UA clients and servers, or to integrate OPC UA-based communication into existing applications.")
-set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
-set(CPACK_PACKAGE_VERSION_MAJOR "0")
-set(CPACK_PACKAGE_VERSION_MINOR "2")
-set(CPACK_PACKAGE_VERSION_PATCH "0")
-set(CPACK_DEBIAN_PACKAGE_MAINTAINER "open62541 team") #required
-
-include(CPack)
+add_subdirectory(tools/packaging)
 
 ##################################
 # Visual studio solution folders #

+ 6 - 8
examples/nodeset/CMakeLists.txt

@@ -13,15 +13,13 @@ ua_generate_nodeset_and_datatypes(
 )
 
 # The .csv file can be created from within UaModeler or manually
+ua_generate_nodeid_header(
+    NAME "example_nodeids"
+    ID_PREFIX "EXAMPLE_NS"
+    FILE_CSV "${PROJECT_SOURCE_DIR}/examples/nodeset/server_nodeset.csv"
+)
 
-add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/example_nodeset_ids.h
-                   PRE_BUILD
-                   COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_nodeid_header.py
-                   ${PROJECT_SOURCE_DIR}/examples/nodeset/server_nodeset.csv  ${PROJECT_BINARY_DIR}/src_generated/example_nodeset_ids EXAMPLE_NS
-                   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/ua_namespace_example.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_nodeids.h)
 if(UA_COMPILE_AS_CXX)
     set_source_files_properties(${PROJECT_BINARY_DIR}/src_generated/ua_namespace_example.c PROPERTIES LANGUAGE CXX)
 endif()

+ 1 - 1
examples/nodeset/server_nodeset.c

@@ -7,7 +7,7 @@
 /* Files example_namespace.h and example_namespace.c are created from server_nodeset.xml in the
  * /src_generated directory by CMake */
 #include "ua_namespace_example.h"
-#include "example_nodeset_ids.h"
+#include "example_nodeids.h"
 
 UA_Boolean running = true;
 

+ 55 - 0
tools/cmake/macros_internal.cmake

@@ -0,0 +1,55 @@
+#Add a new architecture to to the lists of available architectures
+FUNCTION(ua_add_architecture)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURES ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture)
+
+#Include folders to the compilation
+FUNCTION(ua_include_directories)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_INCLUDE_DIRECTORIES ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_include_directories)
+
+#Add a new header file to the architecture group
+FUNCTION(ua_add_architecture_header)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_HEADERS ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture_header)
+
+#Add a new header file to the architecture group at the beginning of it
+FUNCTION(ua_add_architecture_header_beginning)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_HEADERS_BEGINNING ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture_header_beginning)
+
+#Add a new source file to the architecture group
+FUNCTION(ua_add_architecture_file)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_SOURCES ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_add_architecture_file)
+
+#Add definitions to the compilations that are exclusive for the selected architecture
+FUNCTION(ua_architecture_add_definitions)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_ADD_DEFINITIONS ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_architecture_add_definitions)
+
+#Remove definitions from the compilations that are exclusive for the selected architecture
+FUNCTION(ua_architecture_remove_definitions)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_REMOVE_DEFINITIONS ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_architecture_remove_definitions)
+
+#Add libraries to be linked to the comnpilation that are exclusive for the selected architecture
+FUNCTION(ua_architecture_append_to_library)
+    FOREACH(ARG ${ARGV})
+        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_APPEND_TO_LIBRARY ${ARG})
+    ENDFOREACH(ARG)
+ENDFUNCTION(ua_architecture_append_to_library)

+ 104 - 92
tools/cmake/macros.cmake

@@ -1,58 +1,42 @@
-#Add a new architecture to to the lists of available architectures
-FUNCTION(ua_add_architecture)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURES ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_add_architecture)
-
-#Include folders to the compilation
-FUNCTION(ua_include_directories)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_INCLUDE_DIRECTORIES ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_include_directories)
-
-#Add a new header file to the architecture group
-FUNCTION(ua_add_architecture_header)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_HEADERS ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_add_architecture_header)
-
-#Add a new header file to the architecture group at the beginning of it
-FUNCTION(ua_add_architecture_header_beginning)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_HEADERS_BEGINNING ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_add_architecture_header_beginning)
-
-#Add a new source file to the architecture group
-FUNCTION(ua_add_architecture_file)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_SOURCES ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_add_architecture_file)
-
-#Add definitions to the compilations that are exclusive for the selected architecture
-FUNCTION(ua_architecture_add_definitions)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_ADD_DEFINITIONS ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_architecture_add_definitions)
-
-#Remove definitions from the compilations that are exclusive for the selected architecture
-FUNCTION(ua_architecture_remove_definitions)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_REMOVE_DEFINITIONS ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_architecture_remove_definitions)
-
-#Add libraries to be linked to the comnpilation that are exclusive for the selected architecture
-FUNCTION(ua_architecture_append_to_library)
-    FOREACH(ARG ${ARGV})
-        set_property(GLOBAL APPEND PROPERTY UA_ARCHITECTURE_APPEND_TO_LIBRARY ${ARG})
-    ENDFOREACH(ARG)
-ENDFUNCTION(ua_architecture_append_to_library)
+
+# --------------- Generate NodeIDs header ---------------------
+#
+# Generates header file from .csv which contains defines for every
+# node id to be used instead of numeric node ids.
+#
+# The resulting files will be put into OUTPUT_DIR with the names:
+# - NAME.h
+#
+#
+# The following arguments are accepted:
+#   Options:
+#
+#   Arguments taking one value:
+#
+#   NAME            Full name of the generated files, e.g. di_nodeids
+#   ID_PREFIX       Prefix for the generated node ID defines, e.g. NS_DI
+#   [OUTPUT_DIR]    Optional target directory for the generated files. Default is '${PROJECT_BINARY_DIR}/src_generated'
+#   FILE_CSV        Path to the .csv file containing the node ids, e.g. 'OpcUaDiModel.csv'
+#
+function(ua_generate_nodeid_header)
+    set(options )
+    set(oneValueArgs NAME ID_PREFIX OUTPUT_DIR FILE_CSV)
+    set(multiValueArgs )
+    cmake_parse_arguments(UA_GEN_ID "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+    # Set default value for output dir
+    if(NOT UA_GEN_ID_OUTPUT_DIR)
+        set(UA_GEN_ID_OUTPUT_DIR ${PROJECT_BINARY_DIR}/src_generated)
+    endif()
+
+    # Header containing defines for all NodeIds
+    add_custom_command(OUTPUT ${UA_GEN_ID_OUTPUT_DIR}/${UA_GEN_ID_NAME}.h
+        PRE_BUILD
+        COMMAND ${PYTHON_EXECUTABLE} ${open62541_TOOLS_DIR}/generate_nodeid_header.py
+        ${UA_GEN_ID_FILE_CSV}  ${UA_GEN_ID_OUTPUT_DIR}/${UA_GEN_ID_NAME} ${UA_GEN_ID_ID_PREFIX}
+        DEPENDS ${open62541_TOOLS_DIR}/generate_nodeid_header.py
+        ${UA_GEN_ID_FILE_CSV})
+endfunction()
 
 
 # --------------- Generate Datatypes ---------------------
@@ -100,6 +84,9 @@ function(ua_generate_datatypes)
     set(multiValueArgs FILES_BSD FILES_SELECTED)
     cmake_parse_arguments(UA_GEN_DT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
 
+    if(NOT DEFINED open62541_TOOLS_DIR)
+        message(FATAL_ERROR "open62541_TOOLS_DIR must point to the open62541 tools directory")
+    endif()
 
     # ------ Argument checking -----
     if(NOT DEFINED UA_GEN_DT_NAMESPACE_IDX AND NOT "${UA_GEN_DT_NAMESPACE_IDX}" STREQUAL "0")
@@ -142,27 +129,27 @@ function(ua_generate_datatypes)
     endforeach()
 
     add_custom_command(OUTPUT ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c
-                       ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.h
-                       ${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
-                       PRE_BUILD
-                       COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/generate_datatypes.py
-                       --namespace=${UA_GEN_DT_NAMESPACE_IDX}
-                       ${SELECTED_TYPES_TMP}
-                       ${BSD_FILES_TMP}
-                       --type-csv=${UA_GEN_DT_FILE_CSV}
-                       ${UA_GEN_DT_NO_BUILTIN}
-                       ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}
-                       DEPENDS ${PROJECT_SOURCE_DIR}/tools/generate_datatypes.py
-                       ${UA_GEN_DT_FILES_BSD}
-                       ${UA_GEN_DT_FILE_CSV}
-                       ${UA_GEN_DT_FILES_SELECTED})
+        ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.h
+        ${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
+        PRE_BUILD
+        COMMAND ${PYTHON_EXECUTABLE} ${open62541_TOOLS_DIR}/generate_datatypes.py
+        --namespace=${UA_GEN_DT_NAMESPACE_IDX}
+        ${SELECTED_TYPES_TMP}
+        ${BSD_FILES_TMP}
+        --type-csv=${UA_GEN_DT_FILE_CSV}
+        ${UA_GEN_DT_NO_BUILTIN}
+        ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}
+        DEPENDS ${open62541_TOOLS_DIR}/generate_datatypes.py
+        ${UA_GEN_DT_FILES_BSD}
+        ${UA_GEN_DT_FILE_CSV}
+        ${UA_GEN_DT_FILES_SELECTED})
     add_custom_target(open62541-generator-${UA_GEN_DT_TARGET_SUFFIX} DEPENDS
-                      ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c
-                      ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.h
-                      ${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
-                      )
+        ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c
+        ${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.h
+        ${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
+        )
 
     string(TOUPPER "${UA_GEN_DT_NAME}" GEN_NAME_UPPER)
     set(${GEN_NAME_UPPER}_SOURCES "${UA_GEN_DT_OUTPUT_DIR}/${UA_GEN_DT_NAME}_generated.c" CACHE INTERNAL "${UA_GEN_DT_NAME} source files")
@@ -216,6 +203,9 @@ function(ua_generate_nodeset)
     cmake_parse_arguments(UA_GEN_NS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
 
 
+    if(NOT DEFINED open62541_TOOLS_DIR)
+        message(FATAL_ERROR "open62541_TOOLS_DIR must point to the open62541 tools directory")
+    endif()
 
     # ------ Argument checking -----
     if(NOT UA_GEN_NS_NAME OR "${UA_GEN_NS_NAME}" STREQUAL "")
@@ -287,7 +277,7 @@ function(ua_generate_nodeset)
     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
+                       COMMAND ${PYTHON_EXECUTABLE} ${open62541_TOOLS_DIR}/nodeset_compiler/nodeset_compiler.py
                        ${GEN_INTERNAL_HEADERS}
                        ${GEN_NS0}
                        ${GEN_BIN_SIZE}
@@ -297,13 +287,13 @@ function(ua_generate_nodeset)
                        ${FILE_LIST}
                        ${UA_GEN_NS_OUTPUT_DIR}/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
+                       ${open62541_TOOLS_DIR}/nodeset_compiler/nodeset_compiler.py
+                       ${open62541_TOOLS_DIR}/nodeset_compiler/nodes.py
+                       ${open62541_TOOLS_DIR}/nodeset_compiler/nodeset.py
+                       ${open62541_TOOLS_DIR}/nodeset_compiler/datatypes.py
+                       ${open62541_TOOLS_DIR}/nodeset_compiler/backend_open62541.py
+                       ${open62541_TOOLS_DIR}/nodeset_compiler/backend_open62541_nodes.py
+                       ${open62541_TOOLS_DIR}/nodeset_compiler/backend_open62541_datatypes.py
                        ${UA_GEN_NS_FILE}
                        ${UA_GEN_NS_DEPENDS_NS}
                        )
@@ -336,7 +326,8 @@ endfunction()
 # Generates C code for the given NodeSet2.xml and Datatype file.
 # This C code can be used to initialize the server.
 #
-# This is a combination of the ua_generate_datatypes and ua_generate_nodeset macros.
+# This is a combination of the ua_generate_datatypes, ua_generate_nodeset, and
+# ua_generate_nodeid_header macros.
 # This function can also be used to just create a nodeset without datatypes by
 # omitting the CSV, BSD, and NAMESPACE_IDX parameter.
 # If only one of the previous parameters is given, all of them are required.
@@ -374,38 +365,51 @@ endfunction()
 function(ua_generate_nodeset_and_datatypes)
 
     set(options INTERNAL)
-    set(oneValueArgs NAME FILE_NS FILE_CSV FILE_BSD NAMESPACE_IDX)
+    set(oneValueArgs NAME FILE_NS FILE_CSV FILE_BSD NAMESPACE_IDX OUTPUT_DIR)
     set(multiValueArgs DEPENDS)
     cmake_parse_arguments(UA_GEN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
 
 
+    if(NOT DEFINED open62541_TOOLS_DIR)
+        message(FATAL_ERROR "open62541_TOOLS_DIR must point to the open62541 tools directory")
+    endif()
+
+    if(NOT DEFINED open62541_NODESET_DIR)
+        message(FATAL_ERROR "open62541_NODESET_DIR must point to the open62541/deps/ua-nodeset directory")
+    endif()
+
     # ------ Argument checking -----
     if(NOT UA_GEN_NAME OR "${UA_GEN_NAME}" STREQUAL "")
         message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires a value for the NAME argument")
     endif()
+    string(TOUPPER "${UA_GEN_NAME}" GEN_NAME_UPPER)
 
     if(NOT UA_GEN_FILE_NS OR "${UA_GEN_FILE_NS}" STREQUAL "")
         message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires a value for the FILE_NS argument")
     endif()
 
     if((NOT UA_GEN_FILE_CSV OR "${UA_GEN_FILE_CSV}" STREQUAL "") AND
-        (NOT "${UA_GEN_FILE_BSD}" STREQUAL "" OR
+    (NOT "${UA_GEN_FILE_BSD}" STREQUAL "" OR
         NOT "${UA_GEN_NAMESPACE_IDX}" STREQUAL ""))
         message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires FILE_CSV argument if any of FILE_BSD or NAMESPACE_IDX are set")
     endif()
 
     if((NOT UA_GEN_FILE_BSD OR "${UA_GEN_FILE_BSD}" STREQUAL "") AND
-        (NOT "${UA_GEN_FILE_CSV}" STREQUAL "" OR
+    (NOT "${UA_GEN_FILE_CSV}" STREQUAL "" OR
         NOT "${UA_GEN_NAMESPACE_IDX}" STREQUAL ""))
         message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires FILE_BSD argument if any of FILE_CSV or NAMESPACE_IDX are set")
     endif()
-        
+
     if(NOT UA_GEN_NAMESPACE_IDX OR "${UA_GEN_NAMESPACE_IDX}" STREQUAL "" AND
-        (NOT "${UA_GEN_FILE_CSV}" STREQUAL "" OR
+    (NOT "${UA_GEN_FILE_CSV}" STREQUAL "" OR
         NOT "${UA_GEN_FILE_BSD}" STREQUAL ""))
         message(FATAL_ERROR "ua_generate_nodeset_and_datatypes function requires NAMESPACE_IDX argument if any of FILE_CSV or FILE_BSD are set")
     endif()
 
+    # Set default value for output dir
+    if(NOT UA_GEN_OUTPUT_DIR)
+        set(UA_GEN_OUTPUT_DIR ${PROJECT_BINARY_DIR}/src_generated)
+    endif()
 
     set(NODESET_DEPENDS_TARGET "")
     set(NODESET_TYPES_ARRAY "UA_TYPES")
@@ -419,15 +423,22 @@ function(ua_generate_nodeset_and_datatypes)
             NAMESPACE_IDX ${UA_GEN_NAMESPACE_IDX}
             FILE_CSV "${UA_GEN_FILE_CSV}"
             FILES_BSD "${UA_GEN_FILE_BSD}"
+            OUTPUT_DIR "${UA_GEN_OUTPUT_DIR}"
         )
         set(NODESET_DEPENDS_TARGET "open62541-generator-types-${UA_GEN_NAME}")
-        string(TOUPPER "${UA_GEN_NAME}" GEN_UPPER_NAME)
-        set(NODESET_TYPES_ARRAY "UA_TYPES_${GEN_UPPER_NAME}")
+        set(NODESET_TYPES_ARRAY "UA_TYPES_${GEN_NAME_UPPER}")
+
+        ua_generate_nodeid_header(
+            NAME "${UA_GEN_NAME}_nodeids"
+            ID_PREFIX "${GEN_NAME_UPPER}"
+            FILE_CSV "${UA_GEN_FILE_CSV}"
+            OUTPUT_DIR "${UA_GEN_OUTPUT_DIR}"
+        )
     endif()
 
     # Create a list of nodesets on which this nodeset depends on
     if (NOT UA_GEN_DEPENDS OR "${UA_GEN_DEPENDS}" STREQUAL "" )
-        set(NODESET_DEPENDS "${PROJECT_SOURCE_DIR}/deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml")
+        set(NODESET_DEPENDS "${open62541_NODESET_DIR}/Schema/Opc.Ua.NodeSet2.xml")
         set(TYPES_DEPENDS "UA_TYPES")
     else()
         foreach(f ${UA_GEN_DEPENDS})
@@ -457,6 +468,7 @@ function(ua_generate_nodeset_and_datatypes)
         DEPENDS_TYPES ${TYPES_DEPENDS}
         DEPENDS_NS ${NODESET_DEPENDS}
         DEPENDS_TARGET ${NODESET_DEPENDS_TARGET}
+        OUTPUT_DIR "${UA_GEN_OUTPUT_DIR}"
     )
 
 endfunction()

+ 0 - 5
tools/cmake/open62541-config.cmake.in

@@ -1,5 +0,0 @@
-@PACKAGE_INIT@
-
-include ("@PACKAGE_target_install_dest_name@")
-
-set (open62541_TOOLS_DIR @PACKAGE_open62541_tools_dir@ CACHE PATH "Path to the directory that contains the tooling of the stack")

+ 22 - 0
tools/cmake/open62541Config.cmake.in

@@ -0,0 +1,22 @@
+@PACKAGE_INIT@
+
+include ("@PACKAGE_target_install_dest_name@")
+
+set (open62541_TOOLS_DIR @PACKAGE_open62541_install_tools_dir@ CACHE PATH "Path to the directory that contains the tooling of the stack")
+set (open62541_NODESET_DIR @PACKAGE_open62541_install_nodeset_dir@ CACHE PATH "Path to the directory that contains the OPC UA schema repository")
+
+include(CMakeFindDependencyMacro)
+find_dependency(PythonInterp REQUIRED)
+
+include("@PACKAGE_macros_install_dest_name@")
+
+set(open62541_COMPONENTS_ALL @open62541_enabled_components@)
+
+foreach(_comp ${open62541_FIND_COMPONENTS})
+  list (FIND open62541_COMPONENTS_ALL "${_comp}" _index)
+  if (${_index} LESS 0)
+    set(open62541_FOUND False)
+    set(open62541_NOTFOUND_MESSAGE "Unsupported open62541 component: ${_comp}")
+    message(WARNING "${open62541_NOTFOUND_MESSAGE}")
+  endif()
+endforeach()

+ 17 - 0
tools/packaging/CMakeLists.txt

@@ -0,0 +1,17 @@
+##########################
+# Packaging (DEB/RPM)    #
+##########################
+# invoke via `make package`
+
+set(CPACK_GENERATOR "TGZ;DEB;RPM")
+set(CPACK_PACKAGE_VENDOR "open62541 team")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OPC UA implementation")
+set(CPACK_PACKAGE_DESCRIPTION "open62541 is a C-based library (linking with C++ projects is possible) with all necessary tools to implement dedicated OPC UA clients and servers, or to integrate OPC UA-based communication into existing applications.")
+set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
+set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
+set(CPACK_PACKAGE_VERSION_MAJOR "${OPEN62541_VER_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${OPEN62541_VER_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${OPEN62541_VER_PATCH}${OPEN62541_VER_LABEL}")
+set(CPACK_DEBIAN_PACKAGE_MAINTAINER "open62541 team") #required
+
+include(CPack)