Линковка не работает

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Janus
постоялец
Сообщения: 134
Зарегистрирован: 07.11.2005 16:06:49

Сообщение Janus »

Вот что я делаю:

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

program rsa;
{$LinkLib longmath.o}
procedure LongAdd(x, y, z: pointer); stdcall; external;

var
  x, y, z: integer;
begin
  x := 1; y := 1; z := 1;
  
  writeln(x, ';', y, ';', z);
  LongAdd(@x, @y, @z);
  writeln(x, ';', y, ';', z);
end.

А компоновщик мне выдает:
D:\FPC\bin\i386-Win32\ld.exe: cannot find -llongmath.o
rsa.pp(13,1) Error: Error while linking
Error: D:\FPC\bin\i386-Win32\ppc386.exe returned an error exitcode (normal if yo
u did not specify a source file to be compiled)

Во первых, почему он ищет -llongmath.o, если -l - команда?
Во вторых, а почему директива $Link ($L) не работает? Что она делает, если не линкует объектный модуль?

Сразу скажу, что пробовал линковать и elf и coff - нифига. Сам объектный файл в полном порядке, т.к. в g++ он прекрасно линкуется (в обоих форматах) и функция работает.

ОС win32
Аватара пользователя
STAKANOV
энтузиаст
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение STAKANOV »

$LinkLib - это для dll
Во первых, почему он ищет -llongmath.o, если -l - команда?

параметр передоваемый ld

для того чтобы узнать подробности в консольном окне (я про то которое некоторые называют ДОС-окном) набери
ld --help
и достигнешь просветления ;)

Во вторых, а почему директива $Link ($L) не работает?

а что выдает?
Janus
постоялец
Сообщения: 134
Зарегистрирован: 07.11.2005 16:06:49

Сообщение Janus »

А ничего не выдает. Просто не линкует. Если надо полностью, то вот:
Target OS: Win32 for i386
Compiling rsa.pp
Linking rsa.exe
rsa.o(.text+0xc0):rsa.pp: undefined reference to `P$RSA_LONGADD$POINTER$POINTER$
POINTER'
rsa.pp(13,1) Error: Error while linking
Error: D:\FPC\bin\i386-Win32\ppc386.exe returned an error exitcode (normal if yo
u did not specify a source file to be compiled)

Проще говоря, эта директива вообще ничего не делает.

А насчет $linkLib, так в том-то и вопрос, почему компоновщику передается неправильный параметр? Как мне слинковать obj файл к моей проге?
Аватара пользователя
STAKANOV
энтузиаст
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение STAKANOV »

А насчет $linkLib, так в том-то и вопрос, почему компоновщику передается неправильный параметр?

как раз правильно передает :)

Как мне слинковать obj файл к моей проге?

попробуй так
fpc rsa.pp longmath.o (не пробовал, но может съест)
или
fpc rsa.pp -klongmath.o (сработает 100%)

Проще говоря, эта директива вообще ничего не делает.

может тоже устарела, как-то они документацию не очень быстро правят :(
или файл(longmath.o) не там лежит
Janus
постоялец
Сообщения: 134
Зарегистрирован: 07.11.2005 16:06:49

Сообщение Janus »

Ага, теперь проблема такая:
rsa.o(.text+0xc0):rsa.pp: undefined reference to 'P$RSA_LONGADD$POINTER$POINTER$POINTER'

Тоже, что и при использовании $L. Значит, проблема не в $L, а в функции? Интересно, почему? В С++ работает, как ни странно.

Функция объявлена так:

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

public LongAdd as '_LongAdd@12'

В C++/С именно такое работает, а что в FPC?
Janus
постоялец
Сообщения: 134
Зарегистрирован: 07.11.2005 16:06:49

Сообщение Janus »

Все, решил проблему. Вот решение:

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

program rsa;
{$Link longmath.o}
procedure LongAdd(x, y, z: pointer); stdcall; external name '_LongAdd@12';

var
  x, y, z: integer;
begin
  x := 1; y := 1; z := 1;
  
  writeln(x, ';', y, ';', z);
  LongAdd(@x, @y, @z);
  writeln(x, ';', y, ';', z);
end.

А вот был asm-код, если кому интересно:

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

format elf

public LongAdd as '_LongAdd@12'

LongAdd:
  push ebp
  mov  ebp, esp
  add  ebp, 8

  mov  eax, [ebp]
  mov  ebx, [ebp + 4]
  mov  ecx, [ebp + 8]

  add  dword[eax], 1
  add  dword[ebx], 2
  add  dword[ecx], 3

  pop ebp
ret 12

Извиняюсь, что наводил панику, директива $L прекрасно работает :unsure:
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

К началу обсуждения не успел, но итоги подведу:
1. Для компоновки с .o используется {$LINK }, {$LINKLIB } используется для .a
2. Да-да, имена надо явно указывать, а если еще и в объектном файле идет линковка с FPC-шными подпрограммами, то см. public alias...
Janus
постоялец
Сообщения: 134
Зарегистрирован: 07.11.2005 16:06:49

Сообщение Janus »

Иван Шихалев писал(а): 1. Для компоновки с .o используется {$LINK }, {$LINKLIB } используется для .a

Теперь понятно, спасибо за разьяснение.
Ответить