Hello. I've been given a private source of a final OS4 version of software which includes the main program and support libraries. Although it once compiled on OS4 the final version I received needed many changes to makefiles and missing or incomplete headers files just to compile. After some weeks work I finally got to the point where I could compile the main code but am now stuck in a support library.
All the .o files are compiled fine. But it keeps breaking when turning it into a .library file. It keeps referencing INewLib but I can see no reference to it in the code. I've gone through the headers and support files and the only link to CLib I Can see is include files. Would including stdio.h trigger it off even of no functioins were used?
This is the sort of source I hate. One that once compiled but changes to the code or a SDK update broke it compiling and it can ages reinventing the wheel, spending work on it without progrssing the code anywhere, going backwards really. Anyway this is the compiler output breaking:
gcc -nostartfiles -o Support.library Support.o -lm
/SDK/newlib/lib/libc.a(stub___NewlibCall.o): In function `__NewlibCall':
(.text+0x2): undefined reference to `INewlib'
/SDK/newlib/lib/libc.a(stub___NewlibCall.o): In function `__NewlibCall':
(.text+0x6): undefined reference to `INewlib'
make: *** [Support] Error 1
I'm sure this is something simple that will be solved in less time than it took to type this. :-D
The message says that the undefined reference is in libc.a. So although you specify -nostartfiles, gcc includes libc. Might be an effect of -lm.
Anyway I would just open newlib.library and set up INewlib in the library init function and then see if it works.
Well I tried to setup a NewLibLibrary and INewLib but the result is the same.
Removing the -nostartfiles of course gives me an error about a missing main() and a redefinition of _start.
I even tried combinations of -nostartfiles, -nostdlib and -nodefaultlibs to no avail. MAde it worse actually. I even removed the -lm at one stage but it made no difference and didn't comnplain.
GCC PDF says that even with -nostdlib and -nodefaultlibs some memory moving functions may be included. So I tried to include a -lgcc to no effect.
I am at a loss! :-?
I finally got somewhere. I was exaamining some old source and saw it used -lc. Tried that to no avail. Then also saw it specified -mcrt=clib2. Well I tried this on the linker line and suddenly it creates the library! :-)
So it looks like the default GCC setup using newlib has a problem with -nostartfiles. At this point don't know if it's bug or default newlib needs other special flags to compile.
No, it doesn't. You just named the global interface variable wrong (it should be INewlib as thomas wrote, not INewLib). C/C++ languages are case-sensitive in case you didn't know that before.
Then it should have given me a spelling error! ;-)
But that's a different issue to what I was talking about. Which is that when specifying CLib2 it all compiles fine but by default or even specifying Newlib it breaks. To me that looks like a bug. I wish it to resolve things automatically like it does with CLib2. Perhaps Newlib lacks these features and is unsuitable for library creation. Unless there is a specific flag and/or include files I need.
That said, using the proper object names and declaring them in the source it then compiles fine. But, I don't wish to declare and open a C library myself, I want the compiler to sort that out. So I'll stick to CLib2 for now.
Thanks for the input guys. :-)
Clib2 probably assumes that it has been initialized automatically by the code run before main(). As this does not happen in a library, your code might fail miserably when calling certain clib functions.
Newlib needs to be initialized explicitely by a call to OpenLibrary. This can be done in your library init routine which means it's more likely that your code does not fail. Although there might be some implications if multiple processes share the same runtime.
You should really find out where in your code you call clib functions and if you cannot replace them by your own library-proof versions.
Given CLib2 would be static would probably explain why there was no problem when compiling it. Against Newlib being a dynamic library.
I've had a look in all the sources used and can see no sign of any C lib function. I'm thinking of doing a search for lower cased functionb names to see if that spots it. I did an objdump on the compiled library but saw no sign there either.
Given it uses a math lib I wonder if that needs the C lib for some function and that could be causing it.
If you copy large structs by assignment or pass such structs by value instead of by pointer gcc can generate memcpy() calls even if your code doesn't use this c-lib function.
I had this happen while working on XADFileSystem V53.1 because the fsvptool generated skeleton code had a missing '&' in an AllocDosObjectTags() call and it took me a very long time to find out what was going on and fix it.
Math lib functions (math.h) are a part of the c-lib so need INewlib as well.
Well I have got a few warnings in the code I wanted to clean up about mismatched pointer types. If that could also cause it I don't know.
Well that would explain it. I wonder if there is an alternate to -nostartfiles that doesn't kill off Newlib? All I really need is to kill off main() or redirect it, not kill any start up code. Of course I need to control startup code and exit code which is a bit hard and probably against what .nostartfiles does. Perhaps Newlib is unsuitable for this and not good for libraries without extra work.
Stop saying that -nostartfiles kills off newlib, it just disables the standard startup code which is completely useless for a shared library anyway as it's not run like an executable.
Just add the following code in your libInit() function:
and then this code in your libExpunge() function:
And of course you need the following global variables:
Well it did tell you the correct spelling if you had bothered to take a look at the linker errors:
I only said it once! But it removes all links to it. If I use -nostartfiles as a base and try to build link libss on top I can never get Newlib back.
Yes, I'm aware of what I need to add to have Newlib used in a library.
You don't have to take my sarcasm seriously. ;-)
If it really did that then you would have more (and other) undefined references instead of only the few ones for INewlib you are getting now. Just replace -nostartfiles with -nostdlib and you will see.
So what's the problem?
I did and it works as a base with link libs on top. By itself math functions fail but adding -lc brings them back in.
There's been no problem since I found what the issue is. But Newlib can't be used this way without manual intervention.
I have my own self-written Libraries and never ran into this problem,
maybe taking a look at them would help simplify the work needed as I also only need to retain the Interface Pointers instead of the Library Bases in structures... due to the LibraryBase being IN the Interface as part of it's data area...
Maybe that kind of open sourced reference work will help in fixing the problem as I also provide a full GNUmakefile set for working with Make