Невозможно связать собственный надстройку C++ nodeJS с OpenSSL, статически связанный с узлом (0.10.18) при сборке с помощью node-gyp

Я прочитал это: https://github.com/TooTallNate/node-gyp/wiki/Linking-to-OpenSSL, но у меня почему-то не работает. Я получаю «неопределенный символ: SHA1» при попытке потребовать аддон от node. Вот мой код (src/sha_export.cc):

#include <node.h>
#include <node_buffer.h>
#include <v8.h>

#include <openssl/sha.h>

using namespace v8;

Handle<Value> Sha1(const Arguments& args) {
  HandleScope scope;

  if (args.Length() < 1) {
    ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
    return scope.Close(Undefined());
  }

  unsigned char*msg = (unsigned char*) node::Buffer::Data(args[0]->ToObject());
  size_t msglen = node::Buffer::Length(args[0]->ToObject());
  unsigned char dgst[20];

  SHA1(msg, msglen, dgst);

  return scope.Close(node::Buffer::New((const char*)dgst, 20)->handle_);
}

void init(Handle<Object> exports) {
  exports->Set(String::NewSymbol("sha1"),
    FunctionTemplate::New(Sha1)->GetFunction());
}

NODE_MODULE(token, init)

а вот привязка.gyp:

{
  'targets': [
    {
       "target_name": "token"
     , "sources": [ "src/sha_export.cc" ]
     ,'conditions': [
        ['node_shared_openssl=="false"', {
          # so when "node_shared_openssl" is "false", then OpenSSL has been
          # bundled into the node executable. So we need to include the same
          # header files that were used when building node.
          'include_dirs': [
            '<(node_root_dir)/deps/openssl/openssl/include'
          ],
          "conditions" : [
            ["target_arch=='ia32'", {
              "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
            }],
            ["target_arch=='x64'", {
              "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
            }],
            ["target_arch=='arm'", {
              "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
            }]
          ]
        }]
      ]
    }
  ]
}

Я проверил, что для node_shared_openssl установлено значение false в config.gypi, и даже поместил #error в sha.h в /deps/openssl, чтобы убедиться, что он включен. Тем не менее, я все еще получаю «неопределенный символ: SHA1» при запросе надстройки, что, очевидно, означает, что ссылка на связанный OpenSSL не работает. Если я добавлю

     , 'link_settings': {
          'libraries': [
              '-lcrypto'
          ]
      }

после sources все работает, но затем ldd token.node показывает libcrypto.so.1.0.0 => /lib/i386-linux-gnu/libcrypto.so.1.0.0 (0xb7525000), что означает, что вместо этого я сейчас подключаюсь к общему динамическому OpenSSL. Итак, мой вопрос: возможно ли вообще ссылаться на OpenSSL, статически связанный с узлом? Что я тогда делаю не так?

Большое спасибо!

PS На всякий случай: ОС Ubuntu 12.04 LTS


person Dmitry    schedule 20.09.2013    source источник


Ответы (1)


Что ж, отвечая на мой собственный вопрос... Получил некоторую помощь от Бена Нордхуисона в Node.js IRC. Большое спасибо Бен!

По-видимому, существует ограниченное количество подпрограмм OpenSSL, предоставляемых исполняемым файлом узла, в основном только те, которые узел использует сам, и в моем случае это не включало функцию SHA1 более высокого уровня, но включает функции более низкого уровня: SHA1_Init, SHA1_Update и SHA1_Final. Изменил мой код, чтобы он выглядел

SHA_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, msg, msglen);
SHA1_Final(dgst, &ctx);

вместо просто SHA1(msg, msglen, dgst);, и он отлично работает без внешних зависимостей.

По словам Бена, также могут быть некоторые проблемы с подключением к статическому OpenSSL в Windows: не могу комментировать это, используя только Linux.

person Dmitry    schedule 21.09.2013