Electron native addon failing on windows - node.js

I have a native addon that uses openSSL library on a unpacked electron app.
On a windows 10 it works and on a windows 7 it's not working , I am receiving this:
Error: The specified module could not be found.
\\?\C:\Program Files (x86)\AppX Player\resources\app\src\addon\foo.node
at Error (native)
at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:167:20)
at Object.Module._extensions..node (module.js:568:18)
at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:167:20)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.require (module.js:468:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (C:\Program Files (x86)\AppX Player\resources\app\s
rc\addon\index.js:11:3)
I am targeting a windows ia32 architecture for electron and I rebuild it like the following:
node-gyp rebuild --target=1.3.1 --arch=ia32 --dist-url=https://atom.io/download/atom-shell --verbose
The binding-gyp of the file looks like this and is based on this. It uses the openSSL static library
{
"targets": [
{
"target_name": "addon",
"sources": [
"./src/encryptor.cpp" ,
"./src/EncryptorHandler.cpp",
"./src/SetupHandler.cpp",
"./src/RC4Handler.cpp",
"./src/HardwareInfoHandler.cpp",
"../Encryptions/RC4.cpp",
"../Encryptions/AES.cpp",
"../Encryptions/utils.cpp",
"../oggEncDec/src/FileHandler.cpp",
"../oggEncDec/src/OGGSelectiveEncryptor.cpp",
"../machineIdentification/common.cpp"
],
"cflags!": [ "-fno-exceptions" ],
"cflags_cc!": [ "-fno-exceptions" ],
'cflags': ['-fexceptions'],
'cflags_cc': ['-fexceptions -Wall -Wextra -Wconversion'],
"include_dirs": [
"<!(node -e \"require('nan')\")",
"../"
],
'conditions': [
['OS=="linux"', {
"sources": [
"../machineIdentification/linuxHardwareInfo.cpp"
],
'libraries': [
'-lcrypto',
],
}
],
['OS=="mac"', {
"sources": [
"../machineIdentification/macHardwareInfo.cpp"
],
'libraries': [
'-lcrypto',
],
}],
['OS=="win"', {
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': [ '/EHsc' ],
'ExceptionHandling': 1
}
},
"sources": [
"../machineIdentification/windowsHardwareInfo.cpp"
],
'conditions': [
# "openssl_root" is the directory on Windows of the OpenSSL files.
# Check the "target_arch" variable to set good default values for
# both 64-bit and 32-bit builds of the module.
['target_arch=="x64"', {
'variables': {
'openssl_root%': 'C:/OpenSSL-Win64'
},
}, {
'variables': {
'openssl_root%': 'C:/OpenSSL-Win32'
},
}],
],
'libraries': [
'-l<(openssl_root)/lib/libeay32.lib',
],
'include_dirs': [
'<(openssl_root)/include',
],
}]
]
}
]
}
Just in case it was a dll missing (it should not be as I was linking the static library) I added the openSSL dll on the same level of the exe. What else may be causing this behaviour?
Edit
Installing OpenSSL binaries make it works, i thought the static linking would take care of that so I wouldn't depend on external dll's
Edit 2
Everything would be solved if I could pack the static library and bundle it on the ".node" file. Using dependency walker on the .node file shows me that it is requiring the dll and what I need is for it to have the dll code on it.

Turns out the lib on http://slproweb.com/products/Win32OpenSSL.html seems to be just a wrapper around the dll that still uses it.
I misguided thought that node-gyp was just compiling the thing without the dependency which is not true.
I found another precompiled openssl lib here that did the trick.
So to wrap up:
I needed to ship something with OpenSSL under electron but electron does not expose OpenSSL like node does and switchs it for borinSSL.
I followed tooTallNate article that recommended a static library and assumed the static library was right and I was somehow needing the DLL and I assumed node-gyp was not bundling the used static library.
Switching the lib for another one (or better yet compiling it myself) did the trick.

Related

Nuxt installation error : Rule can only have one resource source (provided resource and test + include + exclude)

