PDA

View Full Version : MacOS X dylib suppport...



savage
05-01-2005, 10:39 PM
A quick question for FreePascal users on MacOS X. Does the latest compiler, 1.9.6, link to *.dylib on MacOS X or is static linking the only possibility?

Chris Burkhardt
07-01-2005, 05:19 PM
Hi, sorry I haven't answered this yet. I've barely used FPC on my Mac, so I can't say off the top of my head. But as far as I know it uses the standard linker (same as gcc), so I assume it does dynamic linking to .dylib and frameworks. I'll test it for sure this evening and let you know... that is something I need to know myself before planning on using FreePascal on a large project anyay...

savage
07-01-2005, 06:31 PM
I look forward to your feedback.

Chris Burkhardt
08-01-2005, 08:09 PM
Affirmative: I can dynamically link to .dylib libraries with FreePascal by either using the {$linklib} directive, or by passing the name of the library to the linker with the -k option (example: fpc -k"-framework Carbon" test.pas).

Here is in example just for fun of creating a .dylib in C, and then linking to it in Pascal and calling a function. (I'm using Mac OS X 10.3, by the way)

/* This file is called libtest.c */
int test()
{
return 25;
}
/* EOF */

---

{This file is called dylibtest.pas}
program dylibtest;
{$linklib test} {link to our .dylib}

Function test : longint; cdecl; external;

begin
writeln (test);
end.
{EOF}

---

And now compile the c file to a .dylib:

cris$ gcc -dynamiclib -o libtest.dylib libtest.c -install_name /usr/local/lib/libtest.dylib
Install the library to /usr/local/lib, then compile the pascal source:

cris$ fpc dylibtest.pas
Then run the brand new Mach-O, dynamically linked executable:

cris$ ./dylibtest
25
And we get 25 printed on the screen just like we should!

So that's a good sign at least, though simple. I don't know very much about linking and the complications that can arise... I'm downloading JEDI-SDL now, and hope I can get that working :)

savage
08-01-2005, 11:08 PM
Hi Chris,
This certainly sounds promising. I have a question...
Instead of using {$linklib} directive shouldn't it also work with the external keyword? Or are you saying that the external keyword ie...

procedure SomeProcedure; cdecl; external 'libSDL-1.2.0.dylib';

does not work on MacOS?

You probably know this already, but I will mention it just in case, If you plan to play with JEDI-SDL, don't forget to install SDL first. The relevant packages are...
http://www.libsdl.org/release/SDL-1.2.8.pkg.tar.gz for runtime
or
http://www.libsdl.org/release/SDL-devel-1.2.8.pkg.tar.gz for the development package ( Project Builder + XCode )
It looks like the the other SDL libararies ( SDL_image, SDL_Mixer etc ) need to be built.

Chris Burkhardt
09-01-2005, 01:23 AM
> Or are you saying that the external keyword does not work does not work on MacOS?

Unfortunately, that seems to be the case. If I remove the {$linklib} directive and use external 'libname', I get undefined symbol errors on link... like it can't find the library :( .

I'm also having problem using exported variables from a linked library.

I'm hoping it something I did wrong creating my libtest.dylib. I'll try linking to and using a REAL library, like SDL, when I have time. I do already have the SDL and SDL_Mixer frameworks installed on my Mac, thanks. I'm opening up my iBook and replacing the harddrive this weekend, but if I manage to do that without permanently damaging my computer, then I'll try to get the JEDI-SDL demos compiled in earnest.

(by the way, if I can't get the current version of FreePascal to do what I want... do you know if the JEDI-SDL interfaces compile with GNU Pascal?)

Thanks,
- Chris

savage
09-01-2005, 09:04 AM
Yes the interfaces do have Gnu Pascal compatability code in there, but it is untested with the latest Gnu Pascal compilers. It definately used to work.

When you have a moment, can you confirm what the names of your libSDL*.dylibs are?

Chris Burkhardt
09-01-2005, 09:30 PM
> When you have a moment, can you confirm what the names of your libSDL*.dylibs are?

It is in a framework called SDL.framework (located at /Library/Frameworks/SDL.framework/ or ~/Library/Frameworks/SDL.framework/). The actual executable is named SDL (no extension) and is located at: /Library/Frameworks/SDL.framework/Versions/A/SDL

does that help?

Anonymous
09-01-2005, 09:48 PM
FPC can link against dylibs, it's what the rtl does since Darwin (the OS core of MacOSX) has no kernel interface like linux which can be used without libc.

Regarding MacOSX and SDL have a look at:
http://www.freepascal.org/wiki/index.php/FPC_and_SDL#Mac_OS_X_specific_issues

If you've question about it, ask on the fpc-mailing-lists, it will be probably read by someone who knows more about MacOSX than me :)

FPK
09-01-2005, 09:50 PM
FPC can link against dylibs, it's what the rtl does since Darwin (the OS core of MacOSX) has no kernel interface like linux which can be used without libc.

Regarding MacOSX and SDL have a look at:
http://www.freepascal.org/wiki/index.php/FPC_and_SDL#Mac_OS_X_specific_issues

If you've question about it, ask on the fpc-mailing-lists, it will be probably read by someone who knows more about MacOSX than me :)

Chris Burkhardt
09-01-2005, 10:31 PM
Thanks, FPK! Reading that Wiki also confirmed my experiences that linking to external variables does not yet work on Mac OS X.

savage
09-01-2005, 10:34 PM
FPC can link against dylibs

Yes, but why does it have to use the {$linklib} directive instead of the usual external keyword? If it cannot use the external keyword, then it seem the MacOS X version of the compiler is either buggy or incomplete.


Regarding MacOSX and SDL have a look at:

Yes I am aware of the work arounds, but I have to ask, why do we need to fake the SDL_Main when this is not required on Win32, Linux or even FreeBSD, which I thought MacOS X was based on.

Please enlighten me so I can better understand the nuances of MacOS X.

FPK
09-01-2005, 10:57 PM
FPC can link against dylibs

Yes, but why does it have to use the {$linklib} directive instead of the usual external keyword? If it cannot use the external keyword, then it seem the MacOS X version of the compiler is either buggy or incomplete.


IIRC, the external 'lib' support was removed because on MacOSX the order how the libs are passed to the linker is important. So you should collect all linklib statements at one place to get them in the correct order instead of letting the compiler mess around with it.

If you don't like this behaviour, activate the code in fpc/compiler/systems/t_bsd.pas line 100 :)




Regarding MacOSX and SDL have a look at:

Yes I am aware of the work arounds, but I have to ask, why do we need to fake the SDL_Main when this is not required on Win32, Linux or even FreeBSD, which I thought MacOS X was based on.

Please enlighten me so I can better understand the nuances of MacOS X.

From the wiki:

For Mac OS X, this is not possible because there this main function is written in Objective C.

Rewriting a C function in pascal and wrapping it is probably easy. However, to rewrite an Objective C function is hard because interfacing from Pascal to Objective C is not possible, so you can't call the Objective C functions in the converted code.

savage
09-01-2005, 11:16 PM
It is in a framework called SDL.framework

Christ, does this framework then create the libSDL.dylib file or does it create a libSDL-1.2.0.dylib file, or does the {$linklib SDL} link to the frameworks and totally forget about the *.dylib file?

Chris Burkhardt
09-01-2005, 11:49 PM
Chris, does this framework then create the libSDL.dylib file or does it create a libSDL-1.2.0.dylib file?
Frameworks on Mac OS X are really just directories which contain libraries, headers, and other resources. The SDL.framework contains the actual library, which is simply named SDL (not libSDL.dylib or anything).

I believe this can be ]external 'libname'[/b] style... even though the Mac version of fpc doesn't resolve libraries using the external keyword, it will still find the library and all it's symbols since it is passed to the linker using the -k option. Makes for a longer command line command, with lots of -k's, but still easy enough.

That said, I am having trouble compiling the JEDI-SDL interfaces... I think I'll start another thread about that...

Let me know if you need me to clarify. I'm somewhat a novice to all this but am happy to help if I can.

savage
10-01-2005, 12:00 AM
Hi Chris,
Please start a new thread about the JEDI-SDL issues in the JEDI-SDL sub-forum. I am in the process of trying to add the definitive touches for MacOS support so any help in these stages would be most welcome.

One last question to do with the framework. In my sdl.pas, if I add the line {$linklib sdl} where the darwin declaration is, and leave everything else as is, will that be enough to link in the framework?

Chris Burkhardt
10-01-2005, 02:36 AM
I'm afraid not. For two reasons:

1. /Library/Framework/SDL.framework is not in fpc's default search path, so it must be added with -Fl

Even then...

2. fpc expects libraries to be named lib*.dylib. Libraries in Frameworks have neither the "lib" prefix nor the ".dylib" suffix.

One solution is to create a symlink /usr/local/lib/libsdl.dylib pointing to /Library/Frameworks/SDL.framework/Versions/Current/SDL. (With that symbolic link then simply having {$linklib sdl} will link in the library with no additional changes or compiler flags, but otherwise not :? )

FPK
10-01-2005, 01:23 PM
I recommend that you post your problems on the FPC mailing list, there are also the developers of the MacOSX port subscribed so they can help.

Lightning
11-01-2005, 08:48 AM
FPK doesn't FPC support the index keyword in conjunction with external and name ?
index is the real order in the declared library and is verry useful sometimes, why use all those linklib directives when index is usable.

Anonymous
11-01-2005, 02:43 PM
I can vaguely remember that you don't need to link via frameworks IF you specify the full external possibility:

All FPC unix libs are linked as follows (e.g. for gtk 1.2)

const
{$ifdef darwin}
libname = 'gtk-1.2.0';
{$linklib gtk-1.2.0}
[$endif}
{$ifdef freebsd}
libname = 'gtk12';
{$linklib gtk12}
{$endif}
{$ifdef linux}
libname = 'gtk-1.2'; // harder, multuiple distro's and convention
{$linklib gtk}
{$endif}
{$ifdef win32}
libname = 'gtk-1.2'; // harder, multuiple distro's and convention
{$linklib libgtk-0} // windows doesn't prefix lib by default, because
// it is not the default convention on windows
{$endif}

Then all functions are declared like this:

function someskeleton(a,b:integer); cdecl; external libname name 'someskeleton';

so WITH name and WITH libraryname part. FPC inserts a underscore if accessing the C namespace needs it.

I just got a laptop from work, and am creating a FreeBSD partition on it as I write :D , I'll try to retest Jedi-SDL header with a modern (5.3) BSD system in the coming weeks

savage
11-01-2005, 02:50 PM
Hi Marco,
This is exacltly the sort of thing I meant about my change in sdl.pas. I wanted to write...


const
{$IFDEF DARWIN}
libname= 'libSDL-1.2.0';
{$linklib libSDL-1.2.0}
{$ENDIF}


In the hope that it would be enough for the FreePascal compiler to pick up everything else, thus requiring less work on my part :).

I look forward to hearing about your FreeBSD findings.

Chris Burkhardt
11-01-2005, 05:33 PM
That will not work on Mac OS X... at least not for anyody who has installed the SDL framework using the standard Mac OS X binary installer package from the SDL website.

Maybe the easiest thing is to include a little "installer" script with the JEDI-SDL headers which creates that symlink I talked about above, and then doing:


const
{$IFDEF DARWIN}
libname= 'sdl';
{$linklib sdl}
{$ENDIF}