【问题标题】:Linking a shared library with node-addon-api使用 node-addon-api 链接共享库
【发布时间】:2021-09-20 23:03:04
【问题描述】:

我正在使用 node-gypnode-addon-api 为 C 共享库构建 Node.js 包装器。有用!但是由于该库是从 Golang 代码构建的,因此我针对不同的架构有不同的构建——该模块无法从 Go 源代码本身编译 C 库。

我的问题是,一旦我将库文件移动到 Node 模块内的子目录中,该模块就不再工作了。我希望该库位于子目录中,以便我可以使用条件提供为不同架构构建的副本。

根目录下的所有文件如下:

node-mylib/
┣ build/
┃ ┣ Release/
┃ ┃ ┣ .deps/
┃ ┃ ┃ ┗ Release/
┃ ┃ ┃   ┣ obj.target/
┃ ┃ ┃   ┗ mylib.node.d
┃ ┃ ┣ obj.target/
┃ ┃ ┃ ┗ mylib/
┃ ┃ ┃   ┗ mylib.o
┃ ┃ ┗ mylib.node
┃ ┣ Makefile
┃ ┣ binding.Makefile
┃ ┣ config.gypi
┃ ┣ mylib.target.mk
┃ ┗ gyp-mac-tool
┣ binding.gyp
┣ mylib.cc
┣ index.js
┣ libmylib.h
┣ libmylib.so
┣ package-lock.json
┗ package.json

还有一个像这样的binding.gyp

{
  "targets": [
    {
      "conditions": [
        ['OS=="mac"', {
            'cflags+': ['-fvisibility=hidden'],
            'xcode_settings': {
              'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
            }
        }]
      ],
      "defines": [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
      "include_dirs": ["<(module_root_dir)", "<!(node -p \"require('node-addon-api').include_dir\")"],
      "target_name": "mylib",
      "sources": [ "mylib.cc" ],
      "libraries": [ "-Wl,-rpath,<(module_root_dir)", '-lmylib', '-L<(module_root_dir)'],
    }
  ]
}

...然后node-gyp rebuild 运行良好,node index.js 从库返回预期的输出。

当我将库移动到子目录中时,如下所示:

node-biodiversity/
┣ build/
┃ ┣ Release/
┃ ┃ ┣ .deps/
┃ ┃ ┃ ┗ Release/
┃ ┃ ┃   ┣ obj.target/
┃ ┃ ┃   ┗ mylib.node.d
┃ ┃ ┣ obj.target/
┃ ┃ ┃ ┗ mylib/
┃ ┃ ┃   ┗ macos-arm64/
┃ ┃ ┃     ┗ mylib.o
┃ ┃ ┗ mylib.node
┃ ┣ Makefile
┃ ┣ binding.Makefile
┃ ┣ config.gypi
┃ ┣ mylib.target.mk
┃ ┗ gyp-mac-tool
┣ macos-arm64/
┃ ┣ mylib.cc
┃ ┣ libmylib.h
┃ ┗ libmylib.so
┣ binding.gyp
┣ index.js
┣ package-lock.json
┗ package.json

并像这样更新binding.gyp

{
  "targets": [
    {
      "conditions": [
        ['OS=="mac"', {
            'cflags+': ['-fvisibility=hidden'],
            'xcode_settings': {
              'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
            }
        }]
      ],
      "defines": [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
      "include_dirs": ["<(module_root_dir)", "<(module_root_dir)/macos-arm64", "<!(node -p \"require('node-addon-api').include_dir\")"],
      "target_name": "mylib",
      "sources": [ "macos-arm64/mylib.cc" ],
      "libraries": [ "-Wl,-rpath,<(module_root_dir)/macos-arm64", '-lmylib', '-L<(module_root_dir)/macos-arm64'],
    }
  ]
}

我收到此错误:

Error: dlopen(/Users/toby/Code/node-mylib/build/Release/mylib.node, 1): Library not loaded: libmylib.so
  Referenced from: /Users/toby/Code/node-mylib/build/Release/mylib.node
  Reason: image not found

我已经尝试了 librariesinclude_dirs 的所有组合,但无法找到库。

【问题讨论】:

    标签: c++ node.js node-gyp node-addon-api


    【解决方案1】:

    我可以让这个工作的唯一方法是在 node-gyp postbuild 中使用install_name_tool

    {
      "targets": [
        {
          "conditions": [
            ['OS=="mac"', {
                'cflags+': ['-fvisibility=hidden'],
                'xcode_settings': {
                  'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
                }
            }]
          ],
          "defines": [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
          "include_dirs": ["<(module_root_dir)/macos-arm64", "<!(node -p \"require('node-addon-api').include_dir\")"],
          "target_name": "mylib",
          "sources": [ "macos-arm64/mylib.cc" ],
          "libraries": ['<(module_root_dir)/macos-arm64/libmylib.so'],
          "postbuilds": [
            {
              "postbuild_name": 'Change libmylib load path',
              "action": ['install_name_tool', '-change',  'libmylib.so', '@loader_path/../../macos-arm64/libmylib.so', '<(PRODUCT_DIR)/mylib.node'],
            },
          ],
        }
      ]
    }
    
    

    【讨论】:

      【解决方案2】:

      查看我对这个问题的回答:Program compiles, but cannot run because of missing library that exists

      我所说的一切也适用于 macOS。您有 3 种方法可以让运行时链接器知道您的库:

      • 将其安装在标准位置之一
      • 在运行前指定环境变量
      • 在链接可执行文件时嵌入自定义位置

      【讨论】:

        猜你喜欢
        • 2010-10-18
        • 2017-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-02
        • 2013-08-15
        • 1970-01-01
        相关资源
        最近更新 更多