English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 01 December 2022, 15:06   #1
felmur
Registered User
 
felmur's Avatar
 
Join Date: Nov 2022
Location: Salerno/Italia
Posts: 16
Another "undefined reference" error with Gcc ToolChain and WhatIs Library

Hi all,
in a previous Thread, thanks to Stefan 'Bebbo' Franke, we saw how to compile (with gcc-toolchain) a source file containing calls to the mui.library, installing what is necessary to do so using the command

Code:
make sdk=mui PREFIX=<your installation prefix>
Today I propose a new problem.
I tried compiling this simple source:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <exec/libraries.h>
#include <exec/lists.h>
#include <whatis/libraries/whatisbase.h>
#include <whatis/clib/whatis_protos.h>
#include <whatis/pragmas/whatis_pragmas.h>
#include <clib/exec_protos.h>

struct Library *WhatIsBase=NULL;

int main(void) {
	struct TagItem ti = {
	    WI_Deep, DEEPTYPE
	};

	if (!(WhatIsBase = OpenLibrary("whatis.library",0))) {
        printf("Failed to open \"whatis.library\".");
        return 1;
	}

	printf("%s\n",GetIDString(WhatIs("sys:tools.info",&ti)));

	CloseLibrary(WhatIsBase);
	return EXIT_SUCCESS;
}
After copying the includes found in the package of whatis.library (WhatIs.lha), which is available here:

HTML Code:
https://aminet.net/package/util/cli/WhatIs
I tried to compile, without much hope.

the result of the compilation, as expected, is an "undefined reference" error for the two calls to whatis.library: WhatIs()
and GetIdString().

Code:
15:13:00 **** Incremental Build of configuration Release for project test ****
make all 
Building target: test
Invoking: Cross GCC Linker
m68k-amigaos-gcc -g -noixemul -o "test" ./src/test.o   
/mnt/sdb1/AmigaDev/am-gcc/lib/gcc/m68k-amigaos/6.5.0b/../../../../m68k-amigaos/bin/ld: ./src/test.o: in function `main':
./src/test.o:(.text+0x76): undefined reference to `WhatIs'
/mnt/sdb1/AmigaDev/am-gcc/lib/gcc/m68k-amigaos/6.5.0b/../../../../m68k-amigaos/bin/ld: ./src/test.o:(.text+0x7e): undefined reference to `GetIDString'
collect2: error: ld returned 1 exit status
make: *** [makefile:43: test] Errore 1
"make all" terminated with exit code 2. Build might be incomplete.

15:13:00 Build Failed. 4 errors, 0 warnings. (took 162ms)

Attempt to link with "-lwhatis" fails because there is no such library in the compiler definitions.

I don't see any "sdk" for this library in the related amiga-gcc directory, so I can't fix it as I did for mui.library.

For my project, a library that works under OS 2.x and recognizes file types is essential, and the whatis.library works well for this purpose.

Ideas?

Last edited by felmur; 01 December 2022 at 15:13.
felmur is offline  
Old 01 December 2022, 19:09   #2
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by felmur View Post
Hi all,
in a previous Thread, thanks to Stefan 'Bebbo' Franke, we saw how to compile (with gcc-toolchain) a source file containing calls to the mui.library, installing what is necessary to do so using the command

Code:
make sdk=mui PREFIX=<your installation prefix>
Today I propose a new problem.
I tried compiling this simple source:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <exec/libraries.h>
#include <exec/lists.h>
#include <whatis/libraries/whatisbase.h>
#include <whatis/clib/whatis_protos.h>
#include <whatis/pragmas/whatis_pragmas.h>
#include <clib/exec_protos.h>

struct Library *WhatIsBase=NULL;

int main(void) {
    struct TagItem ti = {
        WI_Deep, DEEPTYPE
    };

    if (!(WhatIsBase = OpenLibrary("whatis.library",0))) {
        printf("Failed to open \"whatis.library\".");
        return 1;
    }

    printf("%s\n",GetIDString(WhatIs("sys:tools.info",&ti)));

    CloseLibrary(WhatIsBase);
    return EXIT_SUCCESS;
}
After copying the includes found in the package of whatis.library (WhatIs.lha), which is available here:

HTML Code:
https://aminet.net/package/util/cli/WhatIs
I tried to compile, without much hope.

the result of the compilation, as expected, is an "undefined reference" error for the two calls to whatis.library: WhatIs()
and GetIdString().

Code:
15:13:00 **** Incremental Build of configuration Release for project test ****
make all 
Building target: test
Invoking: Cross GCC Linker
m68k-amigaos-gcc -g -noixemul -o "test" ./src/test.o   
/mnt/sdb1/AmigaDev/am-gcc/lib/gcc/m68k-amigaos/6.5.0b/../../../../m68k-amigaos/bin/ld: ./src/test.o: in function `main':
./src/test.o:(.text+0x76): undefined reference to `WhatIs'
/mnt/sdb1/AmigaDev/am-gcc/lib/gcc/m68k-amigaos/6.5.0b/../../../../m68k-amigaos/bin/ld: ./src/test.o:(.text+0x7e): undefined reference to `GetIDString'
collect2: error: ld returned 1 exit status
make: *** [makefile:43: test] Errore 1
"make all" terminated with exit code 2. Build might be incomplete.

15:13:00 Build Failed. 4 errors, 0 warnings. (took 162ms)
Attempt to link with "-lwhatis" fails because there is no such library in the compiler definitions.

I don't see any "sdk" for this library in the related amiga-gcc directory, so I can't fix it as I did for mui.library.

For my project, a library that works under OS 2.x and recognizes file types is essential, and the whatis.library works well for this purpose.

Ideas?

Well, a library built in 1994 is not aware of the syntax of newer compilers?
That's expectable, isn't it?
Basically someone has to do what the amiga-gcc sdk installation does:
Copy the provided files to the correct places plus create usable headers for amiga-gcc.


Copying is easy, creating the proper files too, if a sfd or fd file exists.


Thus I recommend writing a fd or sfd file based on the whatis_pragmas.h, then do the same as what the sdk files do. Have a look at the simple ones like camd.sdk.
bebbo is offline  
Old 01 December 2022, 19:47   #3
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
the WhatIsBase.h should rather include
Code:
#include <exec/libraries.h>
#include <exec/lists.h>
#include <utility/tagitem.h>
and the fd file might look like
Code:
##base _WhatIsBase
##bias 30
##public
WhatIs(Name,TagArray)(a0,a1)
GetIDString(Type)(a0)
GetIconName(Type)(a0)
GetIDType(IdString)(a0)
CmpFileType(Type1,Type2)(a0,a1)
GetIDStringMaxLen()()
FirstType()()
NextType(Type)(a0)
AskReparse(Now)(d0)
ParentFileType(Type)(d0)
IsSubTypeOf(Type,ParentType)(d0,d1)
MakeTypeInfos(SizeOfInfo)(d0)
GetTypeInfo(Handle,Type)(a0,d0)
FreeTypeInfos(Handle)(a0)
bebbo is offline  
Old 02 December 2022, 12:54   #4
felmur
Registered User
 
felmur's Avatar
 
Join Date: Nov 2022
Location: Salerno/Italia
Posts: 16
Quote:
Originally Posted by bebbo View Post
the WhatIsBase.h should rather include
Code:
#include <exec/libraries.h>
#include <exec/lists.h>
#include <utility/tagitem.h>
Thank you for your answer.

I had already fixed this

