node-gyp on OSX 10.7.5 — dyld: lazy symbol binding

2019-04-28 03:06发布

问题:

I've searched quite a bit, and the closest thing I found to this same question was this (also unanswered) question:

Symbol not found: _libintl_gettext

I'm attempting to make a thin c++ wrapper for libpuzzle.

$ node --version
v0.8.18
$ npm --version
1.2.4
$ node-gyp --version
v0.8.3

Source code on github

Trying to build (I've hand shorted the paths with ...)

$ node-gyp clean configure build && node test.js 
gyp info it worked if it ends with ok
gyp info using node-gyp@0.8.3
gyp info using node@0.8.18 | darwin | x64
gyp info spawn python
gyp info spawn args [ '/opt/local/lib/node_modules/node-gyp/gyp/gyp',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make',
gyp info spawn args   '-I',
gyp info spawn args   '/.../node-puzzle/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/opt/local/lib/node_modules/node-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/.../.node-gyp/0.8.18/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=/.../.node-gyp/0.8.18',
gyp info spawn args   '-Dmodule_root_dir=/.../node-puzzle',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.' ]
gyp info spawn make
  CXX(target) Release/obj.target/puzzle/puzzle.o
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
  SOLINK_MODULE(target) Release/puzzle.node
  SOLINK_MODULE(target) Release/puzzle.node: Finished
gyp info ok 
dyld: lazy symbol binding failed: Symbol not found: __Z19puzzle_init_contextP14PuzzleContext_
  Referenced from: /.../node-puzzle/build/Release/puzzle.node
  Expected in: dynamic lookup

dyld: Symbol not found: __Z19puzzle_init_contextP14PuzzleContext_
  Referenced from: /.../node-puzzle/build/Release/puzzle.node
  Expected in: dynamic lookup

Ok, so this error makes sense to me, clearly it can't load a dynamic library.

At first I thought I had to adjust my binding.gyp to include the linker settings, so I tried several different configurations. At the moment this is what it looks like:

{
    "targets": [
        {
            "target_name": "puzzle",
            "sources": [ "puzzle.cc" ],
            "link_settings": {
                "libraries": [
                    "/opt/local/lib/libgd.dylib",
                    "/opt/local/lib/libpuzzle.dylib"
                ],
            }
        }
    ]
}

I have the libs here:

$ ll /opt/local/lib/libpuzzle.*
-rwxr-xr-x  1 root  admin    19K Jan 30 21:24 /opt/local/lib/libpuzzle.1.dylib
-rw-r--r--  1 root  admin    20K Jan 30 21:24 /opt/local/lib/libpuzzle.a
lrwxr-xr-x  1 root  admin    17B Jan 30 21:24 /opt/local/lib/libpuzzle.dylib -> libpuzzle.1.dylib
-rwxr-xr-x  1 root  admin   1.3K Jan 30 21:24 /opt/local/lib/libpuzzle.la

$ ll /opt/local/lib/libgd.*
-rwxr-xr-x  1 root  admin   252K Sep  2 23:59 /opt/local/lib/libgd.2.dylib
-rw-r--r--  1 root  admin   289K Sep  2 23:59 /opt/local/lib/libgd.a
lrwxr-xr-x  1 root  admin    13B Sep  2 23:59 /opt/local/lib/libgd.dylib -> libgd.2.dylib
-rwxr-xr-x  1 root  admin   1.2K Sep  2 23:59 /opt/local/lib/libgd.la

I just can't figure out how to get dyld to see them. I have tried adjusting DYLD_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH to no avail.

update: output from otool

otool -l build/Release/puzzle.node

build/Release/puzzle.node:
Load command 0
      cmd LC_SEGMENT_64
  cmdsize 552
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x0000000000002000
  fileoff 0
 filesize 8192
  maxprot 0x00000007
 initprot 0x00000005
   nsects 6
    flags 0x0
Section
  sectname __text
   segname __TEXT
      addr 0x0000000000000edc
      size 0x00000000000008d8
    offset 3804
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __stubs
   segname __TEXT
      addr 0x00000000000017b4
      size 0x000000000000010e
    offset 6068
     align 2^1 (2)
    reloff 0
    nreloc 0
     flags 0x80000408
 reserved1 0 (index into indirect symbol table)
 reserved2 6 (size of stubs)
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x00000000000018c4
      size 0x000000000000021c
    offset 6340
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __cstring
   segname __TEXT
      addr 0x0000000000001ae0
      size 0x00000000000001ea
    offset 6880
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000002
 reserved1 0
 reserved2 0
Section
  sectname __unwind_info
   segname __TEXT
      addr 0x0000000000001cca
      size 0x000000000000008c
    offset 7370
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __eh_frame
   segname __TEXT
      addr 0x0000000000001d58
      size 0x00000000000002a8
    offset 7512
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 1
      cmd LC_SEGMENT_64
  cmdsize 472
  segname __DATA
   vmaddr 0x0000000000002000
   vmsize 0x0000000000001000
  fileoff 8192
 filesize 4096
  maxprot 0x00000007
 initprot 0x00000003
   nsects 5
    flags 0x0
Section
  sectname __dyld
   segname __DATA
      addr 0x0000000000002000
      size 0x0000000000000010
    offset 8192
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __got
   segname __DATA
      addr 0x0000000000002010
      size 0x0000000000000010
    offset 8208
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000006
 reserved1 45 (index into indirect symbol table)
 reserved2 0
Section
  sectname __la_symbol_ptr
   segname __DATA
      addr 0x0000000000002020
      size 0x0000000000000168
    offset 8224
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000007
 reserved1 47 (index into indirect symbol table)
 reserved2 0
Section
  sectname __data
   segname __DATA
      addr 0x0000000000002190
      size 0x0000000000000060
    offset 8592
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __const
   segname __DATA
      addr 0x00000000000021f0
      size 0x0000000000000030
    offset 8688
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 2
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __LINKEDIT
   vmaddr 0x0000000000003000
   vmsize 0x0000000000002000
  fileoff 12288
 filesize 6648
  maxprot 0x00000007
 initprot 0x00000001
   nsects 0
    flags 0x0
Load command 3
          cmd LC_ID_DYLIB
      cmdsize 48
         name @rpath/puzzle.node (offset 24)
   time stamp 1 Wed Dec 31 19:00:01 1969
      current version 0.0.0
compatibility version 0.0.0
Load command 4
     cmd LC_SYMTAB
 cmdsize 24
  symoff 12720
   nsyms 138
  stroff 15344
 strsize 3592
Load command 5
            cmd LC_DYSYMTAB
        cmdsize 80
      ilocalsym 0
      nlocalsym 76
     iextdefsym 76
     nextdefsym 19
      iundefsym 95
      nundefsym 43
         tocoff 0
           ntoc 0
      modtaboff 0
        nmodtab 0
   extrefsymoff 0
    nextrefsyms 0
 indirectsymoff 14976
  nindirectsyms 92
      extreloff 14928
        nextrel 6
      locreloff 12288
        nlocrel 50
Load command 6
     cmd LC_UUID
 cmdsize 24
    uuid 9A75E329-2D02-3AC8-A249-A741702EB141
Load command 7
      cmd LC_VERSION_MIN_MACOSX
  cmdsize 16
  version 10.5
      sdk 10.7
Load command 8
          cmd LC_LOAD_DYLIB
      cmdsize 64
         name /opt/local/lib/libssl.1.0.0.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1.0.0
compatibility version 1.0.0
Load command 9
          cmd LC_LOAD_DYLIB
      cmdsize 64
         name /opt/local/lib/libcrypto.1.0.0.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1.0.0
compatibility version 1.0.0
Load command 10
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /opt/local/lib/libgd.2.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 3.0.0
compatibility version 3.0.0
Load command 11
          cmd LC_LOAD_DYLIB
      cmdsize 64
         name /opt/local/lib/libpuzzle.1.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 2.0.0
compatibility version 2.0.0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libstdc++.6.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 52.0.0
compatibility version 7.0.0
Load command 13
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 159.1.0
compatibility version 1.0.0
Load command 14
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libgcc_s.1.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1094.0.0
compatibility version 1.0.0
Load command 15
      cmd LC_FUNCTION_STARTS
  cmdsize 16
  dataoff 12688
 datasize 32
Load command 16
      cmd LC_DATA_IN_CODE
  cmdsize 16
  dataoff 12720
 datasize 0

otool -L build/Release/puzzle.node

build/Release/puzzle.node:
    @rpath/puzzle.node (compatibility version 0.0.0, current version 0.0.0)
    /opt/local/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
    /opt/local/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
    /opt/local/lib/libgd.2.dylib (compatibility version 3.0.0, current version 3.0.0)
    /opt/local/lib/libpuzzle.1.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1094.0.0)

回答1:

The symbol that dyld is complaining about is __Z19puzzle_init_contextP14PuzzleContext_. In its unmangled form, it is puzzle_init_context(PuzzleContext_*). The mangling indicates that it was considered by the compiler to be a C++ symbol. However, libpuzzle appears to export a pure C interface. This means that the symbol it should be looking for is _puzzle_init_context. You can fix this by wrapping the #include <puzzle.h> in an extern "C" { … } block to inform the compiler that the contents of the header should be treated as C code, so it will handle the symbol names by the appropriate rules.

This sort of error is typically detected by the static linker rather than at runtime by the dynamic linker. The Expected in: dynamic lookup portion of your error message indicates that puzzle.node was linked with -undefined dynamic_lookup. This tells the static linker not to emit any errors for undefined symbols, but instead to have the dynamic linker attempt to resolve the symbols at runtime. This is rarely the behavior you want.