Need to create node native module using an electron app - node.js

I am creating a simple electron app with native modules included. I have included some static libraries sourced from c++ application. Here is my binding.gyp file and the hello.cc file created as mentioned in the https://nodejs.org/dist/latest/docs/api/addons.html
Here is my binding.gyp file
binding.gyp:
"targets": [
{
"target_name": "myext",
"libraries": [
"/Users/rsivaram/logitech/obs-studio/deps/w32-pthreads/libpthreadGC2.a",
"/Users/rsivaram/logitech/obs-studio/build/plugins/obs-x264/libobs-x264-util.a",
"/Users/rsivaram/logitech/obs-studio/build/plugins/mac-syphon/libsyphon-framework.a",
"/Users/rsivaram/logitech/obs-studio/build/deps/file-updater/libfile-updater.a",
"/Users/rsivaram/logitech/obs-studio/build/deps/libcaption/libcaption.a",
"/Users/rsivaram/logitech/obs-studio/build/deps/media-playback/libmedia-playback.a",
],
"cflags!": [ "-fno-exceptions" ],
"cflags": [ "-std=c++11" ],
"cflags_cc!": [ "-fno-exceptions" ]
}
]
}
Here is my hello.cc file
hello.cc:
#include <node.h>
namespace demo {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
args.GetReturnValue().Set(String::NewFromUtf8(
isolate, "world").ToLocalChecked());
}
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace demo
"npm install" works fine, however I m not able to run the application using "npm start".
Errors I m getting
1."identifier "v8" is undefined" in the hello.cc file.
2. "Module did not self-register <abs path of the app>/electron-quick-start/build/Release/myext.node "
How do I create the hello.cc file. Please let me know. Thanks

Related

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

ubuntu18.04 vscode kernel module program ERROR: identifier "KBUILD_MODNAME" is undefine

My environment: Ubuntu 18.04, kernel: linux-5.3.0-53 vscode: lastest
Command for fixing linux/module.h not find asm/xxx.h
cd /usr/src/linux-headers-5.3.0-53/include
sudo ln -s asm-generic/ asm
My c_cpp_properties.json
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/include",
"/usr/local/include",
"/usr/src/linux-headers-5.3.0-53/include",
"/usr/src/linux-headers-5.3.0-53-generic/include",
"/usr/src/linux-headers-5.3.0-53/arch/x86/include",
"/usr/src/linux-headers-5.3.0-53/include/uapi",
"/usr/lib/gcc/x86_64-linux-gnu/7.5.0/include"
],
"defines": [
"__GNUC__",
"__KERNEL__"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
My hello_module.c, a simple Linux kernel module program.
//a simple linux kernel module program.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL"); //error here
static int hello_init(void){
printk(KERN_ALERT "hello world\n");
return 0;
}
static void hello_exit(void){
printk(KERN_ALERT "goodbye world\n");
}
module_init(hello_init);
module_exit(hello_exit);
then ERROR:
identifier "KBUILD_MODNAME" is undefined
How to fix? Please help me..
KBUILD_MODNAME is automatically defined by the Makefile when you build your kernel module, so you will not find it anywhere in the kernel header files.
To stop vscode from complaining about undefined KBUILD_MODNAME identifier, just add a dummy definition to your c_cpp_properties.json file in the "defines" section
"defines": [
"KBUILD_MODNAME=\"hello_module\"",
"__GNUC__",
"__KERNEL__"
],
That should make vscode happy =)
The value you define for KBUILD_MODNAME does not really matter, since it is automatically defined during the make process.
I have not understood if this is your only problem, or if you also have problems to compile the module. If yes let me know and we will figure out how to solve that too!

cannot open source file "node.h" in hello.cc

