LINUX.ORG.RU

Тупой вопрос про ключ компиляции

 , , ,


0

1

Есть хелло ворлд на си

#include <ncurses.h>

int main()
{
    initscr();
    curs_set(0);
    printw("Hello, World!");
    refresh();
    getch();
    endwin();
}

Компилирую так

cc -lncurses crap.c -o crap
/usr/bin/ld: /tmp/cch6cZ50.o: предупреждение: перемещение указывает на «stdscr» из раздела только для чтения «.text»
/usr/bin/ld: /tmp/cch6cZ50.o: в функции «main»:
crap.c:(.text+0x5): неопределённая ссылка на «initscr»
/usr/bin/ld: crap.c:(.text+0xf): неопределённая ссылка на «curs_set»
/usr/bin/ld: crap.c:(.text+0x20): неопределённая ссылка на «printw»
/usr/bin/ld: crap.c:(.text+0x27): неопределённая ссылка на «stdscr»
/usr/bin/ld: crap.c:(.text+0x2f): неопределённая ссылка на «wrefresh»
/usr/bin/ld: crap.c:(.text+0x36): неопределённая ссылка на «stdscr»
/usr/bin/ld: crap.c:(.text+0x3e): неопределённая ссылка на «wgetch»
/usr/bin/ld: crap.c:(.text+0x43): неопределённая ссылка на «endwin»
/usr/bin/ld: предупреждение: создаётся DT_TEXTREL в PIE
collect2: error: ld returned 1 exit status

Не собирается.

Компилирую так

cc crap.c -lncurses -o crap

Работает. Вопрос - почему? Почему от перестановки слагаемых ключа пример скомпилировался?

На предыдущей системе (9 демьян) можно было указывать ключ хоть где и всё компилировалось, но на десятом столкнулся вот с такой фигней.



Последнее исправление: xaizek (всего исправлений: 1)

Потому что линкер так работает. Сначала он должен получить список внешних символов, и только потом уже может начать их резолвить

annulen ★★★★★
()

https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

xmikex ★★★★
()

Вопрос - почему? Почему от перестановки слагаемых ключа пример скомпилировался?

Ответ есть там.

На предыдущей системе (9 демьян) можно было указывать ключ хоть где и всё компилировалось, но на десятом столкнулся вот с такой фигней.

Поменяли настройки тулчейна, видимо. Поведение разнится между дистрибутивами, потому что некоторые «исправляют» поведение незаметно для пользователей.

xaizek ★★★★★
()

Это ты ещё с весёлыми ошибками из-за порядка линковки не сталкивался.

EXL ★★★★★
()

У меня после обновления debian 10 -> 11 аналогично много чего перестало собраться. Переставил везде ключи -l в конец - починилось.

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

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Да, конечно, при обновлении с 10 на 11. Я в стартер посте попутал, указав, что с 9 на 10. У меня аналогично. Я собирал некоторые мелкие игрушки и утилитки с гитхаба. И раньше и на Убунту и Дебиане 10 делал мейк и всё работало. А сейчас поломалось и когда начал копать гугл, выяснилось , что на некоторых дистрибутивах решающее значение имеет то, где поставлен ключ. Меня это смутило, так как чуваки, которые писали свои мейк файлы явно не знали про такое.

nab_linux
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.