LINUX.ORG.RU

инкрементальная сборка и отладка

 , ,


1

4

Привык я с давних времен программирования под венду, что при изменении одной строчки в одном исходном файле, пересборка и запуск происходит мгновенно. Сейчас отлаживаю одну софтинку в QtCreator, так у меня на каждое мелкое изменение и перезапуск происходит пересборка(возможно и не полная, но очень долго) проекта. Я уже замучился при изменении одной переменной ждать старта отладки по 2 минуты.

Подскажите что делать и как жить? может на clang надо как-то переводить сборку или в gcc\gdb какие ключи есть?

Сейчас(в данный момент) QtCreator запущен в венде с GCC MinGW, но в линуксе дома та же ситуация. Поэтому назвать проблему вендоспецифичной нельзя.

★★★★★

Проблема только на этом проекте? Я с таким не сталкивался, инкрементальная сборка даже для ядра есть

XMs ★★★★★ ()

Бывает, что проект так составлен, что появляются циклические зависимости, которые не дают нормально инкрементальной сборке работать. Лечится выделением некоего «корня» зависимостей, который сам ни от чего не зависит, но от него зависят все.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)

Нагуглил что:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:YES" )

Но получаю:

g++.exe: error: /INCREMENTAL:YES: No such file or directory
Loki13 ★★★★★ ()
Ответ на: комментарий от Loki13

Когда собираешь с помощью cmakе (да и обычный makefile проект), в выхлопе наглядно видно, какие цели из каких файлов после изменений начинают пересобираться.

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

Это похоже для вендового компилятора, а не для g++ опция

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

Попробуй заменить ld на gold, а в ключи gcc добавить "-Wl,--incremental"

i-rinat ★★★★★ ()

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

MuZHiK-2 ★★★★ ()

Это никак не зависит от сред и компиляторов. Если ты делаешь изменение в .h файле от которого зависит пол проекта, хочешь - не хочешь, а будут пересобраны эти полпроекта. Если ты изменяешь один .cpp файл, то пересобирается только этот .cpp файл. Решается минимизацией инклудов, в частности более широким использованием forward declarations и нормальной архитектурой с минимумом зависимостей между частями проекта.

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

Оно должно само работать

Оно вроде как и работает, но вот именно что вроде как. Полная сборка 10 минут, а после уже минуты по 2. Но хочется то чтобы 10-15 секунд было до начала дебага, я же всего одну строчку в файле на 100 строк закомментировал, хочется как оно в MSVC происходит(завтра попробую их компилером собрать проект, сравним).

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

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

Это я понимаю - не дурак. но в том и дело что я делаю изменение в срр файле. А сборка 2 минуты идёт. Да, с нуля, сборка идет 10 минут, но я считаю что всё равно что-то не так.

Завтра попробую этот же проект Qt комплектом MSVC собрать, сегодня нет возможность 800Мб качать.

//Комп вроде тоже далеко не калькулятор.

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

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

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

Тебе же пишут что происходит, что именно занимает эти 2 минуты? Компилируется более одного файла? Значит у тебя что-то не так со временем. Файл компилируется 2 минуты? Итоговый бинарник линкуется 2 минуты?

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

Сборка с нуля:

12:04:11: Процесс «C:\Qt\Tools\mingw491_32\bin\mingw32-make.exe» завершился успешно. 12:04:11: Прошло времени: 16:01.

Вообще не менял ни одного файла, а сразу Ф5 нажал:

12:08:04: Процесс «C:\Qt\Tools\mingw491_32\bin\mingw32-make.exe» завершился успешно. 12:08:04: Прошло времени: 02:41.

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

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

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

Так они не перекомпилируются как видно, а только пересобираются. Может в QtCreator чего подкрутить, что не пересобирал, а только собирал недостающее.

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

А черт их знает. Вроде не должны.

Так вроде или нет? Судя по выхлопу, они каждый раз обновляются, пересобирается библиотека, а потом с ней все перелинковываются.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от Loki13

смотри время модифицаии всех файлов.

find . -printf "%T+\t%p\n" | sort

мэйк будет делать то же самое, и перекомпилять свежие

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

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

Это одно и то же.

[ 2%] Generating version_fake_file, trojita-version.h, trojita-git-version.h

Кстати да. Вероятно они криво генерят эти версии, и они генерятся каждый раз, смотри что там происходит в cmake/TrojitaVersion.cmake. За ублюдство с вызовом git'а в сборке я вообще бы руки отрывал.

slovazap ★★★★★ ()
Ответ на: комментарий от MuZHiK-2

Нашел вот такое с CMakeLists:

add_custom_target(version DEPENDS version_fake_file)
add_custom_command(OUTPUT version_fake_file ${version_files}
    COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DNSIS=${NSIS} -DHOST_ARCH=${HOST_ARCH} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/TrojitaVersion.cmake)
set_source_files_properties(${version_files}
    PROPERTIES GENERATED TRUE
    HEADER_FILE_ONLY TRUE)

Може если этот version_fake_file отключить как-то? Я язык CMakeLists знаю совсем немного.

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

Это одно и то же.

Я под сборкой обычно линковку уже готовых obj подразумевал, а не компиляцию.

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

смотри что там происходит в cmake/TrojitaVersion.cmake

Так вот такое есть:

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/trojita-version.h.in ${TROJITA_VERSION_H})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
    ${CMAKE_CURRENT_BINARY_DIR}/trojita-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/trojita-version.h)

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/trojita-git-version.h.in ${TROJITA_GIT_VERSION_H})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
    ${CMAKE_CURRENT_BINARY_DIR}/trojita-git-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/trojita-git-version.h)

логика подсказывает что copy_if_different должно проверить сначала отличаются ли файлы.

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

version_fake_file твоей сборки не касается. Он, похоже, нужен чтобы ручная цель `make version` всегда пересобиралась. Далее, в TrojitaVersion.cmake:

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/trojita-version.h.in ${TROJITA_VERSION_H})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
    ${CMAKE_CURRENT_BINARY_DIR}/trojita-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/trojita-version.h)

т.е. в trojita-version.h.in записывается новое состяние, и в .h копируется только если оно другое. Смотри что там в этих файлах - по логике trojita-version.h.in хоть и перезаписывается каждый раз, содержимое меняться не должно, копироваться поверх .h не должно (но возможно copy_if_different работает как-то не так и внезапно смотрит на дату), и в итоге ничего что зависит от этого хедера пересобираться не должно. В крайнем случае можешь попробовать просто вырезать эту помойку. Кусок из твоей цитаты, например.

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

Ну начнём с того что это полностью бесполезно, так как работает не надёжно. Я могу вытащить одни и те же исходники из git, а могу скачать tarball с github, и ублюдство сгенерит разные версии.

Далее - хуже: у меня есть git репозиторий с пакетами (FreeBSD порты, ебилды, pkgбилды, whatever), я в нём работаю. Туда выкачивается тарболл с гитхаба и начаниат собираться, вызывается ублюдство, начинает искать .git, и находит .git моего репозитория, а вовсе не своего проекта.

А что ещё хуже, при опакечивании оно формально добавляет build-time зависимость от git, причём без зависимости ведёт себя неконсистентно (где установлен, вызывает git, где не установлен - нет), с зависимостью - тоже (находит .git выше по дереву каталогов или нет), и никогда - правильно.

Поэтому _всегда_ приходится безусловно выкорчёвывать это патчем.

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

т.е. вся проблема это разные сборки опакечивания, а если опакечивать и не нужно, то и проблем нет ?

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

Выкинул. Добился следующего:

13:16:05: Выполняются этапы для проекта trojita...
13:16:05: Запускается: «C:\Qt\Tools\mingw491_32\bin\mingw32-make.exe» trojita
[  0%] Automatic moc for target trojita
[  0%] Built target trojita_automoc
[  0%] Automatic moc for target MSA
[  0%] Built target MSA_automoc
[  0%] Automatic moc for target Streams
[  0%] Built target Streams_automoc
[  3%] Built target Streams
[  3%] Automatic moc for target UiUtils
[  3%] Built target UiUtils_automoc
[  3%] Automatic moc for target Plugins
[  3%] Built target Plugins_automoc
[  6%] Built target Plugins
[  6%] Automatic moc for target Common
[  6%] Built target Common_automoc
[  9%] Built target Common
[ 12%] Built target UiUtils
[ 14%] Automatic moc for target qwwsmtpclient
[ 14%] Built target qwwsmtpclient_automoc
[ 14%] Built target qwwsmtpclient
[ 15%] Automatic moc for target Imap
[ 15%] Built target Imap_automoc
[ 51%] Built target Imap
[ 54%] Built target MSA
[ 56%] Automatic moc for target AppVersion
[ 56%] Built target AppVersion_automoc
[ 56%] Built target AppVersion
[ 56%] Automatic moc for target Cryptography
[ 56%] Built target Cryptography_automoc
[ 57%] Built target Cryptography
[ 57%] Automatic moc for target IPC
[ 57%] Built target IPC_automoc
[ 59%] Built target IPC
[ 60%] Automatic moc for target Composer
[ 60%] Built target Composer_automoc
[ 65%] Built target Composer
[ 65%] Automatic moc for target trojita_plugin_AbookAddressbookPlugin
[ 65%] Built target trojita_plugin_AbookAddressbookPlugin_automoc
[ 68%] Built target trojita_plugin_AbookAddressbookPlugin
[ 70%] Automatic moc for target trojita_plugin_ClearTextPasswordPlugin
[ 70%] Built target trojita_plugin_ClearTextPasswordPlugin_automoc
[ 71%] Built target trojita_plugin_ClearTextPasswordPlugin
[ 71%] Automatic moc for target DesktopGui
[ 71%] Built target DesktopGui_automoc
Scanning dependencies of target DesktopGui
[ 73%] Building CXX object CMakeFiles/DesktopGui.dir/src/Gui/Window.cpp.obj
[ 75%] Linking CXX static library libDesktopGui.a
[ 98%] Built target DesktopGui
[ 98%] Linking CXX executable trojita.exe
[100%] Built target trojita
13:16:31: Процесс «C:\Qt\Tools\mingw491_32\bin\mingw32-make.exe» завершился успешно.
13:16:31: Прошло времени: 00:26.

Если бы еще как-то отключить всю фигню до 71%, то было бы вообще красиво. Оно половину времени от этих 26сек занимает. тогда как изменившийся файл только на 73% перекомпилируется.

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

т.е. вся проблема это разные сборки опакечивания, а если опакечивать и не нужно, то и проблем нет ?

Я вроде написал. Оно не работает, а только создаёт проблемы во всех случаях.

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

У make же вроде есть опция когда он пишет по какой причине цель пересобирается (т.е. какая зависимость изменилась) - посмотри из-за чего собирается этот Window.cpp и где оно генерится. А вообще, конечно, запости багу этим рукожопам.

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

посмотри из-за чего собирается этот Window.cpp и где оно генерится.

Он то как раз и должен собираться. Я его только что менял. А вот всё что 10-15 секунд происходит до 71%, вот этого вот не надо.

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

Это все нормально, просто выхлоп показывает, что проверяется наличие изменений. Не парься. Иначе как будет по-твоему работать инкрементная сборка, если она не проверяет, что изменилось?

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

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

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

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

Чё-то долго. «Build target» без вызовов компилятора и линкера значат что цели собраны и никакие сборочные процессы не вызывались. У меня есть проект в котором в два раза больше целей, там пустой make занимает 0.9 сек. На самом деле и это долго, но это уже тормоза make. Можешь попробовать перейти на ninja - он работает мгновенно, но есть вероятность что он не подружится с костылями от разработчиков trojita.

Ещё есть подозрение на «Automatic moc», возможно он ненужное делает каждую сборку. Если это trojita'всий велосипед, то почти наверняка.

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

Оно же по файлам шерстит, может у тебя медленный доступ к диску, а файлов много.

На всякий случай прогони VERBOSE=1 make - оно тебе должно вывести подробно, что делается под каждым пунктом

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

Ещё есть подозрение на «Automatic moc», возможно он ненужное делает каждую сборку. Если это trojita'всий велосипед, то почти наверняка.

Это фича от Qt, но тут не должно быть проблем.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от x905

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

Да ничего подобного. Разработчик дальше своего localhost'а как правило не видит, поэтом и вызовы git в сборке, и захардкоженные пути, компилятор, флаги, CMAKE_BUILD_TYPE, опциональные зависимости и всё остальное. При этом разработчик один, а пользуются проектом все, и мучиться от кривой сборки приходится всем. Так что свое видение разработчик должен свернуть в трубочку и засунуть себе поглубже, а сборку сделать по-человечески.

я например проблем не вижу

Возможно у тебя действительно проблемы со зрением и мой пост где я расписал как вызов git в сборке гарантированно _не работает_, ты не увидел, но тему-то в которую ты пишешь, и причиной которой послужило то же самое, ты не заметить не мог. Сам что-ли любитель усложнить сборку «умными» решениями?

slovazap ★★★★★ ()
Ответ на: комментарий от MuZHiK-2

Видимо комп медленный, надо кору поновее воткнуть

Core i5-3320M. Памяти 8Гб. Единственно что винт ноутбучный, может быть поэтому медленно файлы шерстит.

Loki13 ★★★★★ ()
Ответ на: комментарий от MuZHiK-2

Я бы всё-таки сначала попробовал ninja. С другой стороны да - если файл компилируется 13 секунд, процессор явно староват.

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

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

x905 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.