How to include two C++ libraries - Boost and Quantlib - in node gyp? - javascript

I am new to working with node-gyp in making C++ Addons for JavaScript on Windows and have been struggling for a while with including Quantlib in my binding.gyp file. I was able to generate the .lib file from Quantlib's official site (https://www.quantlib.org/install/vc10.shtml); however, the guide did not mention anything about generating a .dll file, and I am not sure if a .dll file is needed to include Quantlib. Although I cannot include the Quantlib library, I have been successful in linking another C++ library in my binding.gyp file. Any help would be much appreciated!
My binding.gyp file:
{
"targets": [
{
"target_name": "hello",
"sources": [ "src/hello.cc", "src/test.cpp", "src/test.h"],
"include_dirs": ["<!(node -e \"require('nan')\")", "eigen-3.3.7/eigen-3.3.7", "ql/math", "ql", "Quantlib"],
"libraries": ["<(module_root_dir)/Quantlib/QuantLib-mt.lib"]
}
]
}
NOTE: eigen-3.3.7 is the C++ library I was able to include in my binding.gyp file. I created a directory in my root folder for quantlib's .lib file called "Quantlib".

Related

Chicken-and-egg problem with node-gyp: Pointing to a header file in a dependency

This is my first attempt at building an npm package that includes C++ code. I thought that I had everything set up properly because, while working in the project folder for the package itself, npm i or node-gyp rebuild was working just fine.
But now that I've published the package, and I'm trying to use that package as a dependency in another project, installation is failing during compilation, when trying to include an important C header file:
CXX(target) Release/obj.target/ar_signal_monitor/ar-signal-monitor-node.o
../ar-signal-monitor-node.cpp:1:10: fatal error: 'napi.h' file not found
#include <napi.h>
^~~~~~~~
1 error generated.
The header file is inside one of the package's dependencies, node-addon-api. My binding.gyp file looks like this:
{
"targets": [
{
"target_name": "ar_signal_monitor",
"cflags!": ["-fno-exceptions"],
"cflags_cc!": ["-fno-exceptions"],
"cflags": ["-Wall", "-std=c++11", "-pthread"],
"cflags_cc": ["-Wall", "-pthread"],
"sources": [
"ar-signal-monitor-node.cpp",
"ar-signal-monitor-node.h",
"ar-signal-monitor.cpp",
"ar-signal-monitor.h"
],
"include_dirs": [
"<!(node -e \"require('node-addon-api').include\")",
"node_modules/node-addon-api",
"/usr/include/node",
"/usr/local/include/node"
],
"libraries": [
"-lwiringPi"
],
"defines": ["NAPI_CPP_EXCEPTIONS"],
'conditions': [
["OS==\"mac\"", {
"defines": ["USE_FAKE_WIRING_PI"],
"libraries!": ["-lwiringPi"],
"xcode_settings": {"GCC_ENABLE_CPP_EXCEPTIONS": "YES"}
}],
["OS==\"win\"", {
"defines": ["USE_FAKE_WIRING_PI"],
"libraries!": ["-lwiringPi"]
}],
],
}
]
}
I'm trying to use "include_dirs" to tell the compiler where to find the <napi.h> header file. I think that perhaps the problem I have is that the installation process wants to compile my C++ code first, and only after that's successfully done then load the dependent npm packages where the header file I need for successful compilation lives.
Is there a way around this problem? Is it a different problem than I think it is? I tried first including node-addon-api in the client project, but that didn't help. (And even if it had worked, that wouldn't be any better than a temporary word-around.)
Full code for the project can be found here: https://github.com/kshetline/rpi-acu-rite-temperature
I'd been thinking I'd needed to do something different in my binding.gyp file, but the solution (or, at least, a solution) turned out to be something I could do in my package.json:
"scripts": {
"preinstall": "npm i node-addon-api",

How to create an express api executable

I have created a fully functioning fairly basic javaScript Node.js Express API application that I want to run as an executable in a windows environment. I am wanting to do this so I can give clients the ability to run my API on premise without exposing my source code to them.
Currently I have been using the pkg npm package which allows me to package my node.js application into an executable that will contain everything needed to run the app including node and my bundled source code.
My executable runs but my POST route is breaking with the following error:
"name": "RequestError",
"message": "Error: form-data: File or directory 'C:\\**\\myapp-api\\uploads\\1553103249524_test.wav' was not included into executable at compilation stage. Please recompile adding it as asset or script.",
"cause": {
"errno": -4058,
"code": "ENOENT",
"path": "C:\\snapshot\\myapp-api\\uploads\\test.wav",
"pkg": true
},
"error": {
"errno": -4058,
"code": "ENOENT",
"path": "C:\\snapshot\\myapp-api\\uploads\\1553103249524_test.wav",
"pkg": true
},
My POST allows clients to upload a file in a multipart form using multer.js to another external API that will return some metadata. pkg.js doesn't appear to have the means to discover files that are included after the bundling of the executable.
Is there anything I can do in my configuration for my uploaded files to be included? Is there some other utility or process that others use for creating an executable of their node.js express APIs that would better handle the issue I am having?
Any guidance would really be great.
Try adding your files under "assets" in the package.json file.
The config paragraph on the pkg website https://www.npmjs.com/package/pkg#config states:
So you must specify the files - scripts and assets - manually in pkg property of your package.json file.
"pkg": {
"scripts": "build/**/*.js",
"assets": "views/**/*"
}
You may also specify arrays of globs:
"assets": [ "assets/**/*", "images/**/*" ]
Just be sure to call pkg package.json or pkg . to make use of scripts and assets entries.
You are probably using something like this in your script (I am guessing since you didnt provide this part of the code)
app.use(express.static(__dirname+'/uploads'));
res.sendFile(path.join(__dirname+'/uploads'));
__dirname will be wrong when you pack your .exe get rid of it everywhere and replace it with ./
app.use(express.static('./uploads'));
res.sendFile(path.join('./uploads'));
Something like that. It worked for me.
Good luck!

tern.js not loading three.js plugin

Problem
I'm currently trying to build a 3D web app based on three.js.
I'm using neovim as my development environment and YouCompleteMe as a completion system.
I installed tern to complete JS, and I added .tern-project file like this.
{
"libs": [
"browser",
"ecmascript",
],
"loadEagerly": [
],
"plugins": {
"threejs": {}
}
}
I also copied threejs.js and threejs.json to my project's directory generated by tern-threejs.
However, YouCompleteMe doesn't show semantic completion compared to tern-threejs's demo codemirror
Comparison:
codemirror:
neovim:
Note: I can't see any completion at all.
What seems to be the problem?
threejs.js is a tern plugin file and threejs.json is a tern library file. plugin files should be copied in tern/plugin directory and library files needs to be placed within tern/defs directory. These two directory exists within tern directory.
With 'YouCompleteMe' installed this dir path is: ~/.vim/YouCompleteMe/third_party/ycmd/third_party/tern-runtime/node‌​_modules/tern. You only need to copy one of aforementioned files. Plugin file or lib file; and update your .tern-project file accordingly. so:
First ensure that you have enabled the Tern completer on YouCompleteMe. For example on my Mac, I had to run the following:
cd ~/.vim/bundle/YouCompleteMe
./install.py --tern-completer
See YouCompleteMe installation guide for details on how to do it on other environments.
Copy threejs.js then navigate to
~/.vim/YouCompleteMe/third_party/ycmd/third_party/tern-runtime/node‌​_modules/tern/plugin/
and paste.
Update your project's .tern-project file as follows:
{
"libs": [
"browser",
"ecmascript",
],
"plugins": {
"es_modules": {},
"threejs": {}
}
}
Note that i've also included es_modules plugin (which is a plugin shipped with tern itself) as you are using ES6 module pattern system.

How to deploy client side dependencies on webserver?

I have done some web developing using Python and Django. I use virtualenv to make a bootstrap script that can install all my Python dependencies on a server. I have a repository for the code I have written myself, and in that repository are two file (beside my code): requirements.txt and bootstrap.py. Using the bootstrap script, it installs all the dependencies on the server.
Now I would like something similar for the client side dependencies. E.g. jQuery, jQuery-ui and bootstrap. Currently I manually download the files and put them in the static folder on the server.
I have run into Bower, and I understand that it can indeed download various js-libraries. But I don't see how to use it in an elegant way. E.g. for jQuery it downloads the entire jQuery repository, which means both a dist folder and a src folder, containing tons of files. All I need is the jQuery.min.js.
Well, wide question, what is the neat way of automating the deployment of client side dependencies?
you can use composer
{
"require": {
"jquery/jquery": "*"
},
"repositories": [
{
"type": "package",
"package": {
"name": "jquery/jquery",
"version": "1.8.2",
"dist": {
"url": "http://code.jquery.com/jquery-1.8.2.min.js",
"type": "file"
}
}
}
]
}

Instruct Sencha SDK tools to bundle other js files specified in app.json

My app.json file of a Sencha touch 2 application contain.
"js": [
{
"path": "sdk/sencha-touch.js"
},
{"path": "js/mootools-1.2.5-core.js"}, // I want these files to be bundled too
{"path": "js/mootools-1.2.5.1-more.js"}, // <----------+
{"path": "js/soundmanager2-nodebug-jsmin.js"}, // <----+
... // <----+ and there are more.
...
{
"path": "app.js",
"bundle": true, /* Indicates that all class dependencies are concatenated into this file when build */
"update": "delta"
},
Now I see when I invoke sencha app build production It compiles all the sencha classes into a giant app.js file. But all my other classes are just compressed to build directory. They are not concatenated. how can I include them in app.js?
F.A.Q.
Your json file is properly written, right?
A. Yes, app.json is written without any syntax error. The project builds successfully on invoking sencha app build production
After looking at the source code and talking with the devs behind Cmd, it appears that it is currently not possible.
However, because the build file is written in JavaScript, in theory, it wouldn't take much to modify it and add this functionality into Cmd.
You can find the Sencha Touch build file in:
CMD-ROOT/plugins/touch/current/app-build.js
Where CMD-ROOT is the location of the sencha command - which you can find out by using which sencha.
On my system (OSX), the path is:
/Users/Robert/bin/Sencha/Cmd/3.0.0.250/plugins/touch/current/app-build.js
Hopefully this is of some help to you.
Update
It appears that, after talking to another Cmd developer, this actually is possible. There are 2 steps you need to take to make it happen:
1) Add the skipFrameworkFile property into each JS resource you want to bundle. This tells the compiler to not copy the resource when your build your app.
{
"path": "resources/js/jquery.js",
"skipFrameworkFile": true
},
"path": "resources/js/jquery2.js",
"skipFrameworkFile": true
}
2) Require each of the files in your app.js file using the #require tag. This tells the compiler to include each of your files into your app.js file.
//#require resources/js/jquery.js
//#require resources/js/jquery2.js
For SenchaCmd 3.2, rdougan's solution didn't work for me. However, instead of using:
'skipFrameworkFile: true
I used
'x-bootstrap': true
(by looking at SenchaCmd source code) and it worked!
The other steps are the same as rdougan's
Hope this helps. Cheers

Categories

Resources