Как собрать библиотеку .so из Windows?

Я без проблем собираю динамическую библиотеку .dll:

mkdir build
cd build
cmake .. -A Win32 -T ClangCL
cmake --build .

То же самое прекрасно собирается в Ubuntu 22.04, только .so:

mkdir build
cd build
export CC=path to clang CXX=path to clang++
cmake .. -G Ninja -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32
cmake --build .

Но как я могу находясь в Windows собрать библиотеку под Linux? У меня есть Ninja и Clang.

Ну и если кто-нибудь сможет предложить решение, то подскажите еще как сделать то же самое, но из Linux под Win.


Помню вроде как-то раньше делал такое... в сторону MSYS64 надо копать и GCC ставить. На Clang не получиться из Win собрать под Linux?


Ответы (1 шт):

Автор решения: HolyBlackCat

Во-первых, не-кросс-компиляция (т.е. сразу на целевой системе) сильно проще. Поэтому с винды на линукс проще компилировать в WSL2, или в какой-нибдуь другой виртуальной машине.

Но можно и без этого. Весь остальной ответ написан из предположения, что виртуалку вы использовать не хотите.


в сторону MSYS64 надо копать и GCC ставить. На Clang не получиться из Win собрать под Linux?

Наоборот! Clang сильно упрощает кросс-компиляцию. Чтобы кросс-компилировать используя GCC, его самого нужно перекомпилировать (и выбрать при сборке желаемую платформу). А Clang перекомпилировать не нужно, любая его версия может компилировать под любую платформу.

Клангу нужны хедеры и библиотеки от целевой системы. Можно скопировать весь / с линукса, или можно попробовать выкинуть лишнее. Потом компилировать с флагами --target=платформа --sysroot=путь_до_папки. Имя платформы можно посмотреть в clang --version, запустив на нужной платформе.

Может потребоваться добавить флагов: -stdlib=... (стандартная библиотека С++), -rtlib=..., -unwindlib=..., -f[no-]emulated-tls, ... - разведав их значение на целевой платформе, или подбором.


Про CMake: Если используете его, то передавать руками флажки в компилятор не нужно. Нужно написать тулчейн-файл, чтобы CMake сам это делал.


Для случая linux->windows, дистрибутивы обычно имеют в пакетном менеджере MinGW (версию GCC для сборки под винду, со всеми необходимыми библиотеками).

Или можно взять из MinGW только библиотеки, а компилировать Clang-ом (обычной его версией для линукса) - см. флаги выше.

Часто в дистрибутивы кладут устаревший MinGW (особенно в какой-нибудь Ubuntu LTS...), поэтому может иметь смысл скачать MinGW для винды (для которого последнюю версию найти не проблема), и указать клангу путь до него (через --sysroot=). (Теоретически его можно даже в wine запускать, но это медленно.)


Ну и, если это не очевидно - все использованные third-party библиотеки нужно перекомпилировать для целевой системы.

Для случая windows->linux - можно поставить их из пакетного менеджера на линуксе, до копирования / на винду.

Для случая linux->windows - удобно брать уже скомпилированные библиотеки из репозиториев MSYS2. Сам MSYS2 работает только на винде и собирает под винду, но можно вручную скачать зазипованные библиотеки.

На правах рекламы: у меня есть скрипты, которые на линуксе автоматизируют скачивание библиотек от MSYS2 (и заодно делают все остальное: передают нужные флажки в кланг/cmake/...).

Еще можно посмотреть в сторону пакетных менеджеров типа Conan, которые могут как-то автоматизировать кросс-компиляцию.


Ну и для полноты. Есть msvc-wine, для запуска MSVC на линуксе в Wine, и кросс-компиляции таким способом. Вряд ли подойдет для практических целей, потому что медленный, но можно подсунуть библиотеки от него клангу. (Совместимости с third-party библиотеками для mingw не будет.)

→ Ссылка