I'm trying to compile a simple library using FPC. Editing in XCode, but
for now just trying to fun the command line compiler directly.
I got an example form
http://courses.cs.vt.edu/~cs3304/FreePascal/doc/prog/node13.html that
is for Unix systems, but should work on Mac OS X (well, anyway I think
it should).
I think the error makes sense since the article above notes something
about putting the .so file (.dylib in Mac OS I assume) into /usr/lib.
I'm not allowed to do that without su, so I'd like to avoid it if
possible... seems like I should be able to have my whole project in one
directory in my home...
Trying to build I get this:
isaac-raways-computer:~/documents/projects/stonenotes Isaac$
/usr/local/bin/fpc ./subs.pas
Free Pascal Compiler version 2.2.0 [2007/08/30] for i386
Copyright (c) 1993-2007 by Florian Klaempfl
Target OS: Darwin for i386
Compiling ./subs.pas
Assembling subs
Linking libsubs.dylib
23 lines compiled, 0.2 sec
isaac-raways-computer:~/documents/projects/stonenotes Isaac$
/usr/local/bin/fpc ./testsubs.pas
Free Pascal Compiler version 2.2.0 [2007/08/30] for i386
Copyright (c) 1993-2007 by Florian Klaempfl
Target OS: Darwin for i386
Compiling ./testsubs.pas
Assembling testsubs
Linking testsubs
/usr/bin/ld: Undefined symbols:
_SubStr
Error: Error while linking
Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppc386 returned an error exitcode (normal if you
did not specify a source file to be compiled)
Here's the source:
{subs.pas}
library subs;
function SubStr(CString: PChar;FromPos,ToPos: Longint): PChar;
cdecl; export;
var
Length: Integer;
begin
Length := StrLen(CString);
SubStr := CString + Length;
if (FromPos > 0) and (ToPos >= FromPos) then
begin
if Length >= FromPos then
SubStr := CString + FromPos - 1;
if Length > ToPos then
CString[ToPos] := #0;
end;
end;
exports
SubStr;
end.
{testsubs.pas}
program testsubs;
function SubStr(const CString: PChar; FromPos, ToPos: longint): PChar;
cdecl; external 'subs.dylib';
var
s: PChar;
FromPos, ToPos: Integer;
begin
s := 'Test';
FromPos := 2;
ToPos := 3;
WriteLn(SubStr(s, FromPos, ToPos));
end.
I suspect the problem is a change (?) in the mangling that causes cdecl's
not to be mangled anymore. I don't know why this is. For now try specifying
the mangled name:
function xxx:yy; cdecl; export; [public, alias : '_substr'];
And similarly for the import:
function xxx:yy; cdecl; external 'some.dylib' name '_substr';
> function xxx:yy; cdecl; export; [public, alias : '_substr'];
>
> And similarly for the import:
>
> function xxx:yy; cdecl; external 'some.dylib' name '_substr';
The error is now
Compiling ./testsubs.pas
Assembling testsubs
Linking testsubs
/usr/bin/ld: Undefined symbols:
__substr
It appears that the entire library is not visible to the compiler, no
matter the symbol names.
No, but the import/export name mangling is asymmetrical unfortunately.
The correct way is:
export:
function xxx:yy; cdecl; export; [public, alias : '_substr'];
import:
function xxx:yy; cdecl; external 'some.dylib' name 'substr';
Jonas
DIdn't work. Error complains of missing _substr
> DIdn't work. Error complains of missing _substr
You're probably still missing a {$linklib some.dylib} statement in your
program, and possibly a wrong name in the exports section (I shouldn't
have copy/pasted the "public, alias" stuff you were given earlier; it
must not be used in the context of libraries because it's not for
exporting from a library, but only for internal visibility among object
files).
This works for me:
bigmac:~/fpc/test jonas$ cat tlib.pp
library tlib;
procedure test; cdecl;
begin
writeln('hello');
end;
exports
test name '_test';
begin
end.
bigmac:~/fpc/test jonas$ cat ulib.pp
{$linklib libtlib.dylib}
procedure test; cdecl; external 'libtlib.dylib';
begin
test;
end.
bigmac:~/fpc/test jonas$ ppcppc ulib
Free Pascal Compiler version 2.2.1 [2007/10/29] for powerpc
Copyright (c) 1993-2007 by Florian Klaempfl
Target OS: Darwin for PowerPC
Compiling ulib.pp
Assembling program
Linking ulib
bigmac:~/fpc/test jonas$ ppcppc tlib
Free Pascal Compiler version 2.2.1 [2007/10/29] for powerpc
Copyright (c) 1993-2007 by Florian Klaempfl
Target OS: Darwin for PowerPC
Compiling tlib.pp
./Assembling tlib
Linking libtlib.dylib
bigmac:~/fpc/test jonas$ ./ulib
hello
Jonas
> {$linklib libtlib.dylib}
Yep, this was the problem. I'm very new to this, I'm from Borland's
version of Pascal so I've never had to use {$linklib}.
Thanks for your help.