I successfully installed Vuejs and Nodejs but got a problem when installing Nuxtjs. This is what I get. I already asked some friends but it didn't work. Thanks for your help ! :)
Error : Rule can only have one resource source (provided resource and test + include + exclude)
Rule can only have one resource source (provided resource and test + include + exclude) in {
"use": [
{
"loader": "C:\\Users\\User\\Desktop\\JS\\my-first-project\\node_modules\\babel-loader\\lib\\index.js",
"options": {
"configFile": false,
"babelrc": false,
"cacheDirectory": true,
"envName": "server",
"presets": [
[
"C:\\Users\\User\\Desktop\\JS\\my-first-project\\node_modules\\#nuxt\\babel-preset-app\\src\\index.js",
{
"corejs": {
"version": 3
}
}
]
]
},
"ident": "clonedRuleSet-30[0].rules[0].use[0]"
}
]
}
"use": [
{
"loader": "C:\\Users\\User\\Desktop\\JS\\my-first-project\\node_modules\\babel-loader\\lib\\index.js",
"options": {
"configFile": false,
"babelrc": false,
"cacheDirectory": true,
"envName": "server",
"presets": [
[
"C:\\Users\\User\\Desktop\\JS\\my-first-project\\node_modules\\#nuxt\\babel-preset-app\\src\\index.js",
{
"corejs": {
"version": 3
}
}
]
]
},
"ident": "clonedRuleSet-30[0].rules[0].use[0]"
}
]
}
at checkResourceSource (node_modules\#nuxt\webpack\node_modules\webpack\lib\RuleSet.js:167:11)
at Function.normalizeRule (node_modules\#nuxt\webpack\node_modules\webpack\lib\RuleSet.js:198:4)
at node_modules\#nuxt\webpack\node_modules\webpack\lib\RuleSet.js:110:20
at Array.map (<anonymous>)
at Function.normalizeRules (node_modules\#nuxt\webpack\node_modules\webpack\lib\RuleSet.js:109:17)
at new RuleSet (node_modules\#nuxt\webpack\node_modules\webpack\lib\RuleSet.js:104:24)
at new NormalModuleFactory (node_modules\#nuxt\webpack\node_modules\webpack\lib\NormalModuleFactory.js:115:18)
at Compiler.createNormalModuleFactory (node_modules\#nuxt\webpack\node_modules\webpack\lib\Compiler.js:636:31)
at Compiler.newCompilationParams (node_modules\#nuxt\webpack\node_modules\webpack\lib\Compiler.js:653:30)
at Compiler.compile (node_modules\#nuxt\webpack\node_modules\webpack\lib\Compiler.js:661:23)
at node_modules\#nuxt\webpack\node_modules\webpack\lib\Watching.js:77:18
at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:22:1)
at AsyncSeriesHook.lazyCompileHook (node_modules\tapable\lib\Hook.js:154:20)
at Watching._go (node_modules\#nuxt\webpack\node_modules\webpack\lib\Watching.js:41:32)
at node_modules\#nuxt\webpack\node_modules\webpack\lib\Watching.js:33:9
at Compiler.readRecords (node_modules\#nuxt\webpack\node_modules\webpack\lib\Compiler.js:529:11)
npm i -D webpack#^4.46.0 try this, it worked for me.
I've had the same issue today, it seems to be related to an npm dependencies resolution issue.
I have opened an issue in nuxt.js repository
In my project, the issue was present, cause of #nuxtjs/eslint-module, you can remove it and regen dependencies :
npm uninstall #nuxtjs/eslint-module
rm -rf node_modules package-lock.json
npm install
You will not longer have eslint feedbacks in your build command, but you can still use npm run lint, and you will be able to use nuxt until the issue will be fixed.
I ran into this same error while trying to upgrade one of my old NuxtJS projects (using sass) built on node version 12 to version 16.
To fix this, i also installed #nuxtjs/style-resources that matches my versions of sass-loader and node-sass.
To confirm, uninstall the ones you already have, and run
npm install --save-dev node-sass sass-loader#10 fibers #nuxtjs/style-resources
see this article for more
This happened to me when I installed the most recent version of copy-webpack-plugin in Nuxt v2 project. Apparently it doesn't use webpack5 so I had to downgrade copy-webpack-plugin to last compatible version e.g. copy-webpack-plugin#4.6.0

"Identifier 'global' has already been declared at compileFunction" error In jest tests after upgrading to monaco-editor 0.21.0

I upgraded my react project to use monaco-editor version 0.21.0, since then the jest tests for files where monaco-editor is being imported have started to fail with the following error:
● Test suite failed to run
/Users/omerharoon/Documents/code/packages/webapp/node_modules/monaco-editor/esm/vs/editor/editor.api.js:20
const global = self; // Set defaults for standalone editor
^
SyntaxError: Identifier 'global' has already been declared
at compileFunction (<anonymous>)
2 |
3 | import React from 'react';
> 4 | import * as monaco from 'monaco-editor';
| ^
5 | import { Resizable } from 're-resizable';
6 | import {
7 | getLanguageFromFilename,
at Runtime._execModule (node_modules/jest-runtime/build/index.js:1179:56)
at Object.<anonymous> (src/components/helpers/MonacoEditor/index.tsx:4:1)
at Object.<anonymous> (src/components/helpers/MonacoEditor/monaco_colorization.spec.tsx:6:1)
This started occurring right after the upgrade, the old version was 0.19.3 and all the tests worked fine on that version. monaco-editor-webpack-plugin was also upgraded from 1.9.0 to 2.0.0
We're importing monaco directly from
node_modules/monaco-editor/esm/vs/editor/editor.api
in order to overcome lazy loading issues.
Jest Config:
"jest": {
"modulePaths": [
"<rootDir>/src"
],
"collectCoverageFrom": [
"**/*.{js,jsx,ts,tsx}",
"!**/*.d.ts",
"!**/node_modules/**",
"!**/public/**",
"!**/next.config.js",
"!**/server.js"
],
"setupFilesAfterEnv": [
"<rootDir>/setupTests.js"
],
"testPathIgnorePatterns": [
"<rootDir>/node_modules/",
"<rootDir>/.next/",
"<rootDir>/public/",
"<rootDir>/config/",
"<rootDir>/next.config.js",
"<rootDir>/server.js",
"<rootDir>/build/"
],
"transform": {
"^.+\\.[jt]sx?$": "babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js"
},
"transformIgnorePatterns": [
"/node_modules/(?!monaco-editor)/",
"^.+\\.module\\.(css|sass|scss)$"
],
"moduleNameMapper": {
"^monaco-editor$": "monaco-editor/esm/vs/editor/editor.api",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
},
"coverageReporters": [
"text",
[
"lcov",
{
"projectRoot": "../../"
}
]
]},
Upgrading to monaco-editor 0.23.0resolved the problem for me.

Electron node-Gyp Library not loaded: dylib

I have an electron project bundled with a native node module, static and dynamic libs.
When runs the packaged app on mac, I'm getting below error in the developer console. The native node module(addon.node) loads ok but not the dylibs.
Uncaught Error: Cannot open ./addon.node: Error: dlopen(./addon.node, 1): Library not loaded: Core.dylib
Referenced from: /Users/Camera/Documents/myapp/dist/mac/myapp.app/Contents/Frameworks/addon.node
Reason: image not found
at Object.<anonymous> (main.js:3)
at Object.<anonymous> (main.js:3)
at n (main.js:1)
at Module.<anonymous> (main.js:306)
at n (main.js:1)
at main.js:1
at main.js:1
binding.gyp
"targets": [{
"target_name": "addon",
...
'conditions': [
['OS=="mac"', {
...
'library_dirs': [
"/usr/local/lib",
"'$(CORE_DIR)'/lib"
],
"link_settings": {
"libraries": [
"-L'$(CORE_DIR)'/lib",
],
},
'libraries': [
"-lCore"
],
"copies":[{
'destination': './',
'files': [
"$(CORE_DIR)/lib/Core.dylib"
]
}],
'xcode_settings': {
'GCC_ENABLE_CPP_RTTI': 'YES',
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'CLANG_CXX_LIBRARY': 'libc++',
}
}],
I have these static and dynamic libs in CORE_DIR/lib
Core.a
Core.dylib
Works Ok when
Run the app in the terminal by running the executable file inside the packaged app.
But Core.dylib should present in the same directory of the terminal current directory.
./dist/mac/myapp.app/Contents/MacOS/myapp
But how to get this work with double click run? I have copied the Core.dylib wherever possible inside the packaged app, but nothing worked.
Thanks
I faced the same problem while moving a project from windows to a mac.
Just remove node_modules and reinstall again its worked for me

node-gyp ignores (c++17) cflag

I try to configure & build a node.js C++ addon with this
binding.gyp file:
{
"targets": [
{
"target_name": "addon",
"sources": [ "addon.cpp" ],
"cflags": [
"-std=c++17"
]
}
]
}
But when I run node-gyp configure and node-gype rebuild
I always get messages like
warning: ‘if constexpr’ only available with -std=c++17 or -std=gnu++17
The build also fails, because I really depend on these c++17 features. What am I doing wrong?
cflags cflags_cc was not working for me, but with the setting in VCCLCompilerTool it works (on Windows):
{
'targets': [
{
'target_name': 'test-napi-native',
'sources': [ 'src/test_napi.cc' ],
'include_dirs': ["<!#(node -p \"require('node-addon-api').include\")"],
'dependencies': ["<!(node -p \"require('node-addon-api').gyp\")"],
'cflags': [ '-fno-exceptions' ],
'cflags_cc': [ '-fno-exceptions' ],
'xcode_settings': {
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'CLANG_CXX_LIBRARY': 'libc++',
'MACOSX_DEPLOYMENT_TARGET': '10.7'
},
'msvs_settings': {
'VCCLCompilerTool': { "ExceptionHandling": 1, 'AdditionalOptions': [ '-std:c++17' ] }
}
}
]
}
Using "cflags_cc" (instead of "cflags") works.
This solved the problem.
The default is against your will
node-gyp has default settings.
argv.push('-I', addonGypi)
argv.push('-I', commonGypi)
argv.push('-Dlibrary=shared_library')
argv.push('-Dvisibility=default')
argv.push('-Dnode_root_dir=' + nodeDir)
if (process.platform === 'aix' || process.platform === 'os390' || process.platform === 'os400') {
argv.push('-Dnode_exp_file=' + nodeExpFile)
if (process.platform === 'os390' && zoslibIncDir) {
argv.push('-Dzoslib_include_dir=' + zoslibIncDir)
}
}
argv.push('-Dnode_gyp_dir=' + nodeGypDir)
// Do this to keep Cygwin environments happy, else the unescaped '\' gets eaten up,
// resulting in bad paths, Ex c:parentFolderfolderanotherFolder instead of c:\parentFolder\folder\anotherFolder
if (win) {
nodeLibFile = nodeLibFile.replace(/\\/g, '\\\\')
}
argv.push('-Dnode_lib_file=' + nodeLibFile)
argv.push('-Dmodule_root_dir=' + process.cwd())
argv.push('-Dnode_engine=' +
(gyp.opts.node_engine || process.jsEngine || 'v8'))
You need to override the default settings described in node-gyp/addon.gypi and node/common.gypi’s cflags (C & C++), cflags_cc (C++), ldflags (Linux), msvs_settings (Windows), and xcode_settings (OS X). All of them.
In your case, you only set the cflags. So, other default settings were left not overridden and thus in effect.
Specifically, you’d want to override the default settings about:
the C++ standard to conform,
cflags_cc
msvs_settings.VCCLCompilerTool.AdditionalOptions
xcode_settings.CLANG_CXX_LANGUAGE_STANDARD
floating point arithmetics,
msvs_settings.VCCLCompilerTool.FloatingPointModel
exceptions,
cflags_cc
msvs_settings.VCCLCompilerTool.ExceptionHandling
xcode_settings.GCC_ENABLE_CPP_EXCEPTIONS
xcode_settings.GCC_ENABLE_CPP_RTTI
optimization,
the warning level,
et cetera.
If you don’t, unintented default settings might be applied.
Why it defaults to this
Because the Node.js executable is built with the settings and node-gyp adopted the settings for the default settings for unknown reasons.
From the nodejs/node-gyp issue #26 — “Overriding default flags”:
edhemphill: Does anyone know why -fno-rtti was used as a default? Any particular reason?
TooTallNate: #edhemphill node-gyp uses the same configuration as when node itself it built, so the answer is because node itself doesn’t need rtti.

How do you automatically download external (C++) libraries when using native Node addons?

I'd like to include libpng in my native Node addon. How can I include it, so that when my library is installed, it will automatically download a specified version of libpng? Is it possible to use npm's package.json for this? If this is not possible, what is the accepted way of including an external library's source code in your repository?
I recommend that you create a gyp file to build the dependency library and add a script to your package.json to download it for you.
I often use my own native addon modules to demonstrate the answers I give to these questions. My own native addon module, node-dvbtee, demonstrates this.
You will notice the following inside package.json:
"scripts": {
"preinstall": "npm install mkdirp && scripts/prepare-build.sh && node scripts/configure-build.js",
"install": "node-gyp rebuild -j 8",
"test": "mocha"
},
What matters here is the preinstall section of the scripts section. It calls scripts/prepare-build.sh, which contains the following:
#!/bin/sh
cd "$(dirname "$0")"/..
if [ -e libdvbtee ]; then
echo libdvbtee sources present
else
git clone git://github.com/mkrufky/libdvbtee.git
fi
cd libdvbtee
if [ -e libdvbpsi/bootstrap ]; then
echo libdvbpsi sources present
else
rm -rf libdvbpsi
git clone git://github.com/mkrufky/libdvbpsi.git
cd libdvbpsi
touch .dont_del
cd ..
fi
As you can see, the above script checks to see if the libdvbtee directory is present. If not, it will clone it from github. After that, it checks to see if the full libdvbpsi sources are present. If not, it will clone them from github.
Now, for the gyp files:
My project has the gyp files stored in the deps directory.
libdvbpsi.gyp looks like this:
{
'target_defaults': {
'default_configuration': 'Debug',
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 1, # static debug
},
},
},
'Release': {
'defines': [ 'NDEBUG' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 0, # static release
},
},
}
},
'msvs_settings': {
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
},
},
'include_dirs': [
'../libdvbtee/libdvbpsi/src',
'../libdvbtee/libdvbpsi/src/tables',
'../libdvbtee/libdvbpsi/src/descriptors',
'../libdvbtee/libdvbpsi'
],
'defines': [
'PIC',
'HAVE_CONFIG_H'
],
},
'targets': [
# libdvbpsi
{
'target_name': 'dvbpsi',
'product_prefix': 'lib',
'type': 'static_library',
'sources': [
'../libdvbtee/libdvbpsi/src/dvbpsi.c',
'../libdvbtee/libdvbpsi/src/psi.c',
'../libdvbtee/libdvbpsi/src/demux.c',
'../libdvbtee/libdvbpsi/src/descriptor.c',
'../libdvbtee/libdvbpsi/src/tables/pat.c',
'../libdvbtee/libdvbpsi/src/tables/pmt.c',
'../libdvbtee/libdvbpsi/src/tables/sdt.c',
'../libdvbtee/libdvbpsi/src/tables/eit.c',
# '../libdvbtee/libdvbpsi/src/tables/cat.c',
'../libdvbtee/libdvbpsi/src/tables/nit.c',
'../libdvbtee/libdvbpsi/src/tables/tot.c',
# '../libdvbtee/libdvbpsi/src/tables/sis.c',
# '../libdvbtee/libdvbpsi/src/tables/bat.c',
# '../libdvbtee/libdvbpsi/src/tables/rst.c',
'../libdvbtee/libdvbpsi/src/tables/atsc_vct.c',
'../libdvbtee/libdvbpsi/src/tables/atsc_stt.c',
'../libdvbtee/libdvbpsi/src/tables/atsc_eit.c',
'../libdvbtee/libdvbpsi/src/tables/atsc_ett.c',
'../libdvbtee/libdvbpsi/src/tables/atsc_mgt.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_02.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_03.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_04.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_05.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_06.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_07.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_08.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_09.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_0a.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_0b.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_0c.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_0d.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_0e.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_0f.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_10.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_11.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_12.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_13.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_14.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_1b.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_1c.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_24.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_40.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_41.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_42.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_43.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_44.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_45.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_47.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_48.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_49.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_4a.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_4b.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_4c.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_4d.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_4e.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_4f.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_50.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_52.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_53.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_54.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_55.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_56.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_58.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_59.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_5a.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_62.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_66.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_69.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_73.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_76.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_7c.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_81.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_83.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_86.c',
# '../libdvbtee/libdvbpsi/src/descriptors/dr_8a.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_a0.c',
'../libdvbtee/libdvbpsi/src/descriptors/dr_a1.c',
],
'conditions': [
['OS=="mac"',
{
'xcode_settings': {
'WARNING_CFLAGS': [
'-Wno-deprecated-declarations'
]
}
}
]
],
'cflags!': ['-Wdeprecated-declarations','-Wimplicit-function-declaration'],
'cflags+': ['-Wno-deprecated-declarations','-Wno-implicit-function-declaration','-std=c99'],
},
]
}
Of course, there are a lot of specifics in this gyp file that are specific to libdvbpsi and my use case. As such, you will notice that quite a few of the source files in the library are not actually needed for the version of it that we're going to build for my node.js addon module. The source files that we are not going to build are commented out by preceding that line with a hash # character.
We link this library to the node module we're currently building by including it in the dependency section of the node.js addon modules bindings.gyp. Here is the one used in my addon module:
{
"targets": [
{
"target_name": "dvbtee",
"sources": [
"src/node-dvbtee.cc",
"src/dvbtee-parser.cc"
],
"dependencies": [
'deps/libdvbtee.gyp:dvbtee_parser'
],
"include_dirs": [
"libdvbtee/usr/include",
"libdvbtee/libdvbtee",
"libdvbtee/libdvbtee/decode",
"libdvbtee/libdvbtee/decode/table",
"libdvbtee/libdvbtee/decode/descriptor",
"<!(node -e \"require('nan')\")"
],
'cflags': [ '-DDEBUG_CONSOLE=1' ],
'cflags_cc': [ '-DDEBUG_CONSOLE=1', '-Wno-deprecated-declarations' ],
'cflags!': [ '-fno-exceptions' ],
'cflags_cc!': [ '-fno-exceptions', '-Wdeprecated-declarations' ],
'conditions': [
['OS=="mac"', {
'xcode_settings': {
'WARNING_CFLAGS': [
'-Wno-deprecated-declarations'
],
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
}
}]
]
}
]
}
As you can see, deps/libdvbtee.gyp:dvbtee_parser is listed in the dependencies section, above. deps/libdvbtee.gyp:dvbtee_parser itself contains its own dependencies section:
"dependencies": [
'libdvbpsi.gyp:dvbpsi'
],
So, when npm install is executed, npm will run the preinstall script to fetch the sources, then it will build the custom libdvbpsi library based on libdvbpsi.gyp, then build the custom libdvbtee based on libdvbtee.gyp which depends on that custom libdvbpsi library, and finally it will build and link the node.js addon module that depends on the libdvbtee library build.
In my specific case, the libraries need to be configured before we attempt to build them. This step is required to write the config.h header file that these libraries depend on. I handle that step within the scripts/configure-build.js script which is run after downloading the sources. In most cases, you will want to simply run ./configure for each library, but that depends on the libraries that you're including.
This is a cross-platform solution, provided that the libraries you're building are themselves cross-platform.
You can add it in scrips section in package.json. But you have to be careful about which all devices your application will be executed. Such as ARM, Intel 32 bit or Intel 64 bit, or so. You have options, I am just adding some hints here and you can put your code accordingly. Here script will get executed during npm install command.
1. In script, you have to check the machine type and do download library accordingly.
//package.json
{
"scripts": {
"preinstall": ""
,"install": ""
,"test" : ""
}
}
In script, you have to check the machine type and do download library accordingly, something like using wget abc.so in install section of script. You have to do some scripting to take right lib for machine and put in right place.
In other way if you want, you can add build script, which will do download the source code and build in the system on the fly.
git clone git://xyz/abc.git
cd abc
./configure
make
make install.
You can also look for babel cli for source compilation. https://babeljs.io/docs/usage/cli/
And all these within scripts section, within preinstall or install or test.
In your case, you would prefer to go for 1st way.

Resources