Node Version:v12.1.0
Platform:Mac osx
node-gyp:v5.0.3
I don't know if it's a problem or just a personal question 。as a nodejs addons beginner,I write a
hello.cc file,which as below:
#include <node.h>
#include <v8.h>
using namespace v8;
// 实现􏵹定义的方法
Handle<Value> SayHello(const Arguments &args)
{
HandleScope scope;
return scope.Close(String::New("Hello world!"));
}
// 给传入的目􏵺对象􏱭加sayHello()方法 void Init_Hello(Handle<Object>target) {
target->Set(String::NewSymbol("sayHello"),FunctionTemplate::New(SayHello)->GetFunction());
// 调用NODE_MODULE()方法将注􏵻方法定义􏵼内存中 NODE_MODULE(hello, Init_Hello)
and my binding.gyp is like this:
{
'targets': [
{
'target_name': 'hello', 'sources': [
'src/hello.cc'],
'conditions': [['OS == "mac"',
{
}
]],
"include_dirs": [
"<!(node -e \"require('nan')\")"
]
}]
}
but the source code show Squiggles
and when I run node-gyp configure build
error shows:
all right version problem.
use nan.h fixed
https://github.com/nodejs/nan

javascript equivalent for python ctypes with node-gyp

I want to transform a python script into a javascript script. My python script loads a dll and use its API.
processings2D = ctypes.CDLL('processings2D.dll')
print(processings2D.ImageProcessor2DCreate())
I try do to the same with node-gyp but my script doesn't find the dll.
console.log(processings2D.ImageProcessor2DCreate());
^
TypeError: Cannot load processings2D.dll library
test.js
var processings2D = require('./build/Release/processings2D.node');
console.log(processings2D.ImageProcessor2DCreate());
addon.cc
#include <nan.h>
#include "processings2D/processings2D.h"
HINSTANCE hDLL = NULL;
typedef int(*Fn)();
void ImageProcessor2DCreate(const Nan::FunctionCallbackInfo<v8::Value>& info) {
hDLL = LoadLibrary("processings2D.dll");
if(!hDLL)
{
Nan::ThrowTypeError("Cannot load processings2D.dll library");
return;
}
Fn fn = (Fn)GetProcAddress(hDLL, "ImageProcessor2DCreate");
if (!fn) {
Nan::ThrowTypeError("Could not load ImageProcessor2DCreate function");
FreeLibrary(hDLL);
return;
}
info.GetReturnValue().Set(Nan::New(fn()));
}
void Init(v8::Local<v8::Object> exports) {
exports->Set(Nan::New("ImageProcessor2DCreate").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ImageProcessor2DCreate)->GetFunction());
}
NODE_MODULE(twoD, Init)
binding.gyp
{
"targets": [
{
"target_name": "processings2D",
"sources": [
"addon.cc"
],
"include_dirs": [
"<!(node -e \"require('nan')\")"
]
}
]
}
dll is in the Release folder /build/Release/processings2D.dll
Am I in the right direction ?
The solution was really simple :
My dll was a 32 bit version, so I should build my module with the 32 bit arch flag and execute my test with the 32 bit version of node.
node-gyp clean configure --arch=ia32 build
"C:\Program Files (x86)\nodejs\node.exe" test.js

Unable to use helper classes within unit tests of a bundled aurelia app. RequireJS Configuration?