Quote:
Originally Posted by bebbo View Post
and the fd file might look like
Code:
##base _WhatIsBase
##bias 30
##public
WhatIs(Name,TagArray)(a0,a1)
GetIDString(Type)(a0)
GetIconName(Type)(a0)
GetIDType(IdString)(a0)
CmpFileType(Type1,Type2)(a0,a1)
GetIDStringMaxLen()()
FirstType()()
NextType(Type)(a0)
AskReparse(Now)(d0)
ParentFileType(Type)(d0)
IsSubTypeOf(Type,ParentType)(d0,d1)
MakeTypeInfos(SizeOfInfo)(d0)
GetTypeInfo(Handle,Type)(a0,d0)
FreeTypeInfos(Handle)(a0)
Writing this FD file is like having to speak Arabic for me. For example, I don't understand where the bias value is taken from. Mostly I don't understand why for some functions, such as
Code:
NextType(Type)(a0)
ParentFileType(Type)(d0)
which have the same return type and the same calling parameter, registers of different types are specified (A0 and D0).

However, I used this FD file together with clib/whatis_protos.h to generate the whatis.sfd file with fd2sfd.

I then ran the following:
1) created a folder m68k-amigaos/include/whatis
2) copied into this folder the directories contained in include in the WhatIs.lha package
3) I fixed the calls in the WhatIsBase.h file and changed its name to whatisbase.h.
3) copied your whatis.fd file to m68k-amigaos/lib/fd
4) copied the whatis.sfd file generated by me in m68k-amigaos/lib/sfd

I then tried to recompile the source contained in my post, getting the same "undefined reference" error.

I then tried to add -lwhatis to my linker, without success (whatis library not found)

Where am I doing wrong?

Greetings and thanks again for your patience,
felmur is offline  
Old 02 December 2022, 13:11   #5
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,233
Quote:
Originally Posted by felmur View Post
For example, I don't understand where the bias value is taken from.
It's taken from ##bias, and then auto-incremented (or decremented, if you want to say so) automatically for each slot defined.


Quote:
Originally Posted by felmur View Post
Mostly I don't understand why for some functions, which have the same return type and the same calling parameter, registers of different types are specified (A0 and D0).
Only because its author defined it to be so. Typically, address registers are used for pointers and data registers for numbers, but that is just a convention.



Quote:
Originally Posted by felmur View Post


I then tried to recompile the source contained in my post, getting the same "undefined reference" error.
The essential part is that you need to generate some GNU-specific stub functions (or inline function). FD2Pragma can do that for you, but I forgot the command line argument of it to generate them for you. You also need to include these files then, of ocurse.


Quote:
Originally Posted by felmur View Post

I then tried to add -lwhatis to my linker, without success (whatis library not found)
With "-l" you specific static link libraries. This is not how your average amiga library works. These are dynamic libraries, and in order to use them, you need to open them explicitly in your code, and you need the stub files.
Thomas Richter is offline  
Old 02 December 2022, 13:35   #6
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Do something like that to your .sfd file

sfdc --mode=macros whatis_lib.sfd >inline.h

This inline.h (or however you see fit name, maybe whatis_inline.h) is what you need to include.
alkis is offline  
Old 02 December 2022, 14:35   #7
felmur
Registered User
 
felmur's Avatar
 
Join Date: Nov 2022
Location: Salerno/Italia
Posts: 16
Quote:
Originally Posted by alkis View Post
Do something like that to your .sfd file

sfdc --mode=macros whatis_lib.sfd >inline.h

This inline.h (or however you see fit name, maybe whatis_inline.h) is what you need to include.
yes, now it works.

Now I would like to try to redo the same steps with some other small library, to see if I understand how it works.

Thanks for everything.
felmur is offline  
Old 02 December 2022, 14:51   #8
felmur
Registered User
 
felmur's Avatar
 
Join Date: Nov 2022
Location: Salerno/Italia
Posts: 16
Quote:
Originally Posted by Thomas Richter View Post
It's taken from ##bias, and then auto-incremented (or decremented, if you want to say so) automatically for each slot defined.
My doubt is just why Stefan wrote ##bias 30 in the FD file he posted in the post. Where did he get that "30" from? Maybe "30" means 30 bytes offset to the first library call and that value he got from whatis_pragmas.h included in the package, which specifies "1e" equal to 30 decimal for the first library call?

Code:
#pragma libcall WhatIsBase WhatIs 1e 9802
Quote:
Only because its author defined it to be so. Typically, address registers are used for pointers and data registers for numbers, but that is just a convention.
Here too my doubt is the same: why did Stefan use A0 for the first parameter and D0 for the second? The two functions are defined as follows:
Code:
FileType NextType(FileTypeType);
FileType ParentFileType(FileTypeType);
Yet Stefan wrote A0 next to NextType and D0 next to ParentFileType in his FD file in the post. Why?

I repeat, for me it is like speaking Arabic.

Thank you.
felmur is offline  
Old 02 December 2022, 15:37   #9
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by felmur View Post
My doubt is just why Stefan wrote ##bias 30 in the FD file he posted in the post. Where did he get that "30" from? Maybe "30" means 30 bytes offset to the first library call and that value he got from whatis_pragmas.h included in the package, which specifies "1e" equal to 30 decimal for the first library call?

Code:
#pragma libcall WhatIsBase WhatIs 1e 9802
Here too my doubt is the same: why did Stefan use A0 for the first parameter and D0 for the second? The two functions are defined as follows:
Code:
FileType NextType(FileTypeType);
FileType ParentFileType(FileTypeType);
Yet Stefan wrote A0 next to NextType and D0 next to ParentFileType in his FD file in the post. Why?

I repeat, for me it is like speaking Arabic.

Thank you.

The truth is in the digits:



#pragma libcall WhatIsBase WhatIs 1e 9802


1e means 0x1e which is 30, the offset of that function. Thus it's the first after BIAS. Why BIAS? Because there are no functions in front of that.


9802 means: register 9 == a1, register 8 == a0, 02 means 2 registers total.


Now you'll see that the author used different register types for the same supplied type. One has to accept that.







Last edited by bebbo; 26 October 2023 at 13:18.
bebbo is offline  
Old 02 December 2022, 18:17   #10
felmur
Registered User
 
felmur's Avatar
 
Join Date: Nov 2022
Location: Salerno/Italia
Posts: 16
Quote:
Originally Posted by bebbo View Post
The truth is in the digits:



#pragma libcall WhatIsBase WhatIs 1e 9802


1e means 0x1e which is 30, the offset of that function. Thus it's the first after BIAS. Why BIAS? Because there are no functions in front of that.
Ok, that was what I thought.

Quote:
9802 means: register 9 == a1, register 8 == a0, 02 means 2 registers total.

Now you'll see that the author used different register types for the same supplied type. One has to accept that.
So, i take the first line of *pragmas.h file and read BIAS from fist BB (see follow pragma line). For the register involved, I have to see the last number of the line:

#pragma libcall libraryBase fuctionName BB RST...DD

where T is the first register in the library call, S is the second, R is the third register and DD is the number of parameters.

R, S, T is coded as follow:
0 = d0
1 = d1
2 = d2
3 = d3
4 = d4
5 = d5
6 = d6
7 = d7
8 = a0
9 = a1
a = a2
b = a3
c = a4
d = a5
e = a6
f = a7

So, if the last number is 9802, I have to consider 2 parameter for the library call, the first is A0 (8) and the second is A1 (9).

Also, if the last number of the line is ba9821007, I have to consider 7 parameter for the library call, and the register involved is (d0,d1,d2,a0,a1,a2,a3).

Yeah, this is very nice.

Thank you very much.
felmur is offline  
Old 02 December 2022, 22:15   #11
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,233
Quote:
Originally Posted by felmur View Post
My doubt is just why Stefan wrote ##bias 30 in the FD file he posted in the post. Where did he get that "30" from?
A "doubt"? This is not a religion here. You mean "a question" probably? A "doubt" is something that is customary believed to be true, yet you have indications that it could be false. A question is open ended. :-)



The 30 comes from where the first library entry is, at -30 bytes from the library entry. It usually is at this offset. Each entry is 6 bytes, the first four slots are used by the operating system, so this is slot #5, typically the first slot to be used.



Quote:
Originally Posted by felmur View Post

Here too my doubt is the same: why did Stefan use A0 for the first parameter and D0 for the second?
Because he selected this to be like it. That's really it, there is no logic behind it. There are conventions how one can select registers to pass certain types of data, but these are only conventions. Conventionally, one uses address registers for pointers, data registers for numbers, and start allocating from the first one of the family. But that is really it. A convention. If the author selected to do otherwise, well, works too.
Thomas Richter is offline  
Old 02 December 2022, 22:21   #12
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,233
Quote:
Originally Posted by felmur View Post
So, if the last number is 9802, I have to consider 2 parameter for the library call, the first is A0 (8) and the second is A1 (9).
Yeah, this is very nice.

Please remember, #pragmas are compiler specific. The pragmas described here are SAS/C compiler specific, and the same logic may not hold for other compilers. You typically do not generate these #pragmas (or .h files) for the libraries yourself. You typically get them from the vendor of the library, or failing that, you create them from the .fd file via a tool such as FD2Pragma, which you find in Aminet.


FD2Pragma takes arguments that specific for which compiler the file should be generated.
Thomas Richter is offline  
Old 04 December 2022, 19:40   #13
felmur
Registered User
 
felmur's Avatar
 
Join Date: Nov 2022
Location: Salerno/Italia
Posts: 16
Quote:
Originally Posted by Thomas Richter View Post
A "doubt"? This is not a religion here. You mean "a question" probably? A "doubt" is something that is customary believed to be true, yet you have indications that it could be false. A question is open ended. :-)
Oh, I'm sorry for my bad engllish.

I meant "question", by the way.

Thank you.
felmur is offline  
Old 23 December 2022, 18:25   #14
emiespo
Registered User
 
Join Date: Jul 2017
Location: Oxford
Posts: 107
Hi, I am trying to do something similar with the asyncio library (http://aminet.net/dev/c/AsyncIO.lha).

Made an asyncio.sdk file with the following content:

Code:
Short: 	Asyncio library
Version: 39.2a
Url: http://aminet.net/dev/c/AsyncIO.lha

AsyncIO/include/clib/asyncio_protos.h
AsyncIO/include/fd/asyncio_lib.fd = asyncio.fd
AsyncIO/include/libraries/asyncio.h

fd2sfd : asyncio.fd clib/asyncio_protos.h
sfdc : asyncio.sfd
stubs : asyncio.sfd
...tried to make it, this is what happens:

Code:
$ make sdk=asyncio
sdk asyncio...
sdk asyncio...failed
Short: 	Asyncio library
Version: 39.2a
cp build/asyncio/AsyncIO/include/clib/asyncio_protos.h /opt/amiga/m68k-amigaos/include/clib/asyncio_protos.h
cp build/asyncio/AsyncIO/include/fd/asyncio_lib.fd /opt/amiga/m68k-amigaos/lib/fd/asyncio.fd
cp build/asyncio/AsyncIO/include/libraries/asyncio.h /opt/amiga/m68k-amigaos/include/libraries/asyncio.h
Parser confused in line 77
Parser confused in line 77
Parser confused in line 77
Parser confused in line 78
Parser confused in line 78
Parser confused in line 78
Parser confused in line 80
Parser confused in line 80
Parser confused in line 80
Parser confused in line 81
Parser confused in line 81
Parser confused in line 81
Parser confused in line 83
Parser confused in line 84
Parser confused in line 84
Parser confused in line 84
Parser confused in line 85
Parser confused in line 85
Parser confused in line 85
Parser confused in line 86
Parser confused in line 87
Parser confused in line 87
Parser confused in line 87
Parser confused in line 88
Parser confused in line 88
Parser confused in line 88
Parser confused in line 89
Parser confused in line 89
Parser confused in line 89
Parser confused in line 89
Parser confused in line 90
Parser confused in line 90
Parser confused in line 90
Parser confused in line 91
Parser confused in line 91
Parser confused in line 92
Parser confused in line 92
Parser confused in line 93
Parser confused in line 93
Parser confused in line 93
OpenAsync gets 3 fd args and 0 protos.
/Users/emiespo/eprojects/Amy/GCC/amiga-gcc/sdk/install: line 11: 98742 Segmentation fault: 11  $3/bin/fd2sfd -o $3/m68k-amigaos/lib/sfd/$name.sfd $3/m68k-amigaos/lib/fd/$fd $3/m68k-amigaos/include/$proto
sdk asyncio...failed
use less "log/sdk asyncio.log" to view the full log and search for ***
make[1]: *** [sdk] Error 1
make: *** [x] Error 2
worth noting that before using the SDK I tried running fd2pragma alone and got basically the same error (passing the CLIB file and the existing fd).

Am I doing anything wrong? Is there a guide/tutorial on how to get those files by hand?

We're talking about a small library here -- I might simply include the functions I need by hand (I guess also trying to add the linked library is not going to be easy in the transition SAS - GCC).
emiespo is offline  
Old 24 December 2022, 09:36   #15
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by emiespo View Post
Hi, I am trying to do something similar with the asyncio library (http://aminet.net/dev/c/AsyncIO.lha).

Made an asyncio.sdk file with the following content:

Code:
Short:     Asyncio library
Version: 39.2a
Url: http://aminet.net/dev/c/AsyncIO.lha

AsyncIO/include/clib/asyncio_protos.h
AsyncIO/include/fd/asyncio_lib.fd = asyncio.fd
AsyncIO/include/libraries/asyncio.h

fd2sfd : asyncio.fd clib/asyncio_protos.h
sfdc : asyncio.sfd
stubs : asyncio.sfd
...tried to make it, this is what happens:

[CODE]$



...


Am I doing anything wrong? Is there a guide/tutorial on how to get those files by hand?

We're talking about a small library here -- I might simply include the functions I need by hand (I guess also trying to add the linked library is not going to be easy in the transition SAS - GCC).

You are doing ok. That "small library" provides an unusable clib header file. Fix that header and it will work.
bebbo is offline  
Old 25 December 2022, 23:50   #16
emiespo
Registered User
 
Join Date: Jul 2017
Location: Oxford
Posts: 107
Quote:
Originally Posted by bebbo View Post
You are doing ok. That "small library" provides an unusable clib header file. Fix that header and it will work.
Thanks! I managed to have it working by simplifying (ie removing) all those weird _REG() _ASM() in the clib pragma file (just kept definitions as in the camd archive).

In the end I don't think I'm going to use that lib, but rather reuse its source code, as it doesn't allow to force MEMF_CHIP for the read buffers (I'm writing something that would benefit from DMA to chip-mem ;-)).

Now I'm trying to mix-match your toolchain with the VSCode debugging experience, I am getting some strange issues with local variables not working and some code being skipped... but this is OT (ie wrong thread ) and needs more investigation on my side!

PS Merry Christmas! :-)

Last edited by emiespo; 25 December 2022 at 23:51. Reason: Merry Xmas!
emiespo is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
"undefined reference" error with Gcc ToolChain and MUI38. felmur Coders. C/C++ 4 27 November 2022 13:01
"ELF Library" error installing 4.1 in WinUAE mroshaw support.WinUAE 1 10 December 2018 20:48
vasm "undefined symbol" is driving me nuts jotd Coders. Asm / Hardware 6 03 December 2017 20:17
Error "Scalos Request couldn't open workbench.library V39.x" yugorin project.ClassicWB 2 08 August 2016 20:53
"Unpack.library failure" error message Another World New to Emulation or Amiga scene 1 16 December 2008 14:01

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 02:12.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.13503 seconds with 15 queries