从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: %c
从foo.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
现在,如果-r
在MAKEFLAGS
并且使用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
将仅包含选项字符 。