从 node-gyp 调用 make
Invoking make from node-gyp
我正在使用 node-gyp 在 Linux 上构建一个用 C++ 编写的本机 Node.js 附加组件。
加载项依赖于另一个共享库。这个库目前不是用 gyp 构建的,它只有一个 makefile。
如果我先构建共享库,然后构建我的附加组件,在我的 binding.gyp 文件的主要目标中为 'libraries' 指定一个值,一切正常。
但是,我喜欢做的是通过在共享库的 makefile 上调用 make,从 node-gyp 进程中的源代码构建共享库。我尝试使用 '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 看到这种情况),但是 makefile 没有正确执行。
当共享库的 makefile 运行时,GNU make 的隐式构建规则似乎被抑制了。这意味着 .cc 和 .cpp 文件不会被编译为 .o 文件。
我意识到 node-gyp 本身正在从 binding.gyp 中的目标为附加组件生成一组 makefile,并且共享库的 makefile 是从其中一个生成的。
是否继承了node-gyp的make设置,包括内置规则的抑制?
有解决办法吗? (除了向共享库的 makefile 添加显式构建规则之外)?
(我尝试用 $(MAKE) 替换 make,但没有任何区别)。
编辑:
运行 GNU make 在共享库上使用 shell 指定的 -d(即在 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'.
将 -d 添加到 node-gyp 相关目标的操作块中的调用,相同的源文件得到这个:
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'.
所以看起来隐式构建规则确实被抑制了 (?)
node-gyp
在其顶层 makefile 中设置 MAKEFLAGS=-r
。 -r
是短的
--no-builtin-rules
的形式,默认情况下,它会传递给任何
子品牌。
但是,您将能够为您的子品牌重新启用内置规则
通过将 MAKEFLAGS
设置回调用环境中的默认状态。
在不更改绑定操作的情况下,您可以通过抢先导出来实现
在您的 makefile 中纠正 MAKEFLAGS
,然后重新调用 $(MAKE)
。
为了说明,假设这是您的原始 makefile:
all: foo
foo: foo.o
$(CC) -o $@ $<
其中您正在从一个源文件 foo.c
制作一个程序 foo
(假设
存在于工作目录中)并依靠 %o: %c
的内置规则进行编译
foo.o
来自 foo.c
。因此使用此 makefile 构建将失败:
*** 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
则 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
将只包含 选项字符 .
我正在使用 node-gyp 在 Linux 上构建一个用 C++ 编写的本机 Node.js 附加组件。
加载项依赖于另一个共享库。这个库目前不是用 gyp 构建的,它只有一个 makefile。
如果我先构建共享库,然后构建我的附加组件,在我的 binding.gyp 文件的主要目标中为 'libraries' 指定一个值,一切正常。
但是,我喜欢做的是通过在共享库的 makefile 上调用 make,从 node-gyp 进程中的源代码构建共享库。我尝试使用 '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 看到这种情况),但是 makefile 没有正确执行。
当共享库的 makefile 运行时,GNU make 的隐式构建规则似乎被抑制了。这意味着 .cc 和 .cpp 文件不会被编译为 .o 文件。
我意识到 node-gyp 本身正在从 binding.gyp 中的目标为附加组件生成一组 makefile,并且共享库的 makefile 是从其中一个生成的。
是否继承了node-gyp的make设置,包括内置规则的抑制?
有解决办法吗? (除了向共享库的 makefile 添加显式构建规则之外)?
(我尝试用 $(MAKE) 替换 make,但没有任何区别)。
编辑:
运行 GNU make 在共享库上使用 shell 指定的 -d(即在 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'.
将 -d 添加到 node-gyp 相关目标的操作块中的调用,相同的源文件得到这个:
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'.
所以看起来隐式构建规则确实被抑制了 (?)
node-gyp
在其顶层 makefile 中设置 MAKEFLAGS=-r
。 -r
是短的
--no-builtin-rules
的形式,默认情况下,它会传递给任何
子品牌。
但是,您将能够为您的子品牌重新启用内置规则
通过将 MAKEFLAGS
设置回调用环境中的默认状态。
在不更改绑定操作的情况下,您可以通过抢先导出来实现
在您的 makefile 中纠正 MAKEFLAGS
,然后重新调用 $(MAKE)
。
为了说明,假设这是您的原始 makefile:
all: foo
foo: foo.o
$(CC) -o $@ $<
其中您正在从一个源文件 foo.c
制作一个程序 foo
(假设
存在于工作目录中)并依靠 %o: %c
的内置规则进行编译
foo.o
来自 foo.c
。因此使用此 makefile 构建将失败:
*** 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
则 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
将只包含 选项字符 .