从node-gyp调用make

我正在使用node-gyp构build一个在Linux上用C ++编写的本地Node.js插件。

加载项依赖于另一个共享库。 这个库目前不是用gyp构build的,它只是一个makefile。

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

但是,我想要做的是通过在共享库的makefile上调用make,从node-gyp进程内的源代码构build共享库。 我尝试使用'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设置),但生成文件不正确执行。

GNU make的隐式构build规则似乎在共享库的makefile运行时被压制。 这意味着.cc和.cpp文件不被编译为.o文件。

我意识到node-gyp本身就是从binding.gyp中的目标生成一组加载项的makefile文件,共享库的makefile文件正在从其中生成。

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

有没有办法解决它? (除了向共享库的makefile中添加显式构build规则)?

(我已经尝试用$(MAKE)replacemake,这没有什么区别)。

编辑:

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

  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依赖目标中的操作块中将-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'. 

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

node-gyp在其顶层makefile中设置MAKEFLAGS=-r-r--no-builtin-rules的简写forms,默认情况下这是传递给任何子作品。

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

在不改变绑定动作的情况下,你可以通过premamptively在你的makefile中导出校正过的MAKEFLAGS ,然后重新调用$(MAKE)

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

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

其中你从一个源文件foo.c (假设存在于工作目录中)制作一个foo程序,并依靠%o: %c的内置规则%o: %cfoo.c编译foo.o 所以这个makefile的构build会失败:

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

像这样更改makefile:

 ifneq ($(MAKEFLAGS),w) all: export MAKEFLAGS=-w && $(MAKE) else all: foo foo: foo.o $(CC) -o $@ $< endif 

现在,如果-rMAKEFLAGS并且使用MAKEFLAGS=-w运行,则MAKEFLAGS=-w会recursion:

 $ 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之前的一个默认选项。

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