2016-06-20 3 views
2

Я использую node-gyp для создания собственного дополнения Node.js, написанного на C++ в Linux.Вызов make from node-gyp

Это дополнение зависит от другой общей библиотеки. Эта библиотека в настоящее время не построена с помощью gyp, у нее просто есть make-файл.

Если я сначала создаю общую библиотеку, тогда создайте мое дополнение, указав значение для «библиотек» в главной цели в моем файле binding.gyp, все работает нормально.

Однако, что бы я хотел , как, чтобы сделать, это создать общую библиотеку из источника из процесса node-gyp, вызвав make в файле make-файла общей библиотеки. Я попытался добавить зависимую цель, используя свойство «действия» для этого дополнения в binding.gyp и делает основной мишенью зависит от него:

{ 
     "target_name": "other_library", 
     "type": "none", 
     "actions": [ 
      { 
       "action_name": "build_other_library", 
       "inputs": [], 
       "outputs": [ "/path/to/build/output/libother.so" ], 
       "action": [ "make", "-C", "/path/to/makefile" ] 
      } 
     ] 
    } 

Это не полностью работает. Это : обнаружение другого make-файла и make запускается (я вижу, что это происходит с -verbose set), но make-файл не выполняется должным образом.

Кажется, что правила неявной сборки GNU make подавляются, когда выполняется make-файл для общей библиотеки. Это означает, что файлы .cc и .cpp не компилируются в .o-файлы.

Я понимаю, что node-gyp сам генерирует набор make-файлов для надстроек из целевых объектов в binding.gyp, а файл make-файла разделяемой библиотеки генерируется из одного из них.

Наследует ли настройки make от node-gyp, включая подавление встроенных правил?

Есть ли способ вокруг него? (Помимо добавления явных правил сборки в файл make в общей библиотеке)?

(Я попытался заменить make на $ (MAKE), это не имело значения).

EDIT:

Запуск GNU сделать на разделяемую библиотеку с указанной опцией -d из оболочки (т.е. вне узла лавочка), поиск неявного правила для типичного исходного файла выглядит следующим образом:

Considering target file `code.o'. 
    File `code.o' does not exist. 
    Looking for an implicit rule for `code.o'. 
    Trying pattern rule with stem `code'. 
    Trying implicit prerequisite `code.c'. 
    Trying pattern rule with stem `code'. 
    Trying implicit prerequisite `code.cc'. 
    Trying pattern rule with stem `code'. 
    Trying implicit prerequisite `code.C'. 
    Trying pattern rule with stem `code'. 
    Trying implicit prerequisite `code.cpp'. 
    Found prerequisite `code.cpp' as VPATH `../Common/code.cpp' 
    Found an implicit rule for `code.o'. 

Добавление -d в вызове из блока действий в узел-Gyp зависимой цели, тот же самый исходный файл получает это:

Considering target file `code.o'. 
File `code.o' does not exist. 
Looking for an implicit rule for `code.o'. 
No implicit rule found for `code.o'. 

Так это выглядит как неявные правила сборки подавляются (?)

ответ

1

node-gypMAKEFLAGS=-r в своем профиле makefile. -r - это короткая форма --no-builtin-rules, и по умолчанию она передается любым подкатегориям .

Тем не менее, вы сможете повторно включить встроенные правила для своего суб-make , установив MAKEFLAGS в состояние по умолчанию в вызывающей среде.

Не изменяя свое обязательное действие, вы можете добиться этого, превзойдя экспорт исправленного MAKEFLAGS в ваш файл, а затем повторно запустив $(MAKE).

Для иллюстрации, притворитесь это ваш оригинальный Makefile:

all: foo 

foo: foo.o 
    $(CC) -o [email protected] $< 

, в котором вы делаете программу foo из одного исходного файла foo.c (предполагается, что существовать в рабочем каталоге) и рассчитывает на встроенный правило для %o: %c для компиляции foo.o от foo.c. Так с этим Makefile сборка будет терпеть неудачу:

*** No rule to make target 'foo.o', needed by 'foo'. Stop. 

Измените Makefile так:

ifneq ($(MAKEFLAGS),w) 
all: 
    export MAKEFLAGS=-w && $(MAKE) 
else 
all: foo 

foo: foo.o 
    $(CC) -o [email protected] $< 

endif 

Теперь марка будет рекурсию, если -r находится в MAKEFLAGS и работать с MAKEFLAGS=-w вместо:

$ node-gyp 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 make 
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ] 
make: Entering directory '/home/imk/develop/scrap/build' 
    ACTION binding_gyp_prog_target_build_foo foo 
make[1]: Entering directory '/home/imk/develop/scrap' 
export MAKEFLAGS=-w && make 
make[2]: Entering directory '/home/imk/develop/scrap' 
cc -c -o foo.o foo.c 
cc -o foo foo.o 
make[2]: Leaving directory '/home/imk/develop/scrap' 
make[1]: Leaving directory '/home/imk/develop/scrap' 
    TOUCH Release/obj.target/prog.stamp 
make: Leaving directory '/home/imk/develop/scrap/build' 
gyp info ok 

-w (сокращение от --print-directory) - это номер по умолчанию, который был до того, как узел-gyp добавлен -r.

Обратите внимание, что тест ifneq ($(MAKEFLAGS),w) верен. Он не должен быть ifneq ($(MAKEFLAGS),-w). Если переменной окруженияMAKEFLAGS содержит опцию make командной строки то GNU Make специальных переменнойMAKEFLAGS будет содержать только символ опции.

+0

Я вижу, что вы получаете, и чисто с точки зрения перспективы имеет смысл. – dtopham75

+0

Я вижу, что вы получаете, и с точки зрения перспективы это имеет смысл. Однако, это не сработает. Проблема заключается в том, что node-gyp (или просто gyp) объединяет массив «action» вместе. Он не любит элементы, содержащие знак =. Это: «действие»: ["make", "-C", "/ path/to/makefile"] 'расширяется до' 'make -C/path/to/makefile' в сгенерированном make-файле для цель. Но «действие»: ["export MAKEFLAGS = -w && make -C", "/ path/to/makefile" ']' переходит в '"экспорт MAKEFLAGS = -w && make -C"/path/to/makefile ', без кавычек. То же самое для любого, содержащего a =. – dtopham75

+0

@ dtopham75 Я должен был взять на себя труд, чтобы дать вам проверенное решение. Вот один из них: –