Recent

Author Topic: Linking to libraries  (Read 10819 times)

_Tux_

  • New member
  • *
  • Posts: 5
Linking to libraries
« on: July 30, 2006, 01:50:51 pm »
Im trying to link to the Newton physics library but im having a few problems. The compiler outputs an undefined symbol error for every procedure i use inside the newton library, however i can use the procedures in the osx api libraries without any problems.

I have moved the libnewton32.a to the same folder as the project so im not sure what else there is to it. does the a file need to be converted to a dylib for the compiler to pick it up?

Code: [Select]
program test;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes;
 
var
 World: Pointer;
 
function  NewtonCreate( malloc : Pointer; mfree : Pointer ) : Pointer; cdecl; external 'libnewton32.a';
procedure NewtonDestroy( const newtonWorld : Pointer ); cdecl; external 'libnewton32.a';

begin

  World := NewtonCreate(nil, nil);
  NewtonDestroy(World);

end.


Quote
TCompiler.Compile WorkingDir="/Users/jon/Documents/Development/Test/" CompilerFilename="/usr/local/bin/ppc386" CompilerParams=" -S2cgi -OG1 -gl -vewnhi -l -Fu. -otest test.lpr"
[TCompiler.Compile] CmdLine="/usr/local/bin/ppc386  -S2cgi -OG1 -gl -vewnhi -l -Fu. -otest test.lpr"
Hint: Start of reading config file /etc/fpc.cfg
Hint: End of reading config file /etc/fpc.cfg
Warning: You are using the obsolete switch -OG
Free Pascal Compiler version 2.1.1 [2006/07/30] for i386
Copyright (c) 1993-2006 by Florian Klaempfl
Target OS: Darwin for i386
Compiling test.lpr
Assembling test
Linking test
/usr/bin/ld: Undefined symbols:
_NewtonCreate
_NewtonDestroy
Error: Error while linking

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3541
Re: Linking to libraries
« Reply #1 on: July 30, 2006, 04:41:48 pm »
Quote from: "_Tux_"
I have moved the libnewton32.a to the same folder as the project


I think this has no effect. On UNIX there is no "Application Directory". You should instead move the library to a place where the operating system will search for libraries. On Linux a common place is /usr/lib Not sure about OS X

Quote
does the a file need to be converted to a dylib for the compiler to pick it up?


To start with .a files are smarlinking information, and not the full library. I think you would need at least the .o files too.

If you can compile them into a .dynlib, much better.

Other wise you can try to staticaly link the .o files into your executable with:

{$L myobject.o}

Then declare your procedures as just external, without library name.

But it´s probably better to make that into a dynlib.

_Tux_

  • New member
  • *
  • Posts: 5
RE: Re: Linking to libraries
« Reply #2 on: July 30, 2006, 04:53:08 pm »
Thanks.

I dont have access to any .o files, only the .a. i found this on the newton forums on how to convert the .a to a .dylib
Code: [Select]
mkdir sometmpdir && cd sometmpdir
ar x libnewton32.a
gcc -dynamiclib -flat_namespace *.o -o libnewton32.dylib


but on the 2nd line i get this...

Code: [Select]
ar: libnewton32.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
ar: libnewton32.a: Inappropriate file type or format


any idea?

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3541
RE: Re: Linking to libraries
« Reply #3 on: July 30, 2006, 04:57:57 pm »
> any idea?

Yes, since you found the instructions on newton forums, you could ask there why it doesn´t work. I really don´t know the reason.

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: RE: Re: Linking to libraries
« Reply #4 on: July 30, 2006, 07:34:53 pm »
Try putting {$linklib newton32} after your function declarations. FPC doesn't require this with external routines on other platforms, but does for OS X. I've been told that this requirement will eventually be eliminated, but for now you need to do this.

I believe {$linklib} corresponds to the OS X linker (ld) -l switch, which tells the linker to first search for libnewton32.dylib and if it can't find it search for libnewton32.a, which is what you have.

You could also specify this on the FPC command line if you want to make it clearer about what you're doing link-wise:  -k'-lnewton32'  -- the -k switch is how you pass stuff to the linker via FPC.

Not sure what the archiver (ar) error message is telling you. The approach looks correct: extract the archive file's (.a) individual .o files to a temp. folder, then combine them (*.o) into a .dylib (specified with -o switch).

You don't mention what version of OS X you're using or whether you're on the Mac PowerPC or Intel platforms, but these could also be factors, particularly if the .a file is old.

Let us know if any of this helps you. I know it seems like it shouldn't be this complicated - afterall, we're working in Pascal, not C or Java - but sometimes it is due to the cross-platform nature of FPC.

_Tux_

  • New member
  • *
  • Posts: 5
Linking to libraries
« Reply #5 on: August 07, 2006, 10:53:51 pm »
Thanks Phil, im getting closer to the answer now.

Im using OS X Tiger 10.4.7 on an Intel mac mini. Im guessing the libnewton32.a file is a universal library, because the ar command works on the G3 build of newton (PPC), but of course I cant compile the dylib because im on intel.

Firstly, I'm putting the .a file in a folder on the library search folder, is this correct?

After adding {$linklib newton32} after my function declarations it seems to get a bit further. Here is the new build output

Code: [Select]
TCompiler.Compile WorkingDir="/Users/jon/Documents/Development/Test/" CompilerFilename="/usr/local/bin/fpc" CompilerParams=" -S2cgi -OG1 -gl -vewnhi -l -Fu. -otest test.lpr"
[TCompiler.Compile] CmdLine="/usr/local/bin/fpc  -S2cgi -OG1 -gl -vewnhi -l -Fu. -otest test.lpr"
Hint: Start of reading config file /etc/fpc.cfg
Hint: End of reading config file /etc/fpc.cfg
Warning: You are using the obsolete switch -OG
Free Pascal Compiler version 2.1.1 [2006/08/06] for i386
Copyright (c) 1993-2006 by Florian Klaempfl
Target OS: Darwin for i386
Compiling test.lpr
Assembling test
Linking test
/usr/bin/ld: Undefined symbols:
__Unwind_Resume
__ZTVN10__cxxabiv117__class_type_infoE
__ZTVN10__cxxabiv120__si_class_type_infoE
__ZTVN10__cxxabiv121__vmi_class_type_infoE
__ZdlPv
__Znwm
___cxa_pure_virtual
___gxx_personality_v0
___cxa_guard_abort
___cxa_guard_acquire
___cxa_guard_release
Error: Error while linking


just to clarify, this is the test code

Code: [Select]
program test;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes;
 
var
 World: Pointer;
 
function  NewtonCreate( malloc : Pointer; mfree : Pointer ) : Pointer; cdecl; external 'libnewton32.a';
procedure NewtonDestroy( const newtonWorld : Pointer ); cdecl; external 'libnewton32.a';

{$linklib newton32}

begin

  World := NewtonCreate(nil, nil);
  NewtonDestroy(World);

end.


Thanks for the help so far

Phil

  • Hero Member
  • *****
  • Posts: 2750
Linking to libraries
« Reply #6 on: August 08, 2006, 06:05:18 pm »
Quote from: "_Tux_"
Im using OS X Tiger 10.4.7 on an Intel mac mini. Im guessing the libnewton32.a file is a universal library, because the ar command works on the G3 build of newton (PPC), but of course I cant compile the dylib because im on intel.


I don't believe there is such a thing as a universal "library". A universal "binary" on the other hand is an app bundle that contains compiled code for both platforms.

You need to check whether your libnewton.a file was compiled for Intel. If not, you won't be able to use it.

_Tux_

  • New member
  • *
  • Posts: 5
Linking to libraries
« Reply #7 on: August 08, 2006, 06:55:46 pm »
ah good point. to my knowledge the developer compiles it on a g5 imac

[edit]

actually, get info says the following for libnewton32.a: "kind: Unix Executable File (Universal)"

and its 3.5mb compared to the 1.8mb for the g3 library (and finder states that as a "Unix Executable File")

Phil

  • Hero Member
  • *****
  • Posts: 2750
Linking to libraries
« Reply #8 on: August 08, 2006, 08:47:17 pm »
Quote from: "_Tux_"

actually, get info says the following for libnewton32.a: "kind: Unix Executable File (Universal)"

and its 3.5mb compared to the 1.8mb for the g3 library (and finder states that as a "Unix Executable File")


It appears as though libraries can be universal too and the file size would seem to suggest that what you have contains both PPC and Intel code.

You might review the 10.4 ld man and see if there's a special switch that you'll need to pass to ld in order to have it select the correct code to link against.

http://gemma.apple.com/documentation/Porting/Conceptual/PortingUnix/compiling/chapter_4_section_3.html

_Tux_

  • New member
  • *
  • Posts: 5
Linking to libraries
« Reply #9 on: August 08, 2006, 11:01:54 pm »
Hmm, I've only managed to find an anwser for the ar failure.

The library archive utility, ar(1), cannot work with libraries containing code for more than one architecture (or single-architecture libraries generated with lipo(1)) after ranlib has added a table of contents to them. Thus, if you need to add additional object files to a library, you must keep a separate copy without a TOC.

nothing to really help my dylib compile :(

 

TinyPortal © 2005-2018