about summary refs log tree commit diff
path: root/pkgs/by-name/op/open62541/package.nix
blob: 832d376145e18dc2ac718c05df5ddf708b82d021 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
{ stdenv
, lib
, fetchFromGitHub
, cmake
, pkg-config
, check
, libxcrypt
, subunit
, python3Packages
, nix-update-script

, withDoc ? false
, graphviz-nox

, withExamples ? false

, withEncryption ? false # or "openssl" or "mbedtls"
, openssl
, mbedtls

# for passthru.tests only
, open62541
}:

let
  encryptionBackend = {
    inherit openssl mbedtls;
  }."${withEncryption}" or (throw "Unsupported encryption backend: ${withEncryption}");
in

stdenv.mkDerivation (finalAttrs: {
  pname = "open62541";
  version = "1.4.2";

  src = fetchFromGitHub {
    owner = "open62541";
    repo = "open62541";
    rev = "v${finalAttrs.version}";
    hash = "sha256-ziKtRojc/MqRPG//HPESzJa0W0YaHOlz2Mi35UujOkU=";
    fetchSubmodules = true;
  };

  cmakeFlags = [
    (lib.cmakeFeature "OPEN62541_VERSION" finalAttrs.src.rev)
    (lib.cmakeFeature "UA_NAMESPACE_ZERO" "FULL")
    (lib.cmakeBool "BUILD_SHARED_LIBS" (!stdenv.hostPlatform.isStatic))

    # Note comment near doCheck
    (lib.cmakeBool "UA_BUILD_UNIT_TESTS" finalAttrs.finalPackage.doCheck)
    (lib.cmakeBool "UA_ENABLE_ALLOW_REUSEADDR" finalAttrs.finalPackage.doCheck)

    (lib.cmakeBool "UA_BUILD_EXAMPLES" withExamples)
  ] ++ lib.optionals (withEncryption != false) [
    (lib.cmakeFeature "UA_ENABLE_ENCRYPTION" (lib.toUpper withEncryption))
  ];

  nativeBuildInputs = [
    cmake
    pkg-config
    python3Packages.python
  ] ++ lib.optionals withDoc (with python3Packages; [
    sphinx
    sphinx_rtd_theme
    graphviz-nox
  ]);

  buildInputs = lib.optional (withEncryption != false) encryptionBackend;

  buildFlags = [ "all" ] ++ lib.optional withDoc "doc";

  # Tests must normally be disabled because they require
  # -DUA_ENABLE_ALLOW_REUSEADDR=ON. The option must not be used in production,
  # since it is a security risk.
  # See https://github.com/open62541/open62541/issues/6407
  doCheck = false;

  checkInputs = [
    check
    libxcrypt
    subunit
  ];

  # Tests must run sequentially to avoid port collisions on localhost
  enableParallelChecking = false;

  preCheck = let
    disabledTests = [
      # error "Could not create a raw Ethernet socket (are you root?)"
      "check_eventloop_eth"

      # Cannot set socket option IP_ADD_MEMBERSHIP
      "check_pubsub_publish"
      "check_pubsub_publish_json"
      "check_pubsub_connection_udp"
      "check_pubsub_get_state"
      "check_pubsub_publisherid"
      "check_pubsub_subscribe"
      "check_pubsub_publishspeed"
      "check_pubsub_subscribe_config_freeze"
      "check_pubsub_subscribe_rt_levels"
      "check_pubsub_multiple_subscribe_rt_levels"
      "check_pubsub_config_freeze"
      "check_pubsub_publish_rt_levels"

      # Could not find the interface
      "check_pubsub_connection_ethernet"
      "check_pubsub_connection_ethernet_etf"
      "check_pubsub_publish_ethernet_etf"
      "check_pubsub_informationmodel"
      "check_pubsub_informationmodel_methods"
    ];
    regex = "^(${builtins.concatStringsSep "|" disabledTests})\$";
  in lib.optionalString (disabledTests != []) ''
    checkFlagsArray+=(ARGS="-E ${lib.escapeRegex regex}")
  '';

  postInstall = lib.optionalString withDoc ''
    # excluded files, see doc/CMakeLists.txt
    rm -r doc/{_sources/,CMakeFiles/,cmake_install.cmake}

    # doc is not installed automatically
    mkdir -p $out/share/doc/open62541
    cp -r doc/ $out/share/doc/open62541/html
  '' + lib.optionalString withExamples ''
    # install sources of examples
    mkdir -p $out/share/open62541
    cp -r ../examples $out/share/open62541

    ${lib.optionalString (!stdenv.hostPlatform.isWindows) ''
    # remove .exe suffix
    mv -v $out/bin/ua_server_ctt.exe $out/bin/ua_server_ctt
    ''}

    # remove duplicate libraries in build/bin/, which cause forbidden
    # references to /build/ in ua_server_ctt
    rm -r bin/libopen62541*
  '';

  passthru.updateScript = nix-update-script { };

  passthru.tests = let
    open62541Full = encBackend: (open62541.overrideAttrs (_: {
      doCheck = true;
    })).override {
      withDoc = true;
      # if withExamples, one of the example currently fails to build
      #withExamples = true;
      withEncryption = encBackend;
    };
  in {
    open62541WithTests = finalAttrs.finalPackage.overrideAttrs (_: { doCheck = true; });
    open62541Full = open62541Full false;
    open62541Full-openssl = open62541Full "openssl";
    open62541Full-mbedtls = open62541Full "mbedtls";
  };

  meta = with lib; {
    description = "Open source implementation of OPC UA";
    longDescription = ''
      open62541 (http://open62541.org) is an open source and free implementation
      of OPC UA (OPC Unified Architecture) written in the common subset of the
      C99 and C++98 languages.
      The library is usable with all major compilers and provides the necessary
      tools to implement dedicated OPC UA clients and servers, or to integrate
      OPC UA-based communication into existing applications.
    '';
    homepage = "https://www.open62541.org";
    changelog = "https://github.com/open62541/open62541/releases/tag/v${finalAttrs.version}";
    license = licenses.mpl20;
    maintainers = with maintainers; [ panicgh ];
    platforms = platforms.linux;
  };
})