Summary
Using the aurelia cli and the default tasks that are included, I am unable to leverage helper classes that are located within the test folder in my unit tests.
Details
Starting with the sample app created with au new, I have a contrived helper class located within 'test/util/helper.ts':
export class Helper {
Property : string;
}
This class is imported by the test/unit/app.spec.ts file:
import {App} from '../../src/app';
import {Helper} from "../util/helper";
describe('the app', () => {
it('says hello', () => {
let h = new Helper();
h.Property = "Testing";
expect(h.Property).toBe("Testing");
expect(new App().message).toBe('Hello World!');
});
});
Approach #1 - Bundling
I have modified the aurelia.json file in a few places:
Change the source of the typescript compiler to include files under the test folder
"transpiler": {
"id": "typescript",
"displayName": "TypeScript",
"fileExtension": ".ts",
"dtsSource": [
"./typings/**/*.d.ts",
"./custom_typings/**/*.d.ts"
],
"source": ["src\\**\\*.ts","test\\**\\*.ts"]
},
Modify the app-bundle to exclude any file from the test folder
{
"name": "app-bundle.js",
"source": {
"include": [
"[**/*.js]",
"**/*.{css,html}"
],
"exclude": [
"**/test/**/*"
]
}
},
Add a new bundle (test-util-bundle), which includes files from the test\util folder and excludes files within the src and test/unit folders
{
"name": "test-util-bundle.js",
"source": {
"include": [
"[**/*.js]"
],
"exclude": [
"**/src/**/*",
"**/test/unit/**/*"
]
}
},
After bundling the app with 'au build', I have three bundles (app/vendor/test-util), with the test-util-bundle.js bundle defining the helper class like this:
define('../test/util/helper',["require", "exports"], function (require, exports) {
"use strict";
var Helper = (function () {
function Helper() {
}
return Helper;
}());
exports.Helper = Helper;
});
I suspect this is the root of the problem, but not that familiar with RequireJS.
When I do run 'au test' the test fails with the following error:
11 10 2016 12:05:24.606:DEBUG [middleware:source-files]: Fetching C:/git/aurelia-cli-testing/test/test/util/helper
11 10 2016 12:05:24.608:WARN [web-server]: 404: /base/test/test/util/helper
Chrome 53.0.2785 (Windows 7 0.0.0) ERROR
Uncaught Error: Script error for "C:/git/aurelia-cli-testing/test/test/util/helper", needed by: C:/git/aurelia-cli-testing/test/util/helper
http://requirejs.org/docs/errors.html#scripterror
at C:/git/aurelia-cli-testing/scripts/vendor-bundle.js:3763
Note:
This works fine if I move the helper.ts file under the src tree (as done here). This is all available here if you would like to see the behavior.
Approach #2 - Without Bundling of utility class
Modify karma.conf.js
let testSrc = [
{ pattern: project.unitTestRunner.source, included: false },
{ pattern: "test/util/**/*.ts", included: false },
'test/aurelia-karma.js'
];
...
preprocessors: {
[project.unitTestRunner.source]: [project.transpiler.id],
["test/util/**/*.ts"]: [project.transpiler.id]
},
With this modification (no bundling of the utility class) karma produces the following error:
18 10 2016 16:56:59.151:DEBUG [middleware:source-files]: Fetching C:/git/aurelia-cli-testing/test/util/helper
18 10 2016 16:56:59.152:WARN [web-server]: 404: /base/test/util/helper
Chrome 53.0.2785 (Windows 7 0.0.0) ERROR
Uncaught Error: Script error for "C:/git/aurelia-cli-testing/test/util/helper", needed by: C:/git/aurelia-cli-testing/test/unit/app.spec.js
http://requirejs.org/docs/errors.html#scripterror
at C:/git/aurelia-cli-testing/scripts/vendor-bundle.js:3763
Thanks for reading, any help would be greatly appreciated!
With the help of an Aurelia team member, a small modification to the aurelia-karma.js file that is distributed with the aurelia cli fixes the issue:
The normalizePath function should be modified to append '.js' where applicable:
function normalizePath(path) {
var normalized = []
var parts = path
.split('?')[0] // cut off GET params, used by noext requirejs plugin
.split('/')
for (var i = 0; i < parts.length; i++) {
if (parts[i] === '.') {
continue
}
if (parts[i] === '..' && normalized.length && normalized[normalized.length - 1] !== '..') {
normalized.pop()
continue
}
normalized.push(parts[i])
}
//Use case of testing source code. RequireJS doesn't add .js extension to files asked via sibling selector
//If normalized path doesn't include some type of extension, add the .js to it
if(normalized.length > 0 && normalized[normalized.length-1].indexOf('.') < 0){
normalized[normalized.length-1] = normalized[normalized.length-1] + '.js';
}
return normalized.join('/')
}
I had to do the following:
1. update the aurelia-project/aurelia.json file. add this
"unitTestRunnerUtils": {
"id": "karmaUtils",
"displayName": "Karma",
"source": "test\\utils\\**\\*.js" },
Then in the karma.conf.js file updated these two places.
let testSrc = [ { pattern: project.unitTestRunner.source, included:
false }, { pattern: project.unitTestRunnerUtils.source, included:
false}, 'test/aurelia-karma.js' ];
and
preprocessors: {
[project.unitTestRunner.source]: [project.transpiler.id],
[project.unitTestRunnerUtils.source]: [project.transpiler.id]
},
And then it worked...
Here is the example project on github.
https://github.com/duranmg/demo-aurelia-testing

Resources