Je voudrais inclure libpng dans mon addon Node natif. Comment puis-je l'inclure, de sorte que lorsque ma bibliothèque est installée, il téléchargera automatiquement une version spécifiée de libpng? Est-il possible d'utiliser package.json de npm pour cela? Si cela n'est pas possible, quelle est la manière acceptée d'inclure le code source d'une bibliothèque externe dans votre référentiel?Comment télécharger automatiquement des bibliothèques externes (C++) lors de l'utilisation d'extensions de nœud natif?
Répondre
Vous pouvez l'ajouter dans la section scripts de package.json. Mais vous devez faire attention à tous les appareils sur lesquels votre application sera exécutée. Tels que ARM, Intel 32 bits ou Intel 64 bits, ou plus. Vous avez des options, je ne fais qu'ajouter quelques astuces ici et vous pouvez mettre votre code en conséquence. Ici le script sera exécuté pendant la commande npm install
. 1. Dans le script, vous devez vérifier le type de machine et télécharger la bibliothèque en conséquence.
//package.json
{
"scripts": {
"preinstall": ""
,"install": ""
,"test" : ""
}
}
dans le script, vous devez vérifier le type de machine et ne télécharger bibliothèque en conséquence, quelque chose comme l'utilisation
wget abc.so
dans l'installation de la section script. Vous devez faire un script pour prendre la bonne lib pour la machine et mettre au bon endroit. Sinon, si vous le souhaitez, vous pouvez ajouter un script de build, qui téléchargera le code source et le construira dans le système à la volée.
git clone git://xyz/abc.git cd abc ./configure make make install
.Vous pouvez également rechercher babel cli pour la compilation de sources. https://babeljs.io/docs/usage/cli/
Et tout cela dans la section des scripts, dans préinstallé ou installer ou tester. Dans votre cas, vous préféreriez opter pour la 1ère voie.
Pour une solution multi-plateforme, je vous recommande de créer un fichier gyp
pour créer la bibliothèque de dépendances et d'ajouter un script à votre package.json
pour le télécharger pour vous.
J'utilise souvent mes propres modules d'extension natifs pour illustrer les réponses que je donne à ces questions. Mon propre module addon natif, node-dvbtee, le démontre.
Vous remarquerez les éléments suivants à l'intérieur package.json
:
"scripts": {
"preinstall": "npm install mkdirp && scripts/prepare-build.sh && node scripts/configure-build.js",
"install": "node-gyp rebuild -j 8",
"test": "mocha"
},
Ce qui importe ici est la section preinstall
de la section scripts
. Il appelle scripts/prepare-build.sh
, qui contient les éléments suivants:
#!/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
Comme vous pouvez le voir, le script ci-dessus vérifie pour voir si le répertoire libdvbtee
est présent. Sinon, il va cloner le github. Après cela, il vérifie si les sources complètes libdvbpsi
sont présentes. Sinon, il va les cloner de github.
Maintenant, pour les gyp
fichiers:
Mon projet a les fichiers gyp
stockés dans le répertoire deps
.
libdvbpsi.gyp
ressemble à ceci:
{
'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'],
},
]
}
Bien sûr, il y a beaucoup de détails dans ce fichier gyp
qui sont spécifiques à libdvbpsi
et mon cas d'utilisation. En tant que tel, vous remarquerez que plusieurs des fichiers source de la bibliothèque ne sont pas réellement nécessaires pour la version que nous allons construire pour mon module addon node.js. Les fichiers source que nous n'allons pas construire sont commentés en précédant cette ligne avec un caractère de hachage #
.
Nous lions cette bibliothèque au module de noeud que nous sommes en train de construire en l'incluant dans la section dépendance des modules addon node.js bindings.gyp
. Voici celui utilisé dans mon module addon:
{
"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'
}
}]
]
}
]
}
Comme vous pouvez le voir, est listé dans deps/libdvbtee.gyp:dvbtee_parser
la section dependencies
ci-dessus. deps/libdvbtee.gyp:dvbtee_parser
contient lui-même sa propre dependencies
section:
"dependencies": [
'libdvbpsi.gyp:dvbpsi'
],
Ainsi, lorsque npm install
est exécuté, npm
va exécuter le script preinstall
pour aller chercher les sources, il construira la bibliothèque personnalisée libdvbpsi
basée sur libdvbpsi.gyp
, puis construire la coutume libdvbtee
basé sur libdvbtee.gyp
qui dépend de cette bibliothèque personnalisée libdvbpsi
, et enfin il va construire et lier le module addon node.js qui dépend de la construction de la bibliothèque libdvbtee
.
Dans mon cas spécifique, les bibliothèques doivent être configurées avant d'essayer de les construire. Cette étape est requise pour écrire le fichier d'en-tête config.h
dont dépendent ces bibliothèques. Je gère cette étape dans le script scripts/configure-build.js
qui est exécuté après le téléchargement des sources. Dans la plupart des cas, vous souhaiterez simplement exécuter ./configure
pour chaque bibliothèque, mais cela dépend des bibliothèques que vous incluez.
Il s'agit d'une solution multiplate-forme, à condition que les bibliothèques que vous construisez soient elles-mêmes multiplateformes.
Application de noeud "native"? – Wainage
@Wainage un add-on natif pour Node, en particulier celui utilisant Nan –