Насколько возможно удаление неиспользуемого кода и данных из статических библиотек?
Есть задача: быстро и просто создавать GUI-приложения как можно меньшего размера (в идеале, чтобы данные и код интерфейса занимали не более 3-5 мегабайт) в виде единого исполняемого файла. Желательна мультиплатформенность.
В качестве фреймворка идеально подходит Qt, но он слишком громоздкий. Попытки пересобрать его с минимальным набором функционала выигрыша в размере практически не дали. Альтернативы вроде wxWidgets тоже рассматривались, никаких плюсов по сравнению с Qt не имеют. Всякие маловесные библиотеки либо слишком заморочены, либо имеют другие критические недостатки.
Собственно, вопрос: существуют ли способы слинковать приложение так, чтобы в нём не было неиспользуемого кода/данных? Наверняка ведь для этого что-нибудь придумано.
P.S. Об упаковщиках исполняемых файлов я знаю, вопрос об удалении избыточных данных.
Оно работает не само по себе, а только если указать компилятору паковать функции в т.н. COMDAT-объекты (/Gy), а линковщику — удалять такие объекты, если они не используются и/или «сворачивать» идентичные объекты (/OPT:REF, /OPT:ICF).
Такая линковка с использованием QtCore + QtGui дала исполняемый файл размером всего 6 МБ. Это при том, что есть простор для дальнейших оптимизаций. При сжатии 7-zip весит всего 2 МБ, что просто чудесно.
Берете IDE, добавляете туда проект фреймворка Qt и свой проект. Настраиваете свой проект так, чтобы он ссылался на код Qt. Сам же фреймворк Qt собираете как статическую библиотеку.
В итоге компилятор возьмет из Qt только те участки кода, которые реально нужны вашему приложению.
Ну почему ж извращенческий. :)
Мы так на работе делаем. Довольно стандартный подход для приложения «все включено».
Однако минус тут существенный: нельзя подложить приложению обновленную либу, если в старой были баги. Только полная пересборка.
Оно работает не само по себе, а только если указать компилятору паковать функции в т.н. COMDAT-объекты (/Gy), а линковщику — удалять такие объекты, если они не используются и/или «сворачивать» идентичные объекты (/OPT:REF, /OPT:ICF).
Хотя эффект от статической линковки будет и без этого — линковщику будет выкидывать целые единицы компиляции в которых не окажется ни одного используемого символа. А раз QT большой, там таких единиц тоже хватит.
Технически можно линковаться и статически. Если тот, кто получил от нас программу, захочет получить исходный код LGPL-компонента чтобы затем модифицировать/компилировать его самому — а в этом, собственно, и смысл LGPL-лицензий — можно будет выдать ему этот исходник плюс скомпилированные объектные файлы, с которыми он и слинкуется.
A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”.
The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version.
You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:
Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
Важные места я выделил. Явно написано, что excluding source code самого приложения, а вместо corresponding source можно дать corresponding application code.
Мне кажется, я и говорил насчет linkable binaries («скомпилированные объектные файлы») с самого начала :) Кстати, мы не разные LGPL читаем? Если речь идет о третьей версии, то к делу относится пункт 4.d: пункт 0 описывает статическую линковку, пункт 1 — динамическую.