A binding.gyp with dependencies that live outside of its directory will create misplaced artifacts with the makefile generator (usually, on mac & linux). The dependency will be resolved to a relative path with parent directory segments (../../*) and those get joined as-is to the build directory (./build/../../*), resulting in build files outside of the build directory. This result may confuse other tooling too, unfortunately.
For example, the following code in the makefile generator produces a path like ./build/../../node_modules/node-addon-api/node_addon_api.target.mk:
|
if options.generator_output: |
|
output_file = os.path.join( |
|
options.depth, options.generator_output, base_path, base_name |
|
) |
Motivating example
I have a multi-workspace project set up like this:
super/ (root)
package.json (defines "workspaces")
workspaces/
super has no dependencies, and native only depends on node-gyp and node-addon-api. Note that in this setup, npm hoists node-addon-gyp to the root node_modules/.
node-addon-api recommends adding it as a dependency in binding.gyp:
# super/workspaces/native/binding.gyp
{
"targets": [{
"target_name": "native",
"sources": ["module.cc"],
"dependencies": ["<!(node -p \"require('node-addon-api').targets\"):node_addon_api"]
}]
}
After running node-gyp rebuild, we end up with some mysterious build artifacts:
super/ (root)
node_modules/ ... (real, created by npm)
workspaces/
node_modules/ (not real, created by gyp)
node-addon-api/
node_addon_api_except_all.target.mk
node_addon_api_except.target.mk
node_addon_api_maybe.target.mk
node_addon_api.target.mk
node_addon_api.Makefile
A real issue that this causes is npm list failing:
$ npm ls
super@0.0.1 /[...]/super
├─┬ native@0.0.1 -> ./workspaces/native
│ ├── bindings@1.5.0
│ ├── node-addon-api@ invalid: "^8.5.0" from workspaces/native
│ └── node-gyp@12.1.0
└── node-addon-api@8.5.0 extraneous
npm error code ELSPROBLEMS
npm error extraneous: node-addon-api@8.5.0 /[...]/node_modules/node-addon-api
npm error invalid: node-addon-api@ /[...]/workspaces/node_modules/node-addon-api
# exit code 1
We also see some misplaced files within the build directory too:
super/workspaces/native/build/
node_modules/ (should be within Release/obj.target/)
Release/ ...
I haven't found these artifacts to cause issues, but I am highlighting them because they share the same root cause.
A
binding.gypwith dependencies that live outside of its directory will create misplaced artifacts with the makefile generator (usually, on mac & linux). The dependency will be resolved to a relative path with parent directory segments (../../*) and those get joined as-is to the build directory (./build/../../*), resulting in build files outside of the build directory. This result may confuse other tooling too, unfortunately.For example, the following code in the makefile generator produces a path like
./build/../../node_modules/node-addon-api/node_addon_api.target.mk:gyp-next/pylib/gyp/generator/make.py
Lines 2433 to 2436 in 732b09e
Motivating example
I have a multi-workspace project set up like this:
super/(root)package.json(defines"workspaces")workspaces/native/package.jsonbinding.gypsuperhas no dependencies, andnativeonly depends onnode-gypandnode-addon-api. Note that in this setup, npm hoistsnode-addon-gypto the rootnode_modules/.node-addon-apirecommends adding it as a dependency inbinding.gyp:After running
node-gyp rebuild, we end up with some mysterious build artifacts:super/(root)node_modules/... (real, created by npm)workspaces/node_modules/(not real, created by gyp)node-addon-api/node_addon_api_except_all.target.mknode_addon_api_except.target.mknode_addon_api_maybe.target.mknode_addon_api.target.mknode_addon_api.MakefileA real issue that this causes is
npm listfailing:We also see some misplaced files within the build directory too:
super/workspaces/native/build/node_modules/(should be withinRelease/obj.target/)node-addon-api/node_addon_api.stampRelease/...I haven't found these artifacts to cause issues, but I am highlighting them because they share the same root cause.