node-gyp - не находит заголовки библиотек

Я пытаюсь использовать структуру gstreamer в своем аддоне узла. У меня было следующее для моего Binding.gyp, но когда я запускаю команду сборки, консоль сообщает, что заголовок не найден. Когда я компилирую свои файлы gstreamer вне node-gyp, они успешно компилируются. Кто-нибудь видит что-то не так с моим файлом привязки?

консоль

hello.cc3:25: fatal error: gstreamermm.h: No such file or directory 

привязка.gyp

{
  "targets": [
    {
      "target_name": "addon",
          "libraries": [
            "-lgstreamer-1.0", "-L/usr/inlcude/gstreamer-1.0/gst/"
          ],
      "sources": [ "hello.cc" ]
    }
  ]
}

скомпилировать команду, которая работает правильно, и которую я пытаюсь запустить

g++ main.c -o main `pkg-config --cflags --libs gstreamer-1.0`

Обновление: после @Mike Kinghan binding.gyp введите здесь описание изображения


person AJ_    schedule 03.09.2017    source источник
comment
-L предназначен для установки пути к библиотеке, для установки местоположения вы должны использовать -I, поэтому он должен выглядеть как -I /usr/inlcude/gstreamer-1.0/gst   -  person user7860670    schedule 03.09.2017
comment
@VTT, я изменил на I, а ошибка осталась   -  person AJ_    schedule 04.09.2017
comment
Не следует включать каталоги, входящие в раздел include_dirs файлов gyp и каталоги библиотек. перейти в раздел library_dirs?   -  person user7860670    schedule 04.09.2017
comment
@VTT, извини, я не понимаю. Что вы подразумеваете под library_dirs?   -  person AJ_    schedule 04.09.2017
comment
@VTT у тебя есть пример?   -  person AJ_    schedule 04.09.2017


Ответы (1)


Кто-нибудь видит что-то не так с моим файлом привязки?

Да:

"libraries": [
            "-lgstreamer-1.0", "-L/usr/include/gstreamer-1.0/gst/"
          ],

Элемент "libraries" в binding.gyp должен включать библиотеки, указанные в -l или в форме абсолютного имени файла, которые вы хотите связать.

-lgstreamer-1.0 является одним из них. -L/usr/inlcude/gstreamer-1.0/gst/ нет. Это параметр компоновщика, который указывает компоновщику искать библиотеки, указанные в форме -l, в каталоге /usr/include/gstreamer-1.0/gst/.

Это указывает каталог поиска библиотеки, поэтому, если это необходимо, вы должны указать это в элементе "library_dirs":

"library_dirs": [
  "/usr/inlcude/gstreamer-1.0/gst/",
]

Но вам это не нужно, потому что в /usr/inlcude/gstreamer-1.0/gst/ нет библиотек. Все файлы под /usr/include являются заголовочными файлами C или C++, а не библиотеками. Библиотеки устанавливаются под /lib, /usr/lib или /usr/local/lib.

Вы говорите, что можете успешно скомпилировать программу с помощью:

g++ main.c -o main `pkg-config --cflags --libs gstreamer-1.0`

Это работает, потому что, как вы знаете,

pkg-config --cflags --libs gstreamer-1.0

выводит параметры компилятора и компоновщика, необходимые для создания цели, которая зависит от gstreamer-1.0

Давайте посмотрим:

$ 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

Затем воспользуемся этой информацией, чтобы написать binding.gyp. (В вашей системе это может отличаться от моего):

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" ]
    }
  ]
}

(Разве мы не забыли параметр -pthread, выдаваемый pkg-config? Нет. node-gyp передает его компилятору и компоновщику по умолчанию)

С этим binding.gyp ваша сборка должна выглядеть как моя:

$ node-gyp configure build
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | 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 

Кроме того, обратите внимание, что pkg-config сообщает вам, что правильный путь включения компилятора для поиска файлов заголовков gstreamer-1.0:

/usr/include/gstreamer-1.0

нет:

/usr/incude/gstreamer-1.0/gst/

И мы последовали этому совету в нашем binding.gyp. Поэтому в исходном коде вы будете писать, например.

#include <gst/gst.h>

и нет:

#include <gst.h>

Позже

Теперь ваш компилятор не может найти <gst/gstconfig.h>

Одна из возможных причин заключается в том, что вы неправильно скопировали необходимые включаемые каталоги, указанные для вашей системы:

pkg-config --cflags gstreamer-1.0

в список include_dirs вашего binding-gyp. Возможно, вы просто скопировали те, что из моего примера. Мой пример, дающий каталоги:

-I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include

был запущен в Ubuntu 17.04, в котором gst/gstconfig.h фактически установлен в /usr/include/gstreamer-1.0. Но в Ubuntu 16.04, например:

$ 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

мы получаем дополнительный каталог include:

/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include

и gst/gstconfig.h там действительно установлен. Убедитесь, что вы используете правильные включаемые каталоги, которые pkg-config сообщают о вашей системе, и при необходимости исправьте ваш binding.gyp.

Если вы использовали правильные результаты pkg-config, то оказалось бы, что ваш пакет gstreamer-1.0 dev содержит дефектный файл gstreamer-1.0.pc, предоставляющий неверную pkg-config информацию. Чтобы обойти это, попросите менеджера пакетов вашего дистрибутива показать вам, где действительно установлен пакет dev gst/gstconfig.h. Например. для Ubuntu 16.04:

$ dpkg -L libgstreamer1.0-dev | grep gst/gstconfig
/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include/gst/gstconfig.h

Затем добавьте требуемый префикс пути (например, /usr/lib/x86_64-linux-gnu/gstreamer-1.0/include) к include_dirs вашего binding.gyp.

person Mike Kinghan    schedule 06.09.2017
comment
Я все еще получаю некоторые ошибки сборки. Расположение моей библиотеки такое же, как и у вас. см. обновленный вопрос. Какие-либо предложения ? - person AJ_; 07.09.2017
comment
@AJ_: Вы можете скопировать проект на Github? Я пытаюсь начать с этого и ищу хорошую отправную точку. - person user2801184; 26.08.2020