I'm trying to use a the gstreamer framework in my node addon. I had the following to my to my binding.gyp, but when i run the build command it, the console states that the header is not found. When i compile my gstreamer files outside of node-gyp, it compiles successfully. Does anyone see something wrong with my binding file ?
console
hello.cc3:25: fatal error: gstreamermm.h: No such file or directory
binding.gyp
{
"targets": [
{
"target_name": "addon",
"libraries": [
"-lgstreamer-1.0", "-L/usr/inlcude/gstreamer-1.0/gst/"
],
"sources": [ "hello.cc" ]
}
]
}
compile command that works correctly, and that I'm trying to run
g++ main.c -o main `pkg-config --cflags --libs gstreamer-1.0`
Update:
Following @Mike Kinghan binding.gyp
Does anyone see something wrong with my binding file?
Yes:
"libraries": [
"-lgstreamer-1.0", "-L/usr/include/gstreamer-1.0/gst/"
],
The "libraries"
element, in binding.gyp
should include the libraries, specified in -l
or
absolute filename form, that you want to link.
-lgstreamer-1.0
is one of those. -L/usr/inlcude/gstreamer-1.0/gst/
is not. It is a linker option that will instruct the linker to search
for libraries specified in -l
form in the directory /usr/include/gstreamer-1.0/gst/
.
That is specifying a library search directory, so if it were needed, you should say so in
the "library_dirs"
element:
"library_dirs": [
"/usr/inlcude/gstreamer-1.0/gst/",
]
But you don't need it, because there are no libraries in /usr/inlcude/gstreamer-1.0/gst/
.
All the files under /usr/include
are C or C++ header files, not libraries. Libraries
are installed under /lib
, /usr/lib
or /usr/local/lib
.
You say you can successfully compile a program with:
g++ main.c -o main `pkg-config --cflags --libs gstreamer-1.0`
That works because as you may know,
pkg-config --cflags --libs gstreamer-1.0
outputs the compiler and linker options needed to build a target that depends on
gstreamer-1.0
Let's have a look:
$ pkg-config --cflags --libs gstreamer-1.0
-pthread -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include \
-lgstreamer-1.0 -lgobject-2.0 -lglib-2.0
Then let's use that information to write binding.gyp
. (On your system it might differ from mine):
binding.gyp
{
"targets": [
{
"target_name": "addon",
"include_dirs": [
"/usr/include/gstreamer-1.0",
"/usr/include/glib-2.0",
"/usr/lib/x86_64-linux-gnu/glib-2.0/include"
],
"libraries": [
"-lgstreamer-1.0",
"-lgobject-2.0",
"-lglib-2.0"
],
"sources": [ "hello.cc" ]
}
]
}
(Have we forgotten the -pthread
option emitted by pkg-config
? No. node-gyp
passes
it the compiler and linker by default)
With this binding.gyp
, your build should look something like mine:
$ node-gyp configure build
gyp info it worked if it ends with ok
gyp info using node-gyp@3.4.0
gyp info using node@4.7.2 | linux | x64
gyp info spawn /usr/bin/python2
gyp info spawn args [ '/usr/share/node-gyp/gyp/gyp_main.py',
gyp info spawn args 'binding.gyp',
gyp info spawn args '-f',
gyp info spawn args 'make',
gyp info spawn args '-I',
gyp info spawn args '/home/imk/develop/so/scrap/build/config.gypi',
gyp info spawn args '-I',
gyp info spawn args '/usr/share/node-gyp/addon.gypi',
gyp info spawn args '-I',
gyp info spawn args '/usr/include/nodejs/common.gypi',
gyp info spawn args '-Dlibrary=shared_library',
gyp info spawn args '-Dvisibility=default',
gyp info spawn args '-Dnode_root_dir=/usr/include/nodejs',
gyp info spawn args '-Dnode_gyp_dir=/usr/share/node-gyp',
gyp info spawn args '-Dnode_lib_file=node.lib',
gyp info spawn args '-Dmodule_root_dir=/home/imk/develop/so/scrap',
gyp info spawn args '--depth=.',
gyp info spawn args '--no-parallel',
gyp info spawn args '--generator-output',
gyp info spawn args 'build',
gyp info spawn args '-Goutput_dir=.' ]
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
make: Entering directory '/home/imk/develop/so/scrap/build'
CXX(target) Release/obj.target/addon/hello.o
SOLINK_MODULE(target) Release/obj.target/addon.node
COPY Release/addon.node
make: Leaving directory '/home/imk/develop/so/scrap/build'
gyp info ok
Note furthermore, pkg-config
tells you that the correct compiler include-path
to locate gstreamer-1.0 header files is:
/usr/include/gstreamer-1.0
not:
/usr/incude/gstreamer-1.0/gst/
And we have followed that advice in our binding.gyp
. Therefore
in your source code you will write, e.g.
#include <gst/gst.h>
and not:
#include <gst.h>
Later
Now your compiler cannot locate <gst/gstconfig.h>
One possible cause is that you didn't faithfully copy
the necessary include-directories reported for your system by:
pkg-config --cflags gstreamer-1.0
into the include_dirs
list of your binding-gyp
. Possibly you
just copied the ones from my example. My example, giving directories:
-I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include
was run on Ubuntu 17.04, in which gst/gstconfig.h
is in fact
installed in /usr/include/gstreamer-1.0
. But on Ubuntu 16.04,
for example:-
$ pkg-config --cflags gstreamer-1.0
-pthread -I/usr/include/gstreamer-1.0 \
-I/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include -I/usr/include/glib-2.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include
we get the additional include directory:
/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include
and gst/gstconfig.h
is indeed installed there. Check that you are using
the correct include directories that pkg-config
reports on your system and
correct your binding.gyp
if necessary.
If you were using the correct pkg-config
results, then it would appear that your
gstreamer-1.0
dev package has a defective gstreamer-1.0.pc
file providing incorrect
pkg-config
info. To work around that, ask your distro's package manager to show you
where the dev package really installed gst/gstconfig.h
. E.g. for Ubuntu 16.04:
$ dpkg -L libgstreamer1.0-dev | grep gst/gstconfig
/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include/gst/gstconfig.h
Then add the required path prefix (e.g. /usr/lib/x86_64-linux-gnu/gstreamer-1.0/include
)
to the include_dirs
of your binding.gyp
.