URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7666
[ Назад ]

Исходное сообщение
"Статическая линковка + autotools"

Отправлено somemilk , 24-Окт-08 13:25 
Проблема в том, что не удается заставить собрать проект так, чтобы библиотеки прилинковывались статически. Проект собирается с 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

Что еще делать, ума не приложу. Подскажите, пожалуйста, в чем я не прав.


Содержание

Сообщения в этом обсуждении
"Статическая линковка + autotools"
Отправлено vic , 24-Окт-08 18:01 
вместо -static добавляйте -all-static в Makefile.am

"Статическая линковка + autotools"
Отправлено somemilk , 24-Окт-08 18:53 
>вместо -static добавляйте -all-static в Makefile.am

О, спасибо большое, получилось. Об -all-static тоже видел в документации, но видимо не туда вставлял, потому как не получалось.


"Статическая линковка + autotools"
Отправлено Аноним , 24-Окт-08 23:53 
Статическая линковка с libc или g++ это очень плохо.

"Статическая линковка + autotools"
Отправлено somemilk , 25-Окт-08 00:16 
> Статическая линковка с libc или g++ это очень плохо.

А что порекомендуете в данном случае? Я не могу собирать проект на машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы собранный бинарник там работал.


"Статическая линковка + autotools"
Отправлено Аноним , 25-Окт-08 00:30 
>А что порекомендуете в данном случае? Я не могу собирать проект на
>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>собранный бинарник там работал.

Ну libc и подобные библиотеки на машине назначения есть однозначно ))

Я к тому что не надо увлекаться и делать полностью статический вариант. Слинковал сторонние библиотеки статически, но вот системные линковать статичеки не надо.

При статической линковке glibc портятся syscall в linux. Могут сломатся nss из-за несовпадения путей имён файлов настроек. При статической линковке с libstdc++ не работают исключения.


"Статическая линковка + autotools"
Отправлено somemilk , 25-Окт-08 07:13 
>>А что порекомендуете в данном случае? Я не могу собирать проект на
>>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>>собранный бинарник там работал.
>Я к тому что не надо увлекаться и делать полностью статический вариант.
>Слинковал сторонние библиотеки статически, но вот системные линковать статичеки не надо.

Вот мне и интересно, как слинковать статически только сторонние библиотеки. -all-static здесь не подходит, как я понимаю, но чем пользоваться вместо?


"Статическая линковка + autotools"
Отправлено Аноним , 25-Окт-08 13:28 
>не подходит, как я понимаю, но чем пользоваться вместо?

Я вообще не в курсе как работает autotools. Да и не понимаю? зачем они тебе, если компилируешь сам ))


Если ты хочешь линковать разные библиотеки по разному - чередуй опции -static -dynamic.
Они действуют на библиотеки перечисленные ПОСЛЕ этой опции.

То есть например если ты хочешь несколько библиотек линковать статически - перечисляй их между -static и -dynamic опциями линковщика.


"Статическая линковка + autotools"
Отправлено somemilk , 25-Окт-08 13:43 
>>не подходит, как я понимаю, но чем пользоваться вместо?
>
>Я вообще не в курсе как работает autotools. Да и не понимаю?
>зачем они тебе, если компилируешь сам ))

Хм, в целом да, чего я зациклился на autotools именно в этом проекте - неясно. Все равно сам собираю всегда. Спасибо.


"Статическая линковка + autotools"
Отправлено vic , 27-Окт-08 15:56 
>> Статическая линковка с libc или g++ это очень плохо.
>
>А что порекомендуете в данном случае? Я не могу собирать проект на
>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>собранный бинарник там работал.

Можете, просто надо донести до кого-то в руководстве некоторые понятия о unix-way, разъяснить что такое устанавливаемый пакет, репозитории пакетов, build-машины и т.п. иначе вечно будет наколеночная сборка и виндовое копирование бинарника куда-то там с созданием кучи проблем в будущем. И не надо будет городить огород со статической линковкой, которую сейчас используют только в исключительных случаях.


"Статическая линковка + autotools"
Отправлено somemilk , 27-Окт-08 16:09 
>>> Статическая линковка с libc или g++ это очень плохо.
>>
>>А что порекомендуете в данном случае? Я не могу собирать проект на
>>машине назначения, не могу ставить там свои библиотеки. Мне нужно, чтобы
>>собранный бинарник там работал.
>
>Можете, просто надо донести до кого-то в руководстве некоторые понятия о unix-way,
>разъяснить что такое устанавливаемый пакет, репозитории пакетов, build-машины и т.п. иначе

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

>вечно будет наколеночная сборка и виндовое копирование бинарника куда-то там с
>созданием кучи проблем в будущем. И не надо будет городить огород
>со статической линковкой, которую сейчас используют только в исключительных случаях.

Вот я и использую в таких условиях, случай достаточно исключительный.


"Статическая линковка + autotools"
Отправлено vic , 27-Окт-08 16:40 
есть такая штука как префикc пути куда устанавливается пакет, это может быть как стандартный системный /usr, так и /usr/local для локальных, не системных пакетов. Более того никто не мешает поставить все это дело в свой префикс например /home/my/local. Библиотеки при установке пакета устанавливаются в <prefix>/lib, бинарник в <prefix>/bin, и т.д. и бинарник будет знать где нужные ему библиотеки благодаря autoools, который позволяет использовать такие средства как pkg-config для конфигурации зависимости пакетов.

Кстати, к примеру тот же redhat использует пакеты rpm с помощью которых устанавливаются бинарники как самих программ так и библиотек, что вам мешает поступать также, создавать бинарный пакет на build машине и выдавать клиенту готовый пакет к установке? Исходники при этом клиент вообще не увидит (если в этом есть необходимость).

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

Все уже сделано и придумано до нас ;)


"Статическая линковка + autotools"
Отправлено somemilk , 27-Окт-08 17:01 
> есть такая штука как префикc пути куда устанавливается пакет, это может быть как...

Тоже хороший совет, спасибо, попробую и так. Потому что последние пару дней пытаюсь таки собрать все, кроме libc статически - лезет куча каких-то сторонних проблем.