Напрочь отсутствует вызов функции sin

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

promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Напрочь отсутствует вызов функции sin

Сообщение promov »

Cогласитесь, код безупречен

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

#include <stdio.h>
#include <math.h>
int main (){
 double sin (double x);
 double a, b;
 a = 30.0;
 b = sin (a);
 return 0;
}

Тем не менее, не компилируется, выдаётся сообщение
:(.text+0x21): undefined reference to `sin'
collect2: ld returned 1 exit status
Это типа того, что необоснованное обращение к фукции sin, я перевёл.

Cамое-то интересное, что если строку 7 убрать, то всё компилируется и работает. Дело, значит, в этой строчке b = sin (a); Ума не приложу, что тут не так. Типы в левой и правой частях выражения совпадают, тип аргумента а соответствующий. Я уж и функцию sin объявил перед тем, как её вызвать (что, наверное, необязательно, коль скоро она есть в math.h), Всё бесполезно. Не в синтаксисе же дело... Надеюсь на помощь.

И вдогонку, может новички будут читать. Ориентир в том, как использовать функцию sin здесь. Предупреждаю: какой там язык- C или С++ разбирайтесь сами
http://www.cplusplus.com/reference/clibrary/cmath/sin.html
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
Аватара пользователя
Liksys
Сообщения: 2910

Re: Напрочь отсутствует вызов функции sin

Сообщение Liksys »

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

double sin (double x);
Убрать, во-первых, это прототип функции и нормальные люди его в main() не объявляют, во-вторых, он уже объявлен в math.h
А для компиляции с использованием математической либы надо указывать флаг -lm:

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

gcc -lm -o program program.c
Спасибо сказали:
promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Re: Напрочь отсутствует вызов функции sin

Сообщение promov »

Спасибо. Я образец взял из ссылки (см. пост номер 1). Там всё так же, как у меня, разве что добавлено pi. Или там другой язык- С++? И sin, конечно, не объявлена, это я уже сам на всякий случай.

Это введённая команда
gcc -lm -o program program.c

А это ответ
gcc: program.c: No such file or directory
Не могли бы Вы просто написать пример использования функции sin? Типа моего кода в посте номер 1? А я его буду использовать как образец в своих целях.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
Аватара пользователя
Red User
Сообщения: 229
ОС: Debian

Re: Напрочь отсутствует вызов функции sin

Сообщение Red User »

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

gcc: program.c: No such file or directory

Похоже на то, что файла program.c в директории, из которой запускается gcc, нету
А ведь когда-то не боялись мы программы любой,
И с одним лишь debug'ом выходили на бой,
И искусно написанный вирус встречали как брата
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Напрочь отсутствует вызов функции sin

Сообщение Uncle_Theodore »

promov писал(а):
04.10.2007 09:48
gcc -lm -o program program.c

А это ответ
gcc: program.c: No such file or directory

В этом примере вместо "program.c" надо подставить имя Вашего исходного файла. А вместо "program" -- имя исполняеемого файла, каким Вы его хотите видеть. Мы же не знаем, как Вы назвали свой исходник.
В остальном -- это и есть пример использования фнкции sin.
Спасибо сказали:
promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Re: Напрочь отсутствует вызов функции sin

Сообщение promov »

Друзья! То, что я написал, я озаглавил po1. Вот оно:

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

#include <stdio.h>
#include <math.h>
int main (){
double a, b;
a = 30.0;
b = sin (a);
printf ("Sin 30= %f\n", b);
return 0;
}


Потом там, где я команды на запуск ввожу, печатаю:

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

cc -lm -o po1 po1.c


Всё без замечанийй проходит. Потом вот это печатаю:

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

 ./a.out


Тоже без ошибок всё проходит, но никакого значения Sin, как мне хотелось бы, на экран не выводится. Потом то, что я написал, я изменил и стало оно таким:

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

#include <stdio.h>
int main (){
double a, b;
a = 30.0;
b = 7.9;
printf ("b= %f\n", b);
return 0;
}


Стало всё пчататься как предположено:

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


 b= 7.900000


Подхожу к кульминации. Теперь у меня снова первоначальный код, всё компилируется без ошибок, но по запуске в работу упорно выдаётся вышенаписанная строка (b= 7.900000), хотя у меня её уже в том коде и в помине нет, а он имеет первоначальный вид! (см. код номер один) Вот и вся проблема. Что делать, чтобы всё-таки печаталось значание синуса? Спасибо.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Напрочь отсутствует вызов функции sin

Сообщение drBatty »

promov писал(а):
28.11.2007 11:21

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

cc -lm -o po1 po1.c

сейчас по буквам объясню:
сс это вызов компилятора
-lm это ключ, для того, что-бы компилятор знал что такое sin()
-o po1 это тоже ключ, указывающей как компилятору назвать твою программу. Если его использовать, то программу надо запускать так: ./po1, если не использовать, компилятор назовёт a.out и запускать надо будет ./a.out, ты, видно, и так и так делал.
po1.c имя исходного текста твоей програмы. Можешь набрать less po1.c и почитать.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Re: Напрочь отсутствует вызов функции sin

Сообщение promov »

Cпасибо! Понял- не понял, главное,что работает, поле для размышлений есть, я теперь хоть с математическими функциями смогу работать, а то руками квадратный корень не наизвлекаешь!

P. S. И всё-таки: нужно же было придумать -lm... Видать мало было простого подключения #include <math.h>...
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Напрочь отсутствует вызов функции sin

Сообщение drBatty »

promov писал(а):
28.11.2007 12:16
руками квадратный корень не наизвлекаешь!
Почему?, можно. Бином Ньютона знаешь? Вот и считаешь: (1+x)^0.5. Можно по битам дихотомией(как процессор), но в си битовые операции очень слабые :(

promov писал(а):
28.11.2007 12:16
P. S. И всё-таки: нужно же было придумать -lm... Видать мало было простого подключения #include <math.h>...

дело в том, что в math.h написано только double sin(double);
Ну и 99% программ сейчас пишут без плавующей точки вообще. Сам выбери сотню твоих программ, и подумай, зачем в них синус? Вот по дефолту математика и не входит в набор библиотек по умолчанию.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Attila
Сообщения: 125
Статус: Тролль-Лѣсовичокъ
ОС: Свободная aka ArchLinux

Re: Напрочь отсутствует вызов функции sin

Сообщение Attila »

-lm это ключ, для того, что-бы компилятор знал что такое sin()


Насколько я понимаю, не компилятор, а линковщик. Компилятору хватает #include <math.h>?

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

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

double sin (double x );
float sin ( float x );
long double sin ( long double x );

в С же такого нет (так как противоречит языку).

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

double sin(double x);
float sinf(float x);
long double sinl(long double x);
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Напрочь отсутствует вызов функции sin

Сообщение drBatty »

Attila писал(а):
04.12.2007 16:38
Насколько я понимаю, не компилятор, а линковщик.

Да, конечно. Однако promov'а это сакральное знание только запутает ;)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

А у меня такая заморочка:
В тексте есть строки

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

#include <math.h>
#include <complex.h>

В ответ на

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

#gcc -lm wave_c.c

получаю:

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

/home/oleg/tmp/ccxJOTlv.o: In function `cpoint':
wave_c.c:(.text+0x5e): undefined reference to `sin'
wave_c.c:(.text+0x7d): undefined reference to `cos'
wave_c.c:(.text+0x11f): undefined reference to `cexp'
/home/oleg/tmp/ccxJOTlv.o: In function `main':
wave_c.c:(.text+0x2e2): undefined reference to `cabs'
collect2: выполнение ld завершилось с кодом возврата 1

Система - ALT linux 4.0 Desktop Personal - у меня стоит с неделю, gcc только что поставил с помощью Synaptic - вместе с пакетами от которых тот зависит.
Неужели что-то недоустановил???
Синусы обошёл флагом --fast-math, но вот комплексные функции не получается...
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Напрочь отсутствует вызов функции sin

Сообщение sergio »

ЗаГАДашно. Может некомпилирующийся исходник кинете?
Пока могу предложить проверить установленность пакета libc6-dev. Иба:

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

$ apt-file search 'lib/libm.' | uniq
avr-libc: usr/avr/lib/libm.a
dietlibc: usr/lib/diet/lib/libm.so
dietlibc-dev: usr/lib/diet/lib/libm.a
libc6: lib/libm.so.6
libc6-dev: usr/lib/libm.a
libc6-dev: usr/lib/libm.so
libnewlib-dev: usr/lib/newlib/libm.a
libnewlib-dev: usr/lib/newlib/libm.la
libnewlib-dev: usr/lib/newlib/libm.so
mingw32-runtime: usr/i586-mingw32msvc/lib/libm.a
newlib-m68hc1x: usr/m68hc11/lib/libm.a
pocketpc-gcc: usr/arm-wince-pe/lib/libm.a
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

В поте лица наваял исходник такого содержания:

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

#include <stdio.h>
#include <math.h>
main(){
printf("hello\n");
/*printf("%f\n",sin(0.1313));*/
}

Исправно выдаёт "hello".

Теперь убираю комментарии:

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

>gcc -lm test.c
/home/oleg/tmp/cchLskd1.o: In function `main':
test.c:(.text+0x31): undefined reference to `sin'
collect2: выполнение ld завершилось с кодом возврата 1


Пробую так:

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

>gcc -c test.c
>ld -lm test.o
ld: warning: cannot find entry symbol _start; defaulting to 0804823c
>./a.out
bash: ./a.out: Нет такого файла или каталога

Врёт!

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

>file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

Но не запускает.

Чегой-то нету у меня этого apt-file.
Попробовал так:

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

>find /usr -name "libm.*"
/usr/lib/libm.a
/usr/lib/debug/libm.a
/usr/lib/debug/libm.so.6
/usr/lib/debug/libm.so
/usr/lib/libm.so
>find / -mount -name "libm.*"
/lib/libm.so.6
Спасибо сказали:
Аватара пользователя
KiWi
Бывший модератор
Сообщения: 2521
Статус: статус, статус, статус

Re: Напрочь отсутствует вызов функции sin

Сообщение KiWi »

UID1313 писал(а):
22.05.2008 00:08

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

>gcc -c test.c
>ld -lm test.o
ld: warning: cannot find entry symbol _start; defaulting to 0804823c
>./a.out
bash: ./a.out: Нет такого файла или каталога

Гыыы, а передавать gcc -lm уже не понт?
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

А пост с начала прочитать тоже не понт?
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Напрочь отсутствует вызов функции sin

Сообщение sergio »

apt-file нету, значит нету. Я просто показал, в каких пакетах файлы живут. (Т.е. SinAPTic с не apt работает, видимо, тоже?.. (??) )

У меня так:

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

$ find /lib/ /usr/lib -regextype posix-egrep -regex '.*/libm[-.].*' -exec ls -ldF '{}' +
-rw-r--r-- 1 root root 141040 2008-01-19 15:14 /lib/libm-2.3.6.so
lrwxrwxrwx 1 root root     13 2008-02-22 20:02 /lib/libm.so.6 -> libm-2.3.6.so
-rw-r--r-- 1 root root 145136 2008-01-19 15:15 /lib/tls/i686/cmov/libm-2.3.6.so
lrwxrwxrwx 1 root root     13 2008-02-22 20:02 /lib/tls/i686/cmov/libm.so.6 -> libm-2.3.6.so
-rw-r--r-- 1 root root 145136 2008-01-19 15:14 /lib/tls/libm-2.3.6.so
lrwxrwxrwx 1 root root     13 2008-02-22 20:02 /lib/tls/libm.so.6 -> libm-2.3.6.so
-rw-r--r-- 1 root root 481574 2008-01-19 15:14 /usr/lib/libm.a
lrwxrwxrwx 1 root root     14 2008-02-22 20:02 /usr/lib/libm.so -> /lib/libm.so.6

Т.е. вроде бы примерно то же самое, либм.а лежит...

Ошибка с запуском - это такое дебильное сообщение на неправильную линковку, видимо, потому что у меня то же самое и:

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

$ ldd a.out
/usr/bin/ldd: line 117: ./a.out: No such file or directory

С ld надо иначе собираться, ему еще нужен стартап модуль.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

И у меня всё упирается в

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

-rw-r--r-- 1 root root 149308 Янв 25  2007 /lib/libm-2.5.so
-rw-r--r-- 1 root root  522040 Янв 25  2007 /usr/lib/libm.a

ldd выдаёт

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

>ldd a.out
        linux-gate.so.1 =>  (0xffffe000)
        libm.so.6 => /lib/libm.so.6 (0xb7f42000)
        libc.so.6 => /lib/libc.so.6 (0xb7e1c000)
        /usr/lib/libc.so.1 => /lib/ld-linux.so.2 (0x80000000)

С ld напрямую общаться как-то не доводилось, надо бы доки почитать...
Тут или gcc чего-то не то передаёт, или сам ld не там ищет...
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Напрочь отсутствует вызов функции sin

Сообщение sergio »

Коли слинковано все верно (ldd a.out - это a.out полученный при сборке gcc -lm test.c с закомментированным sin(), как я понимаю?), пути совпадают, то вроде бы выходит, что ld не находит sin в libm.
Ну можно сделать еще

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

$ readelf -s /lib/libm-2.3.6.so | egrep '\Wsin'
    84: 00017ef0    38 FUNC    WEAK   DEFAULT   12 sinl@@GLIBC_2.0
   117: 0000aff0    58 FUNC    WEAK   DEFAULT   12 sincos@@GLIBC_2.1
   181: 000095d0    38 FUNC    WEAK   DEFAULT   12 sin@@GLIBC_2.0
   193: 0000aab0   129 FUNC    WEAK   DEFAULT   12 sinh@@GLIBC_2.0
   233: 00019930    58 FUNC    WEAK   DEFAULT   12 sincosl@@GLIBC_2.1
   257: 00012230    58 FUNC    WEAK   DEFAULT   12 sincosf@@GLIBC_2.1
   274: 00010990    38 FUNC    WEAK   DEFAULT   12 sinf@@GLIBC_2.0
   298: 000193e0   139 FUNC    WEAK   DEFAULT   12 sinhl@@GLIBC_2.0
   320: 00011e10   127 FUNC    WEAK   DEFAULT   12 sinhf@@GLIBC_2.0

(путь вашей либы подставьте) но это уже от балды, тут надо или спецов по сборке мучить, или на удачу удалить все пакеты относящиеся к вопросу поставить снова и если не поможет идти жаловаться дистростроителю. :)

А для сборки через ld надо передавать стартап модуль (который содержит код той самой _start, которая обеспечивает инициализацию-развертывание чего нужно для конкретного языка и дальше вызывает процедуры программы, main в случае си/си+ соотв-но. Когда сборкой управляет gcc он это делает - для си. А g++ для сиплюс свое.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

С libm у меня всё в порядке - программы, которые я выпекал в SUSE - и которую я променял на ALT - прекрасно работают и здесь.
Всю жизнь думал, что пишу программы с именем main - оказалось, что пишу функции, которые линкер к чему-то цепляет.
У меня это что-то именуется /usr/lib/crt1.o

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

>ld  /usr/lib/crt1.o  test.o
/usr/lib/crt1.o: In function `_start':
(.text+0xc): undefined reference to `__libc_csu_fini'
/usr/lib/crt1.o: In function `_start':
(.text+0x11): undefined reference to `__libc_csu_init'
/usr/lib/crt1.o: In function `_start':
(.text+0x1d): undefined reference to `__libc_start_main'
test.o: In function `main':
test.c:(.text+0x1a): undefined reference to `puts'
test.c:(.text+0x31): undefined reference to `sin'
test.c:(.text+0x48): undefined reference to `printf'

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

>ld  /usr/lib/crt1.o  -lm test.o
/usr/lib/crt1.o: In function `_start':
(.text+0xc): undefined reference to `__libc_csu_fini'
/usr/lib/crt1.o: In function `_start':
(.text+0x11): undefined reference to `__libc_csu_init'

Ясно, что линкер работает исправно, и если ему указать, где искать __libc_csu_fini и __libc_csu_init, то я получу работающую программу. (кстати, никто не знает - где они?)
По всей видимости, у меня gcc по какой-то причине отказывается передавать флаг -lm линкеру...
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

Заставил я его работать.
Вспомнил, что gcc принимает файлы с *.o и отправил:

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

>gcc -v -lm test.o
Используются внутренние спецификации.
Целевая архитектура: i586-alt-linux
Параметры конфигурации: ../configure --host=i586-alt-linux --build=i586-alt-linux --target=i586-alt-linux --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib --libexecdir=/usr/libexec --localstatedir=/var/lib --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info --disable-dependency-tracking --without-included-gettext --program-suffix=-4.1 --with-slibdir=/lib --enable-shared --enable-__cxa_atexit --enable-threads=posix --enable-checking=release --with-system-zlib --without-included-gettext --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,treelang,java,ada --enable-java-awt=gtk --disable-plugin --with-native-libdir=/usr/lib/gcj-4.1 --enable-libgcj-multi
file --with-cpu=i586 --with-arch=i586 --with-tune=pentium4
Модель многопотоковости: posix
gcc версия 4.1.1 20070105 (ALT Linux, build 4.1.1-alt11)
 /usr/libexec/gcc/i586-alt-linux/4.1.1/collect2 --as-needed --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crt1.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crti.o /usr/lib/gcc/i586-alt-linux/4.1.1/crtbegin.o -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1/../../.. -lm test.o -lgcc --as-needed -lgcc_s -lc -lgcc --as-needed -lgcc_s /usr/lib/gcc/i586-alt-linux/4.1.1/crtend.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crtn.o
 test.o: In function `main':
 test.c:(.text+0x31): undefined reference to `sin'
 collect2: выполнение ld завершилось с кодом возврата 1

Заинтересовала строчка:

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

/usr/libexec/gcc/i586-alt-linux/4.1.1/collect2 --as-needed --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crt1.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crti.o /usr/lib/gcc/i586-alt-linux/4.1.1/crtbegin.o -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1/../../.. -lm test.o -lgcc --as-needed -lgcc_s -lc -lgcc --as-needed -lgcc_s /usr/lib/gcc/i586-alt-linux/4.1.1/crtend.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crtn.o

Что это за зверь за такой - collect2 - не знаю, но ключи похожи на ключи от ld.
Недолго думая и заменил его на ld:

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

>ld --as-needed --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crt1.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crti.o /usr/lib/gcc/i586-alt-linux/4.1.1/crtbegin.o -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1/../../.. -lm test.o -lgcc --as-needed -lgcc_s -lc -lgcc --as-needed -lgcc_s /usr/lib/gcc/i586-alt-linux/4.1.1/crtend.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crtn.o
test.o: In function `main':
test.c:(.text+0x31): undefined reference to `sin'

Хотя ключ -lm присутствует.
Ещё почесал репу: не понравилось --as-needed.
Убрал:

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

>ld  --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crt1.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crti.o /usr/lib/gcc/i586-alt-linux/4.1.1/crtbegin.o -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1/../../.. -lm test.o -lgcc -lgcc_s -lc -lgcc -lgcc_s /usr/lib/gcc/i586-alt-linux/4.1.1/crtend.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crtn.o
>./a.out
hello
0.130923

Ура!!! Заработало!
Хотя что вся эта хрень значит, так и не понял.

Пошёл читать документацию.
Спасибо сказали:
un-defined
Сообщения: 145
ОС: Kubuntu, Gentoo

Re: Напрочь отсутствует вызов функции sin

Сообщение un-defined »

Вот это мощный способ, да уж :)

Я кстати как-то сталкивался с тем, что линкеру бывает важна последовательность подключения библиотек. Т.е. если написать не "gcc -lm test.c", а "gcc test.c -o output -lm" - что будет?:)
Don`t try - just do or do not ©Master Joda
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

А у меня ни так - ни так не получается.
По-моему тут альтовцы намудрили.
Из man ld:
--as-needed
--no-as-needed
This option affects ELF DT_NEEDED tags for dynamic libraries men-
tioned on the command line after the --as-needed option. Normally,
the linker will add a DT_NEEDED tag for each dynamic library men-
tioned on the command line, regardless of whether the library is
actually needed. --as-needed causes DT_NEEDED tags to only be
emitted for libraries that satisfy some symbol reference from regu-
lar objects which is undefined at the point that the library was
linked. --no-as-needed restores the default behaviour.

В английском не силён, но так понял, что тэг DT_NEEDED позарез нужен libm , чтобы линкер правильно её привязал.
Если непосредственно перед -lm воткнуть --no-as-needed (в ld - не в gcc), то всё тоже прекрасно линкуется - со всеми --as-needed'ами.

Где там gcc конфигурируется?
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

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

>gcc test.o -o outfile -lm
test.o: In function `main':
test.c:(.text+0x31): undefined reference to `sin'
collect2: выполнение ld завершилось с кодом возврата 1
>gcc test.o -lm -o outfile
>outfile
hello
0.130923

:wacko: :wacko: :wacko:
Я спать пошёл.
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Напрочь отсутствует вызов функции sin

Сообщение sergio »

Честно говоря, всегда указывал -о и библиотеки до файлов, потому как оно так читается лучше, редактировать удобнее и ваще по канону опции вперед файлов. ;) Но вот попробовал:

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

sergio@mirkwood:~/tmp$ gcc -o ttt -lm t.o
sergio@mirkwood:~/tmp$ ./ttt
hello
0.130923
sergio@mirkwood:~/tmp$ rm ttt
sergio@mirkwood:~/tmp$ gcc -o ttt t.o -lm
sergio@mirkwood:~/tmp$ ./ttt
hello
0.130923
sergio@mirkwood:~/tmp$ rm ttt
sergio@mirkwood:~/tmp$ gcc t.o -o ttt -lm
sergio@mirkwood:~/tmp$ ./ttt
hello
0.130923
sergio@mirkwood:~/tmp$ rm ttt
sergio@mirkwood:~/tmp$ gcc -lm -o ttt t.o
sergio@mirkwood:~/tmp$ ./ttt
hello
0.130923

Ага, вот через десять минут всплыла в памяти еще причина, почему либы вперед указываю (глубоко засела, хехе): где-то попадалось, что порядок либ/файлов компилятору важен и т.д. - по-моему это было где-то в доках по старому борланду. Давно было. ;) Словом, надо перечитывать доки по компилеру. Но как минимум - различие в поведении вашего и моего - на лицо. Да и отказ собираться в виде gcc -lm file.c тоже явный непорядок.
По-моему тут альтовцы намудрили.

По-моему, это мягко сказано. :laugh: Стоит им об этом намекнуть, думаю. ;)
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

А я прописываю в .bashrc alias gcc='gcc -lm' (на время этих экспериментов ещё не успел - забыл), потому как мои программки - это математические вычисления. До этого дистрибутива всегда работало.

Из man ld:

ld -o <output> /lib/crt0.o hello.o -lc

This tells ld to produce a file called output as the result of linking
the file "/lib/crt0.o" with "hello.o" and the library "libc.a", which
will come from the standard search directories. (See the discussion of
the -l option below.)

Some of the command-line options to ld may be specified at any point in
the command line. However, options which refer to files, such as -l or
-T, cause the file to be read at the point at which the option appears
in the command line, relative to the object files and other file
options.



То есть, если следовать этому мануалу, то самое законное место для -l - это сразу после файла, к которому эта библиотека должна быть привязана. Но это для линкера, а не для компилятора.
У меня gcc ставит линкеру -lm сразу после нужного файла только в том случае, если я её пишу её сразу после test.o. Тогда работает. Если перед, или после, но между ними ещё какя-то опция - gcc передаёт линкеру -lm перед файлом. И тогда не работает.
Это справедливо, если я отправляю объектные файлы. Если же исходные тексты - то тут опять не всё однозначно:

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

>gcc test.c -lm -O
 /home/oleg/tmp/ccG7HVJk.o: In function `main':
test.c:(.text+0x29): undefined reference to `sin'
collect2: выполнение ld завершилось с кодом возврата 1
>gcc -O test.c -lm
>./a.out
hello
0.130923

Но: (извиняюсь за длину - смотрите первую и последнюю строчки)

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

>gcc -O test.c -lm -v
Используются внутренние спецификации.
Целевая архитектура: i586-alt-linux
Параметры конфигурации: ../configure --host=i586-alt-linux --build=i586-alt-linux --target=i586-alt -linux --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib --libexecdir=/usr/libexec --localstat edir=/var/lib --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info --disable -dependency-tracking --without-included-gettext --program-suffix=-4.1 --with-slibdir=/lib --enable-shared --enable-__cxa_atexit --enable-threads=posix --enable-checking=release --with-system-zlib --without-included-gettext --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,treelang,java,ada --enable-java-awt=gtk --disable-plugin --with-native-libdir=/usr/lib/gcj-4.1 --enable-libgcj-multifile --with-cpu=i586 --with-arch=i586 --with-tune=pentium4
Модель многопотоковости: posix
gcc версия 4.1.1 20070105 (ALT Linux, build 4.1.1-alt11)
 /usr/libexec/gcc/i586-alt-linux/4.1.1/cc1 -D_FORTIFY_SOURCE=2 -quiet -v test.c -fstack-protector -quiet -dumpbase test.c -march=i586 -auxbase test -O -version -o /home/oleg/tmp/ccj8OGxv.s
 несуществующий каталог "/usr/lib/gcc/i586-alt-linux/4.1.1/../../../../i586-alt-linux/include" проигнорирован
порядок поиска для #include "...":
порядок поиска для #include <...>:
/usr/local/include
/usr/lib/gcc/i586-alt-linux/4.1.1/include
/usr/include
конец списка поиска
GNU C версия 4.1.1 20070105 (ALT Linux, build 4.1.1-alt11) (i586-alt-linux)
скомпилировано GNU C версия 4.1.1 20070105 (ALT Linux, build 4.1.1-alt11).
эвристики GGC: --param ggc-min-expand=64 --param ggc-min-heapsize=64547
Compiler executable checksum: 47b67d78d2d55d8e46d637540ceaca3e
as -V -Qy -o /home/oleg/tmp/cc8F7hxV.o /home/oleg/tmp/ccj8OGxv.s
 GNU assembler version 2.17.50.0.6 (i586-alt-linux) using BFD version 2.17.50.0.6 20061020
/usr/libexec/gcc/i586-alt-linux/4.1.1/collect2 --as-needed --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crt1.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crti.o /usr/lib/gcc/i586-alt-linux/4.1.1/crtbegin.o -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1/../../.. -lm /home/oleg/tmp/cc8F7hxV.o -lgcc --as-needed -lgcc_s -lc -lgcc --as-needed -lgcc_s /usr/lib/gcc/i586-alt-linux/4.1.1/crtend.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crtn.o
/home/oleg/tmp/cc8F7hxV.o: In function `main':
test.c:(.text+0x29): undefined reference to `sin'
collect2: выполнение ld завершилось с кодом возврата 1

В многостадийном процессе превращения текстов в программы компилятор тасует опции как хочет.
Нормальным это, конечно не назовёшь.
И опять-таки по поводу опции --as-needed для линкера (я так думаю, что она придумана для повышения быстродействия). -lm можно ставить в любом месте списка опций - я ставил и на первом и на последнем месте. Всё линкуется, если на -lm не воздействует --as-needed. Действие этой опции прекращается за --no-as-needed или за объектным файлом, к которому данная библиотека должна быть привязана.
В общем, чтобы найти конкретного виновника этого безобразия нужно учинять следственную комиссию.

Эксперименты мне уже поднадоели, пойду-ка я подумаю, как мне от этого безобразия избавиться.
Спасибо сказали:
UID1313
Сообщения: 10
ОС: ALT 4.0 Desktop

Re: Напрочь отсутствует вызов функции sin

Сообщение UID1313 »

Про каноны:
По-моему, самый логичный порядок опций линкера таков:
ld [опции] [-lбиблиотека ...] файл [-lбиблиотека ...] [файл [-lбиблиотека ...] ...]
То есть, сначала опции, потом библиотеки для всех файлов, и после каждого файла - библиотеки конкретно для этого файла. Порядок поиска функций: библиотеки для конкретного файла, для всех файлов, стандартные.
Такого же порядка следует придерживаться и для gcc. И для пущего удобства юзеру в конце можно добавлять ещё опции - ну, там, отладки, оптимизации - не гонять же курсор через всю строчку...
Конкретно в моей сборке, имхо, имеет место быть комбинация двух дефектов:
Во-первых библиотеки для всех файлов не подключаются.
Тексты:

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

     test.c:
=============================================
#include <stdio.h>
#include <math.h>
void subpr();
main(){
printf("hello\n");
printf("%f\n",sin(0.1313));
subpr();
}
=============================================
     test2.c:
=============================================
#include <stdio.h>
#include <math.h>
void subpr()
{
printf("Hi,%f\n",cos(0.1313));
}
=============================================


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

>gcc -lm test.c test2.c
/home/oleg/tmp/ccEAsbpm.o: In function `main':
test.c:(.text+0x31): undefined reference to `sin'
/home/oleg/tmp/ccQ5GCZp.o: In function `subpr':
test2.c:(.text+0x16): undefined reference to `cos'
collect2: выполнение ld завершилось с кодом возврата 1
>gcc test.c -lm test2.c
/home/oleg/tmp/ccCt4yja.o: In function `subpr':
test2.c:(.text+0x16): undefined reference to `cos'
collect2: выполнение ld завершилось с кодом возврата 1
>gcc test.c test2.c -lm
/home/oleg/tmp/ccjz0jrj.o: In function `main':
test.c:(.text+0x31): undefined reference to `sin'
collect2: выполнение ld завершилось с кодом возврата 1
>gcc test.c -lm test2.c -lm
hello
0.130923
Hi,0.991393

То есть, для правильной сборки я должен указывать -lm после каждого файла, содержащего математические функции.

Второй дефект - это глюк, причём нестабильный и без первого дефекта практически непроявляющийся
.
Если я добавляю опции в конце строки, то -lбиблиотека компилятор воспринимает как общую опцию и переносит её вперёд файлов текста, и она не работает (у меня - не у всех). Это само по себе не глюк - глюк в том, что компилятор не может отличить, относится ли эта опция к файлу перед ней или к общему списку опций. Здесь он ведёт себя как бог на душу положит - кажется, это зависит то ли от системных часов, то ли от энтропийного пула, то ли от фазы луны...

В общем, компилировать программки я смогу - правда, без прежних удобств...

Спасибо всем за помощь.
:) :)
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Напрочь отсутствует вызов функции sin

Сообщение sergio »

Some of the command-line options to ld may be specified at any point in
the command line. However, options which refer to files, such as -l or
-T, cause the file to be read at the point at which the option appears
in the command line, relative to the object files and other file
options.

То есть, если следовать этому мануалу, то самое законное место для -l - это сразу после файла, к которому эта библиотека должна быть привязана.

Ирония в том, что я следстивие из этого текста вижу с точностью до наоборот: библиотека д.б. указано ДО файла, который на нее ссылается. А уж прямо перед файлом, или где-то далеко впереди - не суть. Иба:
cause the file to be read at the point at which the option appears in the command line, relative to the object file

т.е. имена, экспортируемые библиотекой, становятся видны в точке указания ее в опции -l. Соотв-но, если она не указана где-то до объектника, то компилятор спотыкается, потому что жаждамые объектником символы он еще не видел и не знает, где их искать. Далее, следствие два, что зависящие друг от друга библиотеки должны появляться также в неком порядке, а взаимные ссылки файлов друг на друга просто не могут быть разрешены. Поэтому как бы напрашивается, что линкер должен сперва собрать все символы из всех переданных объектов, а затем уже озаботиться обработкой запросов кому-чего и их связкой. Ну или, другой вариант описания логики, проходить по списку файлов раз за разом, пока все не свяжется. В доках по борланду (уже пятому, что ли) это вроде попадалось под названием "incremental linkage" - в том ключе, что раньше такого не было, а теперь они сделали. ))


UID1313 писал(а):
24.05.2008 20:44
Про каноны:
По-моему, самый логичный порядок опций линкера таков:
ld [опции] [-lбиблиотека ...] файл [-lбиблиотека ...] [файл [-lбиблиотека ...] ...]
То есть, сначала опции, потом библиотеки для всех файлов, и после каждого файла - библиотеки конкретно для этого файла. Порядок поиска функций: библиотеки для конкретного файла, для всех файлов, стандартные.

Пессимист носит штаны на ремне и подтяжках ))) , а здесь бы лучше имхо как раз получать ошибку при возможных "неясностях", логичнее иметь все символы либо в одном приоритете. Если больше одного адреса у символа - то неоднозначность. Иначе растут риски малопонятных ошибок при изменении зависимостей объектников от библиотек. Ваш объектник использовал некую фу-ю из "общей" либы, теперь вы добавили в него зависимость от необщей либы и ее в опции, а в этой необщий либе обнаружилась фу-я с тем же именем, что в общей, и новая сборка прошла с вызовом не той функции, что в прошлый раз. ;) А компилер вас не предупредит, если эта необщая либа имеет несколько хедеров, и вы инклудили не тот, где конфликтная функция была объявлена...


Спасибо всем за помощь.

Познавательную вы разборку проделали. :)
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали: