2

I am using object file in my Delphi application over Linux Platform and linked them as shown in below piece of code and getting error:

"E2065 Unsatisfied forward or external declaration: 'add'"

Delphi:

    program ITP_Test;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    {$LINK 'hello.o'}
    
    function add(a ,b : Integer): Integer; cdecl; external;
    
    begin
      Writeln(add(2,7));
    end.

hello.c
    
    #include<stdio.h>
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    int add(int a, int b)
    {
        return a + b;
    }
    #ifdef __cplusplus
    }
    #endif

compiled hello.c using command:

'gcc -c hello.c'

gcc version : 7.5.0 Linux version: Ubuntu 18.04

Anna
  • 119
  • 9
  • What makes you think this is related to linking multiple objects? How did you compile the objects? What does the object source look like? Why would you use Pascal calling convention? – David Heffernan Jun 23 '21 at 07:42
  • @DavidHeffernan I have files written in c language which are compiled using gcc and linked like above in delphi code. About "pascal" calling convention I am not sure as it is used in old legacy code for windows. But I have tried using "cdecl " but still getting same error. There are approx 15 .o files to be linked . – Anna Jun 23 '21 at 07:57
  • Maybe an issue with symbol decoration when C code gets compiled? – fpiette Jun 23 '21 at 08:46
  • You don't want `pascal` calling convention. It's surely `cdecl`. The basic debugging step here is to stop trying to compile the end product and go right back to the most simple thing you can try. Can you make a program that links an object containing just this function `int add(int a, int b) { return a + b; }` – David Heffernan Jun 23 '21 at 08:58
  • @DavidHeffernan I tried with simple program and getting "E2065 Unsatisfied forward or external declaration: 'add'" – Anna Jun 23 '21 at 10:40
  • 1
    So the question is not about multiple object files. It would be great if you could edit it so that it had the very simple function I provided, and have it completely reproducible. So details of OS version, compiler version, compiler command line etc. – David Heffernan Jun 23 '21 at 13:09
  • @DavidHeffernan as you suggested ,edited the question and provided the details. could you please suggest what could be done to resolve this issue? – Anna Jun 24 '21 at 07:22
  • I can reproduce your problem. I'm trying to solve it. Using ProcessMonitor I found that building the project doesn't even try to access hello.o. – fpiette Jun 24 '21 at 08:25
  • Thanks all for explanations. This problem is resolved. one of the solution which works for me is the use of .a file instead of .o file. To create hello.a , used archive way of working in Linux. Can refer the details from here: https://www.geeksforgeeks.org/ar-command-in-linux-with-examples/#:~:text=ar%20command%20is%20used%20to%20create%2C%20modify%20and,are%20termed%20as%20the%20members%20of%20the%20archive. Also this video gave me the idea to resolve my problem. May be it can help others too. https://www.youtube.com/watch?v=86zH833Ytkw – Anna Jun 25 '21 at 07:34
  • @Anna Thanks for feedback. I will try it. I suggest you write your comment as an answer so that other searching similar problem will find the solution easily. If you prefer, I can write the answer once I verified it. – fpiette Jun 25 '21 at 12:14
  • sure @fpiette . This is the solution which I found. But If there is some another approach you can post here else we will make the above approach as an answer. And yes you can verify it on your end as well :) – Anna Jun 25 '21 at 15:46
  • @Anna I have verified [the solution](https://www.youtube.com/watch?v=86zH833Ytkw) and it works here. – fpiette Jun 26 '21 at 13:27

1 Answers1

1

I have found the solution in Delphi documentation.

The syntax for your example is:

function add(a, b : Integer): Integer; cdecl; external object 'hello.o' name 'add';

There is no need to use the $LINK compiler directive.

So the full code for your example becomes:

program LinuxExternalHello;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

function add(a, b : Integer): Integer; cdecl; external object 'hello.o' name 'add';

begin
  Writeln(add(2,7));
end.

You hello.c and the way to compile it is perfectly correct.

The alternative described by Marion Candau in his YouTube video is still valid but requires one more step to build the archive file.

fpiette
  • 11,983
  • 1
  • 24
  • 46
  • Thanks @fpiette yes even this solution works :) and yes this avoids the step of linking and creating archive file. – Anna Jun 28 '21 at 07:35