C++代码使用普通的V8引擎编译良好,无法使用Node提供的V8进行构建

C++ code compiles fine with normal V8 engine, fails to build with V8 provided by Node

本文关键字:V8 Node 构建 代码 引擎 编译 C++      更新时间:2023-10-16

Makefile:

CC:=g++
OUTFILE?=addon
SOURCE?=src
CFLAGS+=-Iinclude -lv8 -m64
.PHONY: all clean
all:
    $(CC) $(CFLAGS) -o $(OUTFILE) `ls $(SOURCE)/*.cc`
clean:
    rm -f $(OUTFILE)

addon.h:

#ifndef __addon_h
#define __addon_h

#define BUILDING_NODE_EXTENSION
#define ADDON_VERSION "0.0.1"

#ifdef BUILDING_NODE_EXTENSION
  #include <node/node.h>
  #include <node/v8.h>
#else
  #include <v8.h>
#endif

using namespace v8;
void init(Handle<Object> exports);
Handle<Object> setupExports(Handle<Object> exports);
#endif

addon.cc:

#include <cstdlib>
#include <cstdio>
#include <addon.h>
using namespace v8;
#ifndef BUILDING_NODE_EXTENSION
  int main(int argc, char **argv) {
    Isolate *isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);
    Handle<Context> context = Context::New(isolate);
    Context::Scope context_scope(context);
    Handle<Object> exports = Object::New();
    init(exports);
    printf("Version: %sn", *String::Utf8Value(exports->Get(String::New("version"))));
    return 0;
  }
#else
  int main() {
    printf("This is a module compiled for Node.nPlease use require in Node to use this file.n");
    return 0;
  }
#endif
void init(Handle<Object> exports) {
  setupExports(exports);
}
Handle<Object> setupExports(Handle<Object> exports) {
  // Set version number.
  exports->Set(String::New("version"), String::New(ADDON_VERSION));
  return exports;
}

#ifdef BUILDING_NODE_EXTENSION
  NODE_MODULE(addon, init)
#endif

当使用未定义BUILDING_NODE_EXTENSION的普通V8引擎编译上述代码时,输出是我们所期望的:

 ❱ make && ./addon
g++ -Iinclude -lv8 -m64 -o addon `ls src/*.cc`
Version: 0.0.1

当使用定义的BUILDING_NODE_EXTENSION进行编译时,使用Node的<node/node.h><node/v8.h>作为includes,而不是普通的<v8.h>,我得到的是:

 ❱ make && ./addon
g++ -Iinclude -lv8 -m64 -o addon `ls src/*.cc`
Undefined symbols for architecture x86_64:
  "v8::String::New(char const*, int)", referenced from:
      setupExports(v8::Handle<v8::Object>)       in ccRntYkS.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [all] Error 1

有人知道这里出了什么问题吗?

使用node-gyp构建解决了问题。

脸。棕榈

Makefile change:

CC:=g++
OUTFILE?=addon
SOURCE?=src
CFLAGS+=-Iinclude -lv8 -m64
.PHONY: all clean
all:
    if [ -d build ]; then 
        node-gyp build; 
    else 
        $(CC) $(CFLAGS) -o $(OUTFILE) `ls $(SOURCE)/*.cc`; 
    fi;
clean:
    rm -f $(OUTFILE)