Welcome, Guest. Please login or register.

Author Topic: Compiler  (Read 14002 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #29 on: May 31, 2003, 11:32:36 PM »
After doing a little experimenting, the bottom line seems to be that gcc expects an .a extention to all linker libs, whereas the one i'm trying to link has a .lib extension. Renaming it doesn`t help, it thinks the file is corrupt. Can someone explain to me how to link the .lib files or why they won`t work?
 

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #30 on: June 01, 2003, 01:15:01 AM »
Maybe i'm asking the wrong questions. I want to produce a reaction GUI, and so far GCC seems to be the most promising choice for a compiler. If anyone has coded in reaction in gcc, maybe they can help me. :)
 

Offline iamaboringperson

  • Hero Member
  • *****
  • Join Date: Jun 2002
  • Posts: 5744
    • Show only replies by iamaboringperson
Re: Compiler
« Reply #31 on: June 01, 2003, 01:27:36 AM »
looks like you are not having much luck there :(

i have never had any success with reaction, so i hope people can help me with that too!
 

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show only replies by Cymric
Re: Compiler
« Reply #32 on: June 01, 2003, 02:45:52 AM »
@quiesce:

You seem to have quite some trouble. It's been a long time since I did any Amiga-programming with gcc, but perhaps these hints and tips will help you understand what's going wrong. Please note that this is largely quoting from memory, with lots of experience of using gcc with Linux.

First of all, using an #include does not insert the code of external functions into your program---it just tells the compiler 'Look, somewhere out there, there's a function called foo(), with parameters bar and baz. Trust me. It exists. Don't complain, just generate the proper code to *setup a call* to that function.' The job of the linker is then to look at what the compiler created, and pull out the real code of foo() from a library. If you don't supply the proper linking options to the command line, you get errors like you described. That is a tell-tale sign you forgot to link to the proper libraries.

Now libraries come in two flavours: Amiga-style .lib-format, and gcc-style lib.a-format. Note the prefix 'lib' in the gcc-name. As far as I know, the gcc linker 'ld' cannot handle the Amiga-linker libraries: their format is simply too different. (Someone please correct me if I'm wrong.) It should be possible to convert them into each other: there's bound to be a program on Aminet to do that for you. By the way, do not confuse a .lib-file with a .library-file: they are very different things!

Now then. Fist your helloworld-program. The proper compilation directive for that is:

gcc -o helloworld helloworld.c -lc

Notice that I am calling onto the C-compiler here (and not the C++-one: your program is standard C!). Also note the -lc option: this means 'Link with libc.a'. Notice that is it not -llibc.a or -llibc. If your program contains any math, you should do something like:

gcc -o calculate calculate.c -lm -lc

instructing to link with libm.a first, and then libc.a. Don't reverse the order: it can lead to problems in program execution.

You then wanted to link your program to the Reaction-lib. That doesn't work for two reasons: your program doesn't use any function from that lib so there's nothing to link, and second its file format is incorrect. It is an Amiga-style .lib-file, after all.

Finally, the compiler asked you to insert various volumes. That tells me you have not executed a little script to set all the assign's needed for the GNU-system (and thus the compiler). The compiler will not work properly until you've set them all to their proper values. I recall that there is a small package of about 50 KB called 'ade-setup' or 'gg-setup' or something similar, which contains all the necessary files to do this. It is most likely not included in a standard set of GNU gcc-executables: it is very Amiga-specific. (The Aminet directory /dev/gg has an interesting README---have you looked at it?)

Anyway, I hope that the above helps you sufficiently to get the system up and running to a point where you can compile standard C- and C++-programs; after that the next hurdle is Amiga-specific system programs. Once you can compile those, you can start thinking about Reaction. Good luck.

(Note to experienced Amiga-coders: feel free to say where I went horrendously wrong; like I said, it's been a long time :-).)
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.
 

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #33 on: June 01, 2003, 03:09:03 AM »
Thanks for that. The c++ command was necessary because gcc doesn't like the "//" comment, and it appears in a lot of the header files.

Let me get something straight about libraries... linker libraries include code into the main program during the linking process? And .library files load functions into the program on execution? If my understanding of the latter is correct, how can I prevent the program from complaining about the absence of a function that comes from a .library file?
 

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #34 on: June 01, 2003, 03:15:03 AM »
Another thing... i've looked on aminet and on google and can't find anything to convert amiga link libraries into gnu c link libraries. Does this mean I can't use third party link libraries in gcc, or am I not looking hard enough?

Edit: oops, turns out the util to do it was in my gcc package. :P
 

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #35 on: June 01, 2003, 04:23:07 AM »
Seems some libs won't convert anyway... such as the mui linker libraries and reaction.lib.

When converting reaction.lib I get:

Convert this library into ALINK (join type) format.

How do I do this?
 

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show only replies by Cymric
Re: Compiler
« Reply #36 on: June 01, 2003, 11:21:20 AM »
@quiesce:

Man, I wish Karlos or someone else helped me out here :-). I am under the impression you are trying to run before you can walk: take it one step at a time.

Once again, several issues. The '//' is a C++-style comment. gcc should not have any trouble with that when compiling in C-mode. Certainly version 2.95.x does not. Perhaps it was an addition to the compiler postdating 2.7.x.

You are correct in your understanding of the differences between a .lib- and a .library-library. In order to have gcc shut up about missing .library-functions you have three options: link to a lib which contains so-called stub code, use the compiler directive #pragma (the method used with SAS/C, AztecC and perhaps others too), or generate the necessary inline assembly statements yourself. gcc has extensive facilities for the latter. All methods do the same thing: they generate the proper code for setting up a function call to an Amiga-style run-time library. This unfortunately is somewhat different from a regular gcc-function call, hence the special treatment. If I had an Amiga myself, I could probably hack up some working code: while very arcane, it's not overly difficult.

The problem is that for the applications you wish to develop, the stub code route is difficult. You need to link to amiga.lib as well as, say, mui.lib. The former contains stub code for the basic library functions like OpenLibrary() and CloseLibrary(). The second deals with the calls specific to MUI. Unfortunately, linking fails because the gcc-linker doesn't understand the format of those libs. Since #pragma-statements are highly compiler-specific, you cannot simply 'borrow' them from the Amiga header files. Leaving you stranded with the inline assembly method of gcc... :-?

Which brings me to the final topic: I recall---a dim, hazy, nearly forgotten memory---that the SAS/C suite had a tool which performed the conversion for you. Although I don't really understand why the supplied program you mentioned fails: as far as I can remember is that linker libs *are* basically a string of 'join'ed object files. Also, ALINK was retired back in 1986, and I'm very sure the Amiga-port of the gcc-suite was developed much later. To see a program which still requires after this extinct dinosaur is surprising to say the least. Are you sure you're using the converter correctly?

I regret that's about as much I can tell you. While it is certainly possible to use gcc for Amiga-specific development (foregoing the use of ixemul), it's a bit of a pain setting it up properly and has you fiddling with internals no nere mortal should ever set eyes upon. Nevertheless, I hope you find my comments useful. Good luck!
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show only replies by Karlos
Re: Compiler
« Reply #37 on: June 01, 2003, 11:43:38 AM »
Hi all,

Sorry Cymric ;-) I managed to miss this thread - I haven't been in the developer forums much lately. I'm up to my eyes in some coding at the moment and come to amiga.org to get a break from it :-)

Standard C / C++ code pass arguments to a function on the stack (a unix convention). The amiga libraries have an assembly level interface that works differently. Arguments are passed along in registers and a pointer to the library is passed in register a6.

To call amiga libraries from C, compilers have to generate the appropriate calling convention for a function (ie save off any registers that may get trashed, load the arguments and to a jsr to the code).

Naturally there are several ways of doing this. Inline assembly, stub libraries or #pragmas.

Any #pragma is compiler dependent (that being the point of pramas). IIRC StormC goes this route (with amicall / tagcall).

AFAIK, as Cymric says, gcc basically goes the inline assembly / stub link library way.

In any event, I strongly reccomend the inline asm header approach for performance critical code. Otherwise (with the link libraries) you are calling a function to call a function. Naturally this introduces some additional overhead. Not really much of an issue for GUI related stuff I guess...

I'm not actually using gcc at the moment, but IIRC there was a tool for creating gcc compatible stub .lib files from fd files?

Keep on plugging away at it. I'm sure you'll get there.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show only replies by Karlos
Re: Compiler
« Reply #38 on: June 01, 2003, 12:06:20 PM »
Quote

quiesce wrote:
If my understanding of the latter is correct, how can I prevent the program from complaining about the absence of a function that comes from a .library file?


It is. shared libraries have version numbers. From the documentation on a library, choose the minimum version that fully supports all the functions of that library you intend to use.
The OpenLibrary() call supports a minimum version number that you specify (often left as zero if you don't care which version). You give this as the second argument eg:

/* Open at least v41 of intuition.library */
IntuitionBase = OpenLibrary("intuition.library", 41);

OpenLibrary() will return NULL if either the library isn't available (should never happen for intuition btw ;-)  ) or isn't available in at least the version you asked for. Simply test the return value for NULL and handle accordingly (maybe put up an error message and cleanly exit the program).
int p; // A
 

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #39 on: June 01, 2003, 04:11:13 PM »
It seems that if I setup a pointer to the opened library, (like intuitionbase, as you said) the compiler won't complain. Thanks. :)
 

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #40 on: June 01, 2003, 04:38:36 PM »
I hope noone minds me asking another coding question... ;) I would like to know how you go about creating another thread/process?

For instance, if I had the function  STRPTR FRequester(STRPTR pattern, STRPTR pathname) which displayed a file requester window, this function would normally stall the rest of the program until the file requester closed and the function returned. How could I have this function call move onto another thread/process (not sure what the correct terminology is here) so that my program could multitask and do other things?
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show only replies by Karlos
Re: Compiler
« Reply #41 on: June 01, 2003, 04:40:15 PM »
Actually that wasn't a very good example :-)

IntuitionBase is not a standard Library (in that it has extended stuff in it)

What I should have written int that example was

struct IntuitionBase *IntuitionBase;

IntuitionBase = (struct IntuitionBase*)OpenLibrary("intuition.library", 41);

/* we can check if we opened it ok by testing if IntuitionBase is not NULL */

But the general idea is the same for all libraries.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show only replies by Karlos
Re: Compiler
« Reply #42 on: June 01, 2003, 04:57:40 PM »
Hi quiesce,

Ah, the wonders of multithreading :-)

Creating multithreaded code has its complications. But generally what you do is to define a function that serves as the entry point for the new thread.

The next thing is to create a thread and tell it to launch from that address. You have two choices under amiagos

1) Use an exec.library Task

Tasks are lightweight and do not use many resources. Their principal drawback is that they cannot use dos.library or anything else which may use it (eg normal C IO mechanisms).

Use tasks when character IO is not important for your code.

You need to look at exec.library/AddTask() or amiga.lib/CreateTask()

Eg :

struct Task* myTask;

void myTaskMain()
{
   /* code for myTask */
}

/* struct Task* CreateTask(name, pri, entry, stacksize)*/

myTask = CreateTask("mytask", 0, myTaskMain, 4096);

2) Use a dos.library Process

This is an exec.library task extended with the various handles that allow it to use the dos.library. It's pretty much complete. You need to look at dos.library/CreateNewProc(). This call returns a struct Process* (castable to struct Task*) and takes a range of arguments as a taglist.

If you do go for multithreading, you need to protect data that is used from parallel threads. You have to ensure that modifications to data are exclusive. For this you need to look at Signal Semaphores (see exec.library manuals).

You will also need to look at signalling and sending messages such that your threads can norify each other. An understanding of how exec works is very handy here.

It sounds a bit more complex than it is but it's also not for the beginner either.
int p; // A
 

Offline quiesceTopic starter

  • Jr. Member
  • **
  • Join Date: Feb 2003
  • Posts: 72
    • Show only replies by quiesce
Re: Compiler
« Reply #43 on: June 01, 2003, 05:16:59 PM »
Thanks.
 

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show only replies by Cymric
Re: Compiler
« Reply #44 from previous page: June 01, 2003, 08:17:42 PM »
@quiesce:

Karlos already did a great job of answering, and I agree with him: explicitly coding a program so it's fully multi-threaded/tasking is a very tricky job. Let the amount of programs which actually have the sort of threading you want serve as an indication. It's quite often difficult enough as it is to create a single-threaded application without there being bugs in it :-P.
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.