LINUX.ORG.RU

CMake сжирает всю память и процессор

 , , , ,


0

1

Всем привет!

Вопрос наверно глупый для тех кто пишет на плюсах, но я с таким никогда еще не сталкивался. Есть telegram библиотека для написания клиентских приложений tdlib. Мне она нужна для использования на Java. https://github.com/tdlib/td/tree/master/example/java

Для того чтобы смочь ею пользоваться, ее нужно собрать под свою систему. Что я и пытался сделать. Но столкнулся с небольшой неожиданностью. Оказывается это занимает не 10 минут, не 30 минут, и даже не час! Я до сих пор не знаю сколько это занимает времени, я оставлял на ночь сборку и на утро она все еще шла! Пришлось отменить т.к. нужен был компьютер для работы. Это нормально?

Может я не правильно что-то делаю? Кроме того сборка забирает все мои бедные 4гб оперативки и полностью загружает 4 ядра. Системой пользоваться невозможно. Да что там системой, даже мышкой пошевелить нельзя, она еле откликается на движения.

И у меня такой вопрос. Если все же у меня получиться собрать и использовать эту библиотеку, и я захочу задеплоить на сервер готовый jar-ник, мне же придется собирать под сервер по новой библиотеку? Т.е. лучше сразу начать сборку библиотеки на сервере и там уже собирать и тестировать свое java-приложение?

cmake - это только система сборки, дело не в нём. Для компиляции сложных исходников (при использовании большого количества шаблонов, например) на современном C++, компиляторы C++ требуют много памяти и процессорного времени. И это никак не исправить.

mironov_ivan ★★★★★ ()

Выше уже написали, всё жрёт компилятор, а не cmake. Памяти не хватает, оно лезет в свап и результат предсказуем.

Ищи готовую сборку или нормальный комп.

anonymous ()

Добавить swapfile размером 6GB к твоей 4GB памяти.

Собирать с cmake --build . -j8 (или make -j8) если 4 ядра реальных, или -j4 если 2ядра+2HT.

И не забудь ещё про то, что нужно передать -DTD_ENABLE_JNI=ON в CMake, чтобы Java-код мог взаимодействовать с нативной библиотекой посредством JNI.

EXL ★★★★★ ()
Последнее исправление: EXL (всего исправлений: 2)
Ответ на: комментарий от mironov_ivan

Спасибо за тычок носом в issues! Я что-то не додумался сам туда заглянуть)

Тогда еще такой вопрос. Как работает зависимость от системы при сборке. Например если я собираю на Debian 9 то и запустить я смогу только на Debian 9, и никак иначе? Или это тоже зависит от исходников?

Sppawa ()
Ответ на: комментарий от Sppawa

Вообще это зависит от очень большого количества факторов (компилятор, используемые сторонние библиотеки, как написан код, etc.), но в общем случае да, при сборке в среде Debian 9 полученные бинари гарантированно работать будут только в Debian 9. С той же процессорной архитектурой, естественно.

Обычно если надо под одним дистрибутивом линукса полноценно собрать что-то для другого, используют chroot, контейнеры (docker, например), виртуалки (qemu-kvm, например) или какие-нибудь обёртки для вышеперечисленного. Внутри которых стоит окружение другого дистрибутива.

mironov_ivan ★★★★★ ()
Ответ на: комментарий от Sppawa

Например если я собираю на Debian 9 то и запустить я смогу только на Debian 9, и никак иначе?

В общем случае, на более старых системах ты можешь получить ошибку аля:

/usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20'

Поэтому лучше всего собирать на старых дистрах со старым Glibc. Я посмотрел в их реп, они собирают на trusty. Это Ubuntu 14.04.

EXL ★★★★★ ()
Ответ на: комментарий от mironov_ivan

ппц, программа для отсылки сообщений собирается дольше и жрет памяти на сборке больше, чем кеды.

дожили.

поправка: библиотека для программы для *

takino ★★★★ ()
Последнее исправление: takino (всего исправлений: 1)
Ответ на: комментарий от EXL

У меня стоит свап на 4гб. Этого не хватит? Лучше поменять на 6?

И еще, у них в редми написано что два раза нужно собирать. Первый раз саму tdlib, а потом example для Java. Я правильно понял? https://github.com/tdlib/td/tree/master/example/java

Sppawa ()
Ответ на: комментарий от Sppawa

Лучше оперативки добавьте. И процессор обновить может оказаться нелишним. Что за процессор, сколько памяти у вас?

Своп не советую - в свопе всё будет собираться не днями, а месяцами, а то и годами.

Ещё MAKEOPTS какой у вас?.. надо указывать больше -j1, в идеале число ядер процессора. Чем больше MAKEOPS, тем более параллельно идёт сборка, но может в то же время кушать больше памяти.

(как в cmake это указывается, я не помню - не интересовался этим)

P.S. https://wiki.gentoo.org/wiki/MAKEOPTS я про это, там вообще-то gentoo-специфично - но подозреваю в случае ручной сборки надо какую-то переменную среды или параметр для cmake/make указать.

BattleCoder ★★★★★ ()
Последнее исправление: BattleCoder (всего исправлений: 1)
Ответ на: комментарий от EXL

(или make -j8) если 4 ядра реальных

Вы уверены, что это хорошая идея? Ну и про сборку в свопе тоже...

-j надо увеличивать, но осторожно... в меру. чем он больше, тем больше памяти нужно.

BattleCoder ★★★★★ ()

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

Не увидел сразу, виноват.

Возможно, у вас этот параметр автоматом выставляется в -j4 или -j8 или что-то такое, вот память и кончается. Тогда имеет смысл его наоборот, уменьшить. -j3/-j2. Процессор будет нагружаться меньше (что вообще-то замедлит сборку), но памяти будет съедаться меньше.

Но боюсь, вам с 4 гигабайтами памяти не разгуляться. Купите планку (я вот на днях обновил до 16, радуюсь как ребёнок), она сейчас недорого стоит.

BattleCoder ★★★★★ ()
Последнее исправление: BattleCoder (всего исправлений: 1)
Ответ на: комментарий от BattleCoder

Да, я бы тоже не стал увеличить j при недостатке оперативы. А свопа добавить, что бы не падало, скорости это вряд ли прибавит.

Кроме смены компилятора (или версии компилятора, попробуй на старом gcc например), поможет только смена железа (добавление оперативы). Чудес не бывает.

Deleted ()
Ответ на: комментарий от takino

там цэпэпэшки на 27К строк.

............................................________
....................................,.-'"...................``~.,
.............................,.-"..................................."-.,
.........................,/...............................................":,
.....................,?......................................................,
.................../...........................................................,}
................./......................................................,:`^`..}
.............../...................................................,:"........./
..............?.....__.........................................:`.........../
............./__.(....."~-,_..............................,:`........../
.........../(_...."~,_........"~,_....................,:`........_/
..........{.._$;_......"=,_......."-,_.......,.-~-,},.~";/....}
...........((.....*~_......."=-._......";,,./`..../"............../
...,,,___.`~,......"~.,....................`.....}............../
............(....`=-,,.......`........................(......;_,,-"
............/.`~,......`-...................................../
.............`~.*-,.....................................|,./.....,__
,,_..........}.>-._...................................|..............`=~-,
.....`=~-,__......`,.................................
...................`=~-,,.,...............................
................................`:,,...........................`..............__
.....................................`=-,...................,%`>--==``
........................................_..........._,-%.......`
..................................., 
mos ★★★★★ ()
Ответ на: комментарий от BattleCoder

Возможно, у вас этот параметр автоматом выставляется в -j4 или -j8 или что-то такое

Кстати да, cmake гнерит сборку с максимальным j, по имеющимся в системе ядрам. ТС, делай `cmake -j1 --build .`, или экспортни CMAKE_BUILD_PARALLEL_LEVEL

Deleted ()

афтырь, на каком пылесосе ты собираешь этот Ынтерпайзный (с) (тм) софт?
на далеко не свежем AMD FX с 8 гигами памяти в чруте (ubuntu 18.04 gcc) собралось минут за 45 и расход памяти судя по всему к критическому не подходил - своп был девственно чист, когда бы я не смотрел free

mos ★★★★★ ()
Ответ на: комментарий от Deleted

Да мне в принципе не нужно урезать ресурсы для cmake. Я просто хотел узнать в норме ли такая нагрузка на машину от сборки.

в общем случае да, при сборке в среде Debian 9 полученные бинари гарантированно работать будут только в Debian 9. С той же процессорной архитектурой, естественно.

Что в данном случае имеется ввиду под процессорной архитектурой? Разрядность системы? Или важен даже тип и модель процессора? В таком случае, если я например хочу потом задеплоить свое приложение на какой-нибудь VPS с тем же Debian 9 на котором я и собирал, то остается только молиться богу, чтобы мои архитектурные характеристики совпали с его?

Sppawa ()
Ответ на: комментарий от Sppawa

Я просто хотел узнать в норме ли такая нагрузка на машину от сборки

Да, у меня рабочий проект требует около 9 GB RAM и собирается около часа на ноуте, например. Это C++ с его прелестями.

Deleted ()
Ответ на: комментарий от a1batross

Да там кажется вообще какой-то баг в GCC. Смотри, разрабы отключили многопоточную сборку для него, но оставили для Clang'а:

https://github.com/tdlib/td/blob/master/.travis.yml#L23

Сейчас попробовал — при сборке в несколько потоков GCC съедает все 128 GB RAM на Travis-CI и прибивается по OOM.

EXL ★★★★★ ()
Ответ на: комментарий от mironov_ivan

Там же, кстати, рекомендуют попробовать clang вместо gcc. Но я сомневаюсь, что он будет жрать сильно меньше памяти.

Тут ещё вопрос в том, а будет ли библиотека собранная Clang'ом работать с libjvm.so, который собран GCC? C++ ABI и всё такое.

Я вот попробовал пример про который ТС ниже спрашивал собрать и запустить с либами которые собрались Travis'овским Clang'ом и получил закономерное:

$ java '-Djava.library.path=.' org/drinkless/tdlib/example/Example
java: symbol lookup error: /home/exl/Downloads/td/example/java/bin/libtdjni.so: undefined symbol: _ZN2td3jni22register_native_methodEP7JNIEnv_P7_jclassNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_Pv

А собирать эту либу в один поток на GCC и ждать час мне тупо лень.

EXL ★★★★★ ()
Ответ на: комментарий от BattleCoder

Ну и про сборку в свопе тоже...

SWAP-файл не раз выручал меня, когда нужно было собрать что-то требующее 6-10 GB RAM для сборки, на машинке где всего 4 GB RAM.

EXL ★★★★★ ()
Ответ на: комментарий от anonymous

Ситуации разные бывают. Если RAM жрёт только линковка, то -j8/-j4 никак не повлияют на её потребление.

А вот если шаблонная дрисня (похоже в этом проекте именно так), то ты конечно прав.

EXL ★★★★★ ()
Ответ на: комментарий от EXL

Почему я не удивлён, что всё что связано с Telegram является говнокодом? Что официальный клиент, что библиотека...

Ну так пусть клангом и компилит. Кланг делает хорошую работу по совместимости с GCC, даже на уровне плюсов.

Тут ещё вопрос в том, а будет ли библиотека собранная Clang'ом работать с libjvm.so, который собран GCC? C++ ABI и всё такое.

JNI это исключительно Си.

a1batross ★★★★★ ()
Ответ на: комментарий от EXL

А по времени как? Мне даже интересно?

Собирал как-то firefox на 6 гигабайтах оперативки (часть была занята другими приложениями, доступно может быть для компилятора 4-5) - с -j4 уходил в своп и тратил очень много времени (хотя, безусловно, дождаться было можно), а в -j1 за более приемлемое время собирался. С тех пор, конечно, добавил уже оперативки - давно хотел на самом деле, откладывал.

P.S. Ещё важный факт, где swap находится - на старом медленном HDD/SSD, или на новом реактивном SSD.

BattleCoder ★★★★★ ()
Последнее исправление: BattleCoder (всего исправлений: 2)
Ответ на: комментарий от BattleCoder

А по времени как?

Да норм у меня было. Собирал с -j4 на 2GB и 4-ядерном CPU. Сборка Firefox жрала память только на линковке и я добавлял 6GB swapfile. Собиралось оно минут 40-50, насколько я помню. Без -j4 часа два-три.

SSD был, но не слишком быстрый. Новые HDD наверное быстрее будут :)

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

Ну и тут важный момент, если код — шаблонная дрисня и OOM приходит из-за компилятора, то -j4 будет во вред, конечно. А если при ООМ ядро убивает не компилятор, а линкер, то с -j4 и на системе с малым количеством RAM будет отлично работать.

EXL ★★★★★ ()
Ответ на: комментарий от a1batross

JNI это исключительно Си.

У меня запуск примера почему-то ругается на заманджленную питушню:

java: symbol lookup error: /home/exl/Downloads/td/example/java/bin/libtdjni.so: undefined symbol: _ZN2td3jni22register_native_methodEP7JNIEnv_P7_jclassNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_Pv

Разбираться из-за чего такая хрень — лень. Возможно из-за того, что либа собранная Clang'ом не работает с libjvm, которая собрана GCC. А может из-за того, что на Ubuntu 14.04 эта libjvm отличная от той, что имеется в моей системе. Хотя вроде как и там и у меня Oracle Java 8.

EXL ★★★★★ ()

Тем временем на NixCon 2018 edolstra делился планами сделать из Nix ещё и систему сборки проектов.

Nix должен захватить мир, покайтесь и смиритесь.

anonymous ()