从node-gyp

时间:2016-06-20 15:35:53

标签: node.js gnu-make node-gyp gyp

我正在使用node-gyp在Linux上构建用C ++编写的本机Node.js插件。

加载项依赖于另一个共享库。这个库目前没有用gyp构建,它只有一个makefile。

如果我首先构建共享库,然后构建我的附加组件,在binding.gyp文件的主目标中指定'libraries'的值,一切正常。

然而,我喜欢要做的是通过在共享库的makefile上调用make,从node-gyp进程中的source构建共享库。我尝试使用'action'属性将依赖目标添加到附加组件的binding.gyp并使主目标依赖于它:

    {
        "target_name": "other_library",
        "type": "none",
        "actions": [
            {
                "action_name": "build_other_library",
                "inputs": [],
                "outputs": [ "/path/to/build/output/libother.so" ],
                "action": [ "make", "-C", "/path/to/makefile" ]
            }
        ]
    }

这不完全有效。 找到其他makefile并且make正在启动(我可以看到这发生了--verbose set),但是makefile没有正确执行。

当共享库的makefile运行时,似乎正在抑制GNU make的隐式构建规则。这意味着.cc和.cpp文件未编译为.o文件。

我意识到node-gyp本身为binding.gyp中的目标生成了一组makefile,并且正在从其中一个派生出共享库的makefile。

是否继承了node-gyp的make设置,包括内置规则的抑制?

周围有办法吗? (除了向共享库的makefile添加显式构建规则之外)?

(我尝试用$(MAKE)替换make,它没有任何区别)。

编辑:

使用shell中指定的-d在共享库上运行GNU make(即在node-gyp外部),搜索典型源文件的隐式规则如下所示:

   Considering target file `code.o'.
     File `code.o' does not exist.
     Looking for an implicit rule for `code.o'.
     Trying pattern rule with stem `code'.
     Trying implicit prerequisite `code.c'.
     Trying pattern rule with stem `code'.
     Trying implicit prerequisite `code.cc'.
     Trying pattern rule with stem `code'.
     Trying implicit prerequisite `code.C'.
     Trying pattern rule with stem `code'.
     Trying implicit prerequisite `code.cpp'.
     Found prerequisite `code.cpp' as VPATH `../Common/code.cpp'
     Found an implicit rule for `code.o'.

在node-gyp依赖目标的action块中添加-d到调用,同一个源文件得到:

Considering target file `code.o'.
 File `code.o' does not exist.
 Looking for an implicit rule for `code.o'.
 No implicit rule found for `code.o'.

所以它看起来像隐式构建规则被抑制(?)

1 个答案:

答案 0 :(得分:1)

node-gyp在其顶级makefile中设置MAKEFLAGS=-r-r是简短的 --no-builtin-rules的形式,默认情况下会传递给任何形式 子品牌。

但是,您将能够为子制作​​重新启用内置规则 通过将MAKEFLAGS设置回调用环境中的默认状态。

无需更改绑定操作,您可以通过prememptively export实现此目的 在makefile中纠正MAKEFLAGS,然后重新调用$(MAKE)

为了说明,假装这是你的原始makefile:

all: foo

foo: foo.o
    $(CC) -o $@ $<

您正在从一个源文件foo创建一个程序foo.c(假设 存在于工作目录中)并指望编译%o: %c的内置规则 来自foo.o的{​​{1}}。因此,使用此makefile,构建将失败:

foo.c

像这样更改makefile:

*** No rule to make target 'foo.o', needed by 'foo'. Stop.

现在,如果ifneq ($(MAKEFLAGS),w) all: export MAKEFLAGS=-w && $(MAKE) else all: foo foo: foo.o $(CC) -o $@ $< endif 位于-r并且MAKEFLAGS使用MAKEFLAGS=-w,那么make将会递归:

$ node-gyp build
gyp info it worked if it ends with ok
gyp info using node-gyp@3.0.3
gyp info using node@4.2.6 | linux | x64
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
make: Entering directory '/home/imk/develop/scrap/build'
  ACTION binding_gyp_prog_target_build_foo foo
make[1]: Entering directory '/home/imk/develop/scrap'
export MAKEFLAGS=-w && make
make[2]: Entering directory '/home/imk/develop/scrap'
cc    -c -o foo.o foo.c
cc -o foo foo.o
make[2]: Leaving directory '/home/imk/develop/scrap'
make[1]: Leaving directory '/home/imk/develop/scrap'
  TOUCH Release/obj.target/prog.stamp
make: Leaving directory '/home/imk/develop/scrap/build'
gyp info ok 

-w--print-directory的缩写)就是那个 在node-gyp添加-r之前有效的默认选项。

请注意,测试ifneq ($(MAKEFLAGS),w)是正确的。它不应该是ifneq ($(MAKEFLAGS),-w)。 如果环境变量 MAKEFLAGS包含make命令行选项 那么 GNU Make特殊变量 MAKEFLAGS将只包含选项字符