我正在使用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'.
所以它看起来像隐式构建规则被抑制(?)
答案 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
将只包含选项字符。