@Chalovik

Как скопилить кросс дистрибутивний нативный node.js модуль?

Всем привет.
Пишу модуль на С++ с использованием NAN. Писал его на Debian 9. Компилил, запускал все работало хорошо. Там у меня gcc версии 6.8.0.
На другом ноуте у меня стоит CentOS 7. Когда я пытался запустить приложение с моим модулем на нем, то возникла ошибка:

A Javascript error occurred in the main process
Uncaught Exception:
Error: Cannot open /tmp/.mount_figma-ijkRXB/resources/app.asar/main/binding.node: Error: /lib64/libstdc++.so.6:
/lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found


На CentOS 7 gcc версии 4.8.5. Установить или собрать из исходников gcc более новой версии не увенчалось успехом из-за зависимостей, т.к. в CentOS 7 нету новых версий других пакетов которые требует новая версия gcc. Ну соответственно пересобрать модуль на CentOS так же не получилось.

Подскажите как можно собрать модуль и задеплоить все зависимости? Чтобы можно было использовать модуль на любом linux дистрибутиве независимо есть ли вообще на нем gcc и другие необходимые либы. Как например это делает linuxdeployqt для Qt приложений.
  • Вопрос задан
  • 96 просмотров
Решения вопроса 1
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Два варианта:
1) Линковать с флагом -static-libstdc++. В этом случае статическая версия либы будет влинкована в исполняемый файл. Все остальные зависимости можно тоже линковать статически. Что обычно и делают для плагинов. В общем и целом, это очень хороший вариант.
2) Поставлять нужную версию либы с приложением, и линковать с '-Wl,-rpath,$ORIGIN/relative_path_to_lib_dir'. Тоже самое для остальных зависимостей.

Первый вариант может не сработать по некоторым причинам (скорее всего, вас это не коснётся):
1) Если не известно, с какими флагами хост-приложение выполняет dlopen на ваш плагин. Это можно обойти введением ещё одной прослойки без лишних зависимостей, которая будет правильно выполнять dlopen.
2) Лицензии. Что-то может быть нельзя линковать статически, или можно, но с невыгодными для вас условиями.

Во втором варианте тоже могут быть проблемы. Если хост-приложение уже загрузило зависимость, имя и версия которой совпадает с именем и версией зависимости, которая нужна вашему плагину, то зависимость для вашего плагина загружена не будет. Это не проблема, если зависимости не отличаются. Но вот если вы патчиили свои зависимости, то вам придётся их переименовывать и использовать флаг soname. Но опять же, не уверен, что вас эта проблема коснётся.

Добро пожаловать в мир C++ :)

PS
Попробуйте написать ваш плагин на Rust, например. Жизнь скорее всего станет легче.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Deissh
@Deissh
I like Python, Node.JS, Go, pain, bugs and my cat.
Как один из вариантов использовать Docker для сборки, в нем можно будет скомпилировать с нужными пакетами и версией gcc.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы