gcc -Wl,--as-needed ... (в различных дистрибутивах)

Модератор: Модераторы разделов

Ответить
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX
Контактная информация:

gcc -Wl,--as-needed ...

Сообщение Olej »

Собираем простейшую программу (рекомендую попробовать :laugh: )
... сложности порядка Hello World! - файл ex1.c

Код: Выделить всё

#include <stdio.h>
#include <math.h>

int main( void ) {
   float d = 9;
   printf( "%f\n", sqrt( d ) );
   return 0;
}

И надеемся, что уж с такой то программой мы справимся...
Ага ... ща-а-а-аз:

Код: Выделить всё

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ gcc -Wall -lm ex1.c -o ex1
/tmp/ccUuI8Fy.o: In function `main':
ex1.c:(.text+0x1a): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

Но стоит поменять местами опции gcc - и всё срабатывает:

Код: Выделить всё

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ gcc -Wall ex1.c -lm -o ex1

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ ./ex1
3.000000

И ещё одна особенность - если то же собирать как приложение C++:

Код: Выделить всё

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ g++ -lm -Wall ex1.c -o ex1++

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ ./ex1++
3.000000

Это не зависит а). ни от версии gcc, б). ни от разрядности системы 32/64...
А зависит это ... от используемого дистрибутива Linux! :unsure:
Это не возникает в: Fedora, CentOS, Debian ... и даже Rosa, Mageia.
Это возникает в: Ubuntu (со всеми их разнообразными Xubuntu, Lubuntu, Kubuntu...), Mint, Gentoo, ALT Linux.
Не знаю, каким ещё дистрибутивам это свойственно.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: gcc -Wl,--as-needed ...

Сообщение Bizdelnick »

Сейчас могу ошибаться, но вроде бы и в ROSA я на эти грабли наступал. Если дело не в версии gcc, то, вполне вероятно, в версии binutils или в том, используется ld.bfd или gold.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX
Контактная информация:

Re: gcc -Wl,--as-needed ...

Сообщение Olej »

("Olej") писал(а):А зависит это ... от используемого дистрибутива Linux!

Проблема, в общем, известная.
Интернет полнится криками: "Help!". :wacko: :unsure:
Но в ... организованной литературе (книги, статьи, ...) я никогда не встречал даже упоминания проблемы.
Но если с ней столкнуться и быть неготовым ... много крови может попить!
Особенно когда это сборка чужого проекта с готовым и объёмным Makraile (или ./configure), подготовленным в другой системе.
И уж не говоря про сборку с помощью CMake (вдруг кому такая глупость взбредёт), которую в таких случаях, предполагаю, или просто невозможно корректно описать в CMakeLists.txt, или очень искусственно нужно изощряться ... и долго. :wacko:

Происхождение, природа проблемы мне известна.
И её преодоление ... на 50-70% случаев - известны.
О подобном достаточно много писали и обсуждали ещё в AltLinux времён 2008 года и в некоторых Fedora того же периода.
http://www.linux.org.ru/forum/development/3104129
http://www.linux.org.ru/forum/development/2729273
https://bugzilla.altlinux.org/show_bug.cgi?id=15584
Причина объясняется как сборка ld (gcc) с желанием экономить до 5% времени работы :laugh: - вот здесь подробно. Там подробно описывается когда и почему это возникает...
В любом случае, технически достаточно просто записывать библиотеки в команде gcc позже, чем объектные файлы их использующие.
Но это не всегда возможно, особенно при сборке чужих проектов.

Проблема тянет за собой целый ряд вопросов:
- как точно определить (предполагать) что в вашем проекте (в вашей системе) это может выявиться?
- по каким параметрам сборки GCC? :

Код: Выделить всё

$ gcc -dumpspecs

- как её устранить ... в тех случаях, которые не подпадают под вот те 50-70% случаев?
- почему это не проявляется при использовании g++, C++ ?

Bizdelnick писал(а):
19.08.2016 17:52
Сейчас могу ошибаться, но вроде бы и в ROSA я на эти грабли наступал.

В одном и том же дистрибутиве, в текущей версии может не быть этой проблемы, а в следующей версии - есть ... и наоборот.

Bizdelnick писал(а):
19.08.2016 17:52
Если дело не в версии gcc,

Дело в тех параметрах spec, с которыми собирался проект GCC.
Но это не баг, это - фича ... дистрибьюторы считают и так и так, и собирают по-разному ... это как у Гуливера: остроконечники и тупоконечники. :drinks:

Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: gcc -Wl,--as-needed ...

Сообщение Bizdelnick »

debian jessie

% ls -l /usr/bin/ld lrwxrwxrwx 1 root root 6 авг 19 17:59 /usr/bin/ld -> ld.bfd % gcc -Wall -Wl,--as-needed -lm test.c -o test /tmp/ccNMyWUP.o: In function `main': test.c:(.text+0x17): undefined reference to `sqrt' collect2: error: ld returned 1 exit status % sudo ln -sf ld.gold /usr/bin/ld % gcc -Wall -Wl,--as-needed -lm test.c -o test % echo $? 0 %


Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX
Контактная информация:

Re: gcc -Wl,--as-needed ...

Сообщение Olej »

Bizdelnick писал(а):
19.08.2016 18:01

debian jessie

% ls -l /usr/bin/ld lrwxrwxrwx 1 root root 6 авг 19 17:59 /usr/bin/ld -> ld.bfd % gcc -Wall -Wl,--as-needed -lm test.c -o test /tmp/ccNMyWUP.o: In function `main': test.c:(.text+0x17): undefined reference to `sqrt' collect2: error: ld returned 1 exit status % sudo ln -sf ld.gold /usr/bin/ld % gcc -Wall -Wl,--as-needed -lm test.c -o test % echo $? 0 %


Это пример на использование -Wl,--as-needed.
Это совсем другое, чем то что я описал и спрашивал.
Хотя природа у них общая, происхождение: желание не связывать приложение с теми DLL, на которые нет ссылок из объектных файлов.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: gcc -Wl,--as-needed ...

Сообщение Bizdelnick »

Ну корень ошибки тот же самый: ld.bfd при использовании опции --as-needed чувствителен к порядку аргументов. Варианты объезда разные: использовать gold, не использовать --as-needed, всегда указывать библиотеки в конце командной строки.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX
Контактная информация:

Re: gcc -Wl,--as-needed ...

Сообщение Olej »

Bizdelnick писал(а):
19.08.2016 18:15
всегда указывать библиотеки в конце командной строки.

Это хороший способ... но только до тех пор, пока собирается собственный проект.
А вот когда собирается чужой проект (чуть объёмнее Hello World) - всё становится гораздо грустнее... :unsure:
Получается проект, который в одном Linux собирается, а в другом нет.

Опять же, если кто вздумает прописать сборку своего проекта CMake ... ну что-то такое в CMakeLists.txt типа:

Код: Выделить всё

execute_process(COMMAND net-snmp-config --agent-libs
                OUTPUT_VARIABLE LDOPT
               )
string(STRIP "${LDOPT}" CMAKE_EXE_LINKER_FLAGS)

Совершенно непредсказуемо куда там (в начало, в хвост) влепит CMake вот этот CMAKE_EXE_LINKER_FLAGS ... да и вообще неизвестно, что там и в каком порядке вернёт как опции линковщика net-snmp-config --agent-libs ... :wacko:
Спасибо сказали:
Аватара пользователя
RusWolf
Сообщения: 604
ОС: Arch Linux x64 на BTRFS

Re: gcc -Wl,--as-needed ...

Сообщение RusWolf »

Olej писал(а):
19.08.2016 17:46
Собираем простейшую программу (рекомендую попробовать :laugh: )
... сложности порядка Hello World! - файл ex1.c

Код: Выделить всё

#include <stdio.h>
#include <math.h>

int main( void ) {
   float d = 9;
   printf( "%f\n", sqrt( d ) );
   return 0;
}

И надеемся, что уж с такой то программой мы справимся...
Ага ... ща-а-а-аз:

Код: Выделить всё

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ gcc -Wall -lm ex1.c -o ex1
/tmp/ccUuI8Fy.o: In function `main':
ex1.c:(.text+0x1a): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

Но стоит поменять местами опции gcc - и всё срабатывает:

Код: Выделить всё

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ gcc -Wall ex1.c -lm -o ex1

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ ./ex1
3.000000

И ещё одна особенность - если то же собирать как приложение C++:

Код: Выделить всё

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ g++ -lm -Wall ex1.c -o ex1++

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ ./ex1++
3.000000

Это не зависит а). ни от версии gcc, б). ни от разрядности системы 32/64...
А зависит это ... от используемого дистрибутива Linux! :unsure:
Это не возникает в: Fedora, CentOS, Debian ... и даже Rosa, Mageia.
Это возникает в: Ubuntu (со всеми их разнообразными Xubuntu, Lubuntu, Kubuntu...), Mint, Gentoo, ALT Linux.
Не знаю, каким ещё дистрибутивам это свойственно.


Проверил ради интереса на своём Arch Linux:

Код: Выделить всё

[wolf@arch-wolf Sborka]$ gcc -Wall -lm ex1.c -o ex1
[wolf@arch-wolf Sborka]$ gcc -Wall ex1.c -lm -o ex1
[wolf@arch-wolf Sborka]$

Собирается в обоих вариантах.
С++ тоже без проблем.

Код: Выделить всё

[wolf@arch-wolf Sborka]$ ls -l /usr/bin/ld
-rwxr-xr-x 2 root root 995480 авг  6 13:42 /usr/bin/ld
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX
Контактная информация:

Re: gcc -Wl,--as-needed ...

Сообщение Olej »

Bizdelnick писал(а):
19.08.2016 18:15
Ну корень ошибки тот же самый: ld.bfd при использовании опции --as-needed чувствителен к порядку аргументов. Варианты объезда разные: использовать gold, не использовать --as-needed, всегда указывать библиотеки в конце командной строки.

Пакостность ситуации состоит в том, что в некоторых (и их немало) дистрибутивах ld.bfd чувствителен к порядку аргументов и без использования опции --as-needed, т.е. поумолчанию:

Код: Выделить всё

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ lsb_release -ircd
Distributor ID:    LinuxMint
Description:    Linux Mint 17.1 Rebecca
Release:    17.1
Codename:    rebecca

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ ls -l `which ld`
lrwxrwxrwx 1 root root 6 мая    2 23:41 /usr/bin/ld -> ld.bfd

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ gcc -Wall -lm ex1.c -o ex1
/tmp/cc8HtmX6.o: In function `main':
ex1.c:(.text+0x1a): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status


И зависит это от того, с какими параметрами дистрибьюторы собирают пакет gcc/ld.
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX
Контактная информация:

Re: gcc -Wl,--as-needed ...

Сообщение Olej »

RusWolf писал(а):
19.08.2016 19:15
Проверил ради интереса на своём Arch Linux:

Код: Выделить всё

[wolf@arch-wolf Sborka]$ gcc -Wall -lm ex1.c -o ex1
[wolf@arch-wolf Sborka]$ gcc -Wall ex1.c -lm -o ex1
[wolf@arch-wolf Sborka]$

Собирается в обоих вариантах.

Код: Выделить всё

[olej@comp-core-i7-ec8cfa as-needed]$ lsb_release -ircd
Distributor ID: ALT
Description:    ALT Linux starter kit (Hypericum)
Release:        n/a
Codename:       Hypericum

olej@nvidia ~/2016_WORK/in.WORK/as-needed $ uname -a
Linux nvidia 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:30:01 UTC 2014 i686 i686 i686 GNU/Linux

[olej@comp-core-i7-ec8cfa as-needed]$ gcc -Wall -lm ex1.c -o ex1
/tmp/.private/olej/ccKiC3Eh.o: In function `main':
ex1.c:(.text+0x1b): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status


RusWolf писал(а):
19.08.2016 19:15
С++ тоже без проблем.

А вот с C++ - это другая песня ... в C++ подобное не наблюдается.
Почему?
Спасибо сказали:
Аватара пользователя
RusWolf
Сообщения: 604
ОС: Arch Linux x64 на BTRFS

Re: gcc -Wl,--as-needed ...

Сообщение RusWolf »

Olej, по моему скромному мнению, этот вопрос надо задать сборщикам дистрибутива, в котором наблюдается данная проблема.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: gcc -Wl,--as-needed ...

Сообщение Bizdelnick »

Olej писал(а):
19.08.2016 19:21
А вот с C++ - это другая песня ... в C++ подобное не наблюдается.
Почему?

Полагаю, потому что к команде линковки g++ по умолчанию добавляет -lstdc++ с зависимостями (включая -lm), и делает это в конце командной строки. Если повторить эксперимент не с libm, а с другой библиотекой, от которой libstdc++ не зависит, должна вылезти та же ошибка (не проверял).
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX
Контактная информация:

Re: gcc -Wl,--as-needed ...

Сообщение Olej »

RusWolf писал(а):
19.08.2016 19:30
по моему скромному мнению, этот вопрос надо задать сборщикам дистрибутива, в котором наблюдается данная проблема.

Во-первых, этот эффект проявляется в доброй половине существующих дистрибутивов.
Каким сборщикам будем задавать вопрос? :rolleyes:

Во-воторых, это не глюк, это особенность поведения, которую вводят сознательно ... не баг, но фича. :drinks:
Вокруг этой особенности обсуждения идут давно, как минимум с 2008 года, и неизвестно что лучше.

В-третьих, вопрос не в том, кому вы станете задавать вопрос... :drinks: , а в том, как учесть и устранить такую особенность когда она мешает.


Bizdelnick писал(а):
19.08.2016 19:45
Olej писал(а):
19.08.2016 19:21
А вот с C++ - это другая песня ... в C++ подобное не наблюдается.
Почему?

Полагаю, потому что к команде линковки g++ по умолчанию добавляет -lstdc++ с зависимостями (включая -lm), и делает это в конце командной строки.

А я предполагаю (IMHO!) что g++ для компоновки, с некоторых пор, использует именно компоновщик ld.gold.
gold (компоновщик)
gold — это компоновщик для ELF файлов. Он стал официальным пакетом GNU[1] и был добавлен в binutils в марте 2008 года[2] [3] и был впервые выпущен в составе binutils версии 2.19. Gold был разработан Йеном Лэнсом Тейлором и небольшой командой из Google.[4] Мотивацией для написания gold было создание компоновщика, который является более быстрым, чем GNU linker, особенно для больших приложений, написанных на C++.

Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: gcc -Wl,--as-needed ...

Сообщение Bizdelnick »

Olej писал(а):
19.08.2016 22:30
А я предполагаю (IMHO!) что g++ для компоновки, с некоторых пор, использует именно компоновщик ld.gold.

Какой компоновщик будет использоваться — определяется на стадии конфигурирования gcc, и для всех языков он один и тот же (как правило /usr/bin/ld).
Проверил своё предположение на таком примере:

Код: Выделить всё

#include <iostream>
#include <cstring>
#include <pcre.h>

int main(int argc, char **argv) {
    pcre *re;
    const char *err;
    int erroffset;

    if (argc != 3) {
        std::cerr << "usage: " << argv[0] << " <PATTERN> <STRING>" << std::endl;
        return 1;
    }

    re = pcre_compile(argv[1], 0, &err, &erroffset, nullptr);
    if (! re) {
        std::cerr << erroffset << ": " << err << std::endl;
        return 2;
    }

    if (pcre_exec(re, nullptr, argv[2], strlen(argv[2]), 0, 0, nullptr, 0) != PCRE_ERROR_NOMATCH) {
        std::cout << argv[2] << std::endl;
    }
    return 0;
}

Shell

% g++ -std=gnu++11 -Wl,--as-needed -o test test.cpp -lpcre % g++ -std=gnu++11 -Wl,--as-needed -o test -lpcre test.cpp /tmp/ccvzxiAN.o: In function `main': test.cpp:(.text+0x5f): undefined reference to `pcre_compile' test.cpp:(.text+0xef): undefined reference to `pcre_exec' collect2: error: ld returned 1 exit status %

Ровно то же самое поведение.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Ответить