Проблема в том, что не удается заставить собрать проект так, чтобы библиотеки прилинковывались статически. Проект собирается с autotools, я проиллюстрирую проблему на простейшем hello-world проекте, буду очень благодарен, если кто-нибудь укажет на мои ошибки.Сначала покажу, как все работает без autotools. Код hello.cc:
#include <iostream>
int main()
{
std::cout << "Hello world" << std::endl;
return 0;
}Компилируем:
$ g++ -o hello hello.cc
Получаем бинарник hello, 8829 байт. Теперь попробуем прилинковать к нему какую-нибудь библиотеку:
$ g++ -o hello hello.cc -lxml2
Получаем немного больший файл, 9077 байт. Теперь попробуем прилинковать его статически:
$ g++ -static -o hello hello.cc -lxml2
Получаем файл в 1263359 байт, т.е. все прилинковалось нормально. Теперь попробуем сделать то же, но с autotools.
Создаем проект, вот файл configure.ac:
AC_INIT(hello,1.0)
AM_INIT_AUTOMAKE(hello,1.0)AM_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LIBTOOL
AC_OUTPUT(Makefile)и файл Makefile.am:
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = hello
hello_SOURCES = hello.cc
hello_LDADD = -lxml2
hello_LDFLAGS = -L/usr/libгенерируем файлы проекта:
$ libtoolize --force && aclocal && autoconf && autoheader && automake --add-missing --gnu
You should add the contents of `/usr/share/aclocal/libtool.m4' to `aclocal.m4'.
configure.ac:2: installing `./install-sh'
configure.ac:2: installing `./missing'
Makefile.am: installing `./depcomp'./configure - появился Makefile, собираем:
$ make
make all-am
make[1]: Entering directory `/home/andrey/test'
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.cc
mv -f .deps/hello.Tpo .deps/hello.Po
/bin/bash ./libtool --tag=CXX --mode=link g++ -g -O2 -L/usr/lib -o hello hello.o -lxml2
mkdir .libs
g++ -g -O2 -o hello hello.o -L/usr/lib /usr/lib/libxml2.soПолучаем файл hello размером 43086 байт, с динамически прилинкованой библиотекой. В куче доков, которые я перерыл, советуют добавлять -static к _LDFLAGS, это не имеет никакого эффекта:
$ make
make all-am
make[1]: Entering directory `/home/andrey/test'
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.cc
mv -f .deps/hello.Tpo .deps/hello.Po
/bin/bash ./libtool --tag=CXX --mode=link g++ -g -O2 -static -L/usr/lib -o hello hello.o -lxml2
mkdir .libs
g++ -g -O2 -o hello hello.o -L/usr/lib /usr/lib/libxml2.soСоветуют также делать ./configure --disable-shared, это тоже ничего не меняет.
./configure --disable-shared
...
checking whether to build shared libraries... no
checking whether to build static libraries... yes
...
$ make
make all-am
make[1]: Entering directory `/home/andrey/test'
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.cc
mv -f .deps/hello.Tpo .deps/hello.Po
/bin/bash ./libtool --tag=CXX --mode=link g++ -g -O2 -static -L/usr/lib -o hello hello.o -lxml2
mkdir .libs
g++ -g -O2 -o hello hello.o -L/usr/lib /usr/lib/libxml2.soЧто еще делать, ума не приложу. Подскажите, пожалуйста, в чем я не прав.
вместо -static добавляйте -all-static в Makefile.am
>вместо -static добавляйте -all-static в Makefile.amО, спасибо большое, получилось. Об -all-static тоже видел в документации, но видимо не туда вставлял, потому как не получалось.
Статическая линковка с libc или g++ это очень плохо.
> Статическая линковка с libc или g++ это очень плохо.А что порекомендуете в данном случае? Я не могу собирать проект на машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы собранный бинарник там работал.
>А что порекомендуете в данном случае? Я не могу собирать проект на
>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>собранный бинарник там работал.Ну libc и подобные библиотеки на машине назначения есть однозначно ))
Я к тому что не надо увлекаться и делать полностью статический вариант. Слинковал сторонние библиотеки статически, но вот системные линковать статичеки не надо.
При статической линковке glibc портятся syscall в linux. Могут сломатся nss из-за несовпадения путей имён файлов настроек. При статической линковке с libstdc++ не работают исключения.
>>А что порекомендуете в данном случае? Я не могу собирать проект на
>>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>>собранный бинарник там работал.
>Я к тому что не надо увлекаться и делать полностью статический вариант.
>Слинковал сторонние библиотеки статически, но вот системные линковать статичеки не надо.Вот мне и интересно, как слинковать статически только сторонние библиотеки. -all-static здесь не подходит, как я понимаю, но чем пользоваться вместо?
>не подходит, как я понимаю, но чем пользоваться вместо?Я вообще не в курсе как работает autotools. Да и не понимаю? зачем они тебе, если компилируешь сам ))
Если ты хочешь линковать разные библиотеки по разному - чередуй опции -static -dynamic.
Они действуют на библиотеки перечисленные ПОСЛЕ этой опции.То есть например если ты хочешь несколько библиотек линковать статически - перечисляй их между -static и -dynamic опциями линковщика.
>>не подходит, как я понимаю, но чем пользоваться вместо?
>
>Я вообще не в курсе как работает autotools. Да и не понимаю?
>зачем они тебе, если компилируешь сам ))Хм, в целом да, чего я зациклился на autotools именно в этом проекте - неясно. Все равно сам собираю всегда. Спасибо.
>> Статическая линковка с libc или g++ это очень плохо.
>
>А что порекомендуете в данном случае? Я не могу собирать проект на
>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>собранный бинарник там работал.Можете, просто надо донести до кого-то в руководстве некоторые понятия о unix-way, разъяснить что такое устанавливаемый пакет, репозитории пакетов, build-машины и т.п. иначе вечно будет наколеночная сборка и виндовое копирование бинарника куда-то там с созданием кучи проблем в будущем. И не надо будет городить огород со статической линковкой, которую сейчас используют только в исключительных случаях.
>>> Статическая линковка с libc или g++ это очень плохо.
>>
>>А что порекомендуете в данном случае? Я не могу собирать проект на
>>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>>собранный бинарник там работал.
>
>Можете, просто надо донести до кого-то в руководстве некоторые понятия о unix-way,
>разъяснить что такое устанавливаемый пакет, репозитории пакетов, build-машины и т.п. иначеНасчет руководства - это немного мимо, в данном случае руководство - я. Ограничения связаны с тем, что клиент права администратора для установки нам не даст, а некоторые части исходников должны быть от него закрыты. То есть мы должны дать ему бинарник, в крайнем случае бинарник и пару либ.
>вечно будет наколеночная сборка и виндовое копирование бинарника куда-то там с
>созданием кучи проблем в будущем. И не надо будет городить огород
>со статической линковкой, которую сейчас используют только в исключительных случаях.Вот я и использую в таких условиях, случай достаточно исключительный.
есть такая штука как префикc пути куда устанавливается пакет, это может быть как стандартный системный /usr, так и /usr/local для локальных, не системных пакетов. Более того никто не мешает поставить все это дело в свой префикс например /home/my/local. Библиотеки при установке пакета устанавливаются в <prefix>/lib, бинарник в <prefix>/bin, и т.д. и бинарник будет знать где нужные ему библиотеки благодаря autoools, который позволяет использовать такие средства как pkg-config для конфигурации зависимости пакетов.Кстати, к примеру тот же redhat использует пакеты rpm с помощью которых устанавливаются бинарники как самих программ так и библиотек, что вам мешает поступать также, создавать бинарный пакет на build машине и выдавать клиенту готовый пакет к установке? Исходники при этом клиент вообще не увидит (если в этом есть необходимость).
Случай не исключительный, вполне стандартный. Раз вы руководитель в данном случае, то посмотрите на то как поставляется софт под половину дистрибутивов линукса и не только, они же не предлагают пользователю исходники, они предлагают бинарники, а сорцы уже потом если пользователь захочет, то сам их возьмет да посмотрит, ведь определена лицензией доступность сорцов к просмотру, а не необходимость насильно втюхивать пользователю сорцы. в вашем случае получается распространение бинарников с библиотеками без сорцов только и всего.
Все уже сделано и придумано до нас ;)
> есть такая штука как префикc пути куда устанавливается пакет, это может быть как...Тоже хороший совет, спасибо, попробую и так. Потому что последние пару дней пытаюсь таки собрать все, кроме libc статически - лезет куча каких-то сторонних проблем.