2013-09-20 1 views
2

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

#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) 

и вот binding.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 установить ложь в config.gypi, и даже положить #Error в ша .h in/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

ответ

2

Ну, отвечая на мой собственный вопрос ... Got некоторую помощь от Бен Noordhuison на 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.