#c #qt #visual-studio-2012 #linker #static-libraries
#c #qt #visual-studio-2012 #компоновщик #статические библиотеки
Вопрос:
У меня было 300 KB
приложение, связанное динамически, из-за множества проблем я решил попробовать статическую компоновку сборки.
Я настроил Qt следующим образом:
configure -c 11 -mp -static -debug-and-release -platform win32-msvc2012 -opengl desktop -opensource -confirm-license -make libs -nomake tools -nomake tests -nomake examples -no-openssl -skip webkit
В динамически связанной сборке мне приходилось ссылаться только на зависимости:
qtmain.lib
Qt5Gui.lib
Qt5Core.lib
Qt5Widgets.lib
Qt5Network.lib
Qt5WinExtras.lib
qwindows.lib
Теперь мне приходится использовать 15 библиотек!
qtmain.lib
qtpcre.lib
Qt5Gui.lib
Qt5Core.lib
Qt5Widgets.lib
Qt5Network.lib
Qt5WinExtras.lib
opengl32.lib
imm32.lib
Ws2_32.lib
Qt5PlatformSupport.lib
qtfreetype.lib
winmm.lib
qtharfbuzzng.lib
qwindows.lib
Я имею в виду, почему я должен ссылаться на qtpcre
или qtfreetype
, если я не использую регулярные выражения или свободный тип в своем решении? Мне действительно нужно все это?
Я попытался включить полную оптимизацию.
В результате размер моего приложения составляет 10 731 КБ, и это действительно расстраивает и угнетает. Есть ли какая-либо возможность уменьшить его? Может быть, внешние приложения?
(Да, я знаю, что это статическая сборка, и это не будет файл размером 7 МБ или меньше, но, может быть, я мог бы получить хотя бы меньше 10 МБ?)
Комментарии:
1. Вы зависите от набора динамических библиотек. Они, в свою очередь, зависят от других динамических библиотек, которые, в свою очередь, могут зависеть от других библиотек и т.д. Если вы связываете статически, вам нужно связать со всеми библиотеками в дереве зависимостей. И да, это может сделать ваш исполняемый файл действительно большим, но это компромисс статического связывания. И ваши требования к памяти на самом деле не изменятся, все эти динамические библиотеки все еще необходимо загрузить, статическое связывание может фактически сэкономить некоторую память, поскольку это только один файл, который должен быть загружен операционной системой.
2. Возможно, вам не нужно использовать регулярное выражение, но используемые вами функции библиотеки qt нуждаются в регулярном выражении, следовательно, с ними необходимо связать. Если вы хотите использовать статическое связывание, поиск всех косвенных зависимостей теперь является вашей обязанностью. Даже при динамическом связывании вы по-прежнему загружаете весь этот код, за исключением того, что динамический компоновщик выполняет всю эту работу за вас.
3. Кроме того, этот размер вы показываете для сборки debug или release? Вы пробовали удалять отладочные и другие метаданные из исполняемого файла? Передать флаги компилятора для оптимизации размера, а не скорости?
4. Библиотеки и зависимости Qt довольно большие, так что это то, что происходит, когда вы статически связываете с qt. Также обратите внимание, что при статической сборке на основе Qt могут возникнуть проблемы с лицензированием.
5. «Есть ли какая-либо возможность уменьшить его?» — да, вернитесь к динамическому связыванию. Вероятно, стоит попытаться решить проблему «из-за множества проблем», которая заставила вас перейти к статическому связыванию.
Ответ №1:
Существует инструмент, который значительно уменьшает размер исполняемого файла под названием upx
Использование:
upx --best path/to/executable
Рассмотрите также возможность добавления -q
опции, которая не выводила бы выходные данные). Таким образом, вы даже можете добавить этот инструмент в свой процесс сборки, чтобы избежать дополнительных действий вручную.
Комментарии:
1. Хороший инструмент. Спасибо! 🙂
Ответ №2:
Дополнительные зависимости, вероятно, являются системными библиотеками, динамическая сборка которых в противном случае загружалась бы динамически, или косвенными зависимостями. В статической сборке они не могут использоваться в качестве плагинов и должны быть включены в двоичный файл.
Имейте в виду, что только потому, что вы явно не используете функцию, это не означает, что функции, на которые вы подаете в суд, не зависят от других и прочее. Зависимость есть зависимость, независимо от того, прямая она или косвенная.
10 МБ — это не так уж мало, и вы уже экономите значительный объем пространства по сравнению с развертыванием библиотек динамических ссылок. Двоичный файл будет включать в себя всю необходимую функциональность, и вы ничего не сможете с этим поделать, если вам действительно нужны эти модули. Кроме того, статическая сборка будет иметь немного лучшую производительность (и, конечно, удобство развертывания).
Я не помню флагов компилятора по умолчанию, но, скорее всего, по умолчанию он не оптимизирован по размеру, поэтому для MSVC вы можете получить двоичные файлы меньшего размера, используя /O1
для минимального размера. Обратите внимание, что это может привести к небольшому снижению производительности.
Кроме того, даже при том, что количество библиотек больше, большинство из них довольно малы и на самом деле не будут сильно увеличивать двоичный размер.
Наконец, вы действительно не хотите создавать отладочные двоичные файлы для Qt — они огромны, и это отнимает много потерянного времени. Отлаживайте с использованием версии с динамической связью, создавайте только статические двоичные файлы для выпуска.