GCC 3.2.3 / 3.4.6 - almost there!

Started by t-rexky, December 01, 2011, 10:31:06 PM

Previous topic - Next topic

t-rexky

Greetings,

I've had way too much "free" time on my hands lately and one of my projects was playing with some new compiles...

Ultimately I managed to build gcc-3.2.3 on m68k under NS3.3 through all three bootstrap stages, and the compiler works and compares stage2 to stage3 just fine.  Note that to build three stages of c, c++, objc and f77 takes almost 13 hours on my turbo color :-)

Unfortunately things somewhat fall apart when it comes to building the libstdc++ libraries.  In fact I coaxed the libraries to build with a really brute force approach, but linking c++ fails due to undefined symbols, specifically access(), strxfrm(), strdup() and write(), most of which I believe are in the NeXT posix library.  I also get ___gxx_personality_sj0 and ___cxa_call_unexpected as undefined when trying to link  the abi_check testsuite program.

Now, I am not a developer or even a programmer.  I only used to do some rudimentary C work years in the past when I was working on my mechanical engineering degree.  So I am a bit stuck.

It would be great if a real developer or anyone familiar with GCC in general could assist to make this happen.  Based on what I have seen I think even newer GCC 3 branches would be possible if we could find a workaround for the broken NeXT libraries.

t-rexky

oneNeXT

I'm not a gcc specialist but can you make public what you've already done ?
Maybe i can give a little help !

t-rexky

Thank you for your response!  I can most certainly summarize what I have done.  Here is a list of the critical items - you will notice that getting the compilers to build is almost trivial, but the runtime libraries are somewhat more demanding.

[list=1]
  • The biggest stumbling block was the new pre-processor that the gcc-3 branch introduced.  This pre-processor seems to break pretty hard on the NeXT headers, specifically on the ARCH_INCLUDE() macro.  Considering that the chance of more architectures being introduced to NEXTSTEP is pretty slim :-), I edited all of the header files to disable the ARCH_INCLUDE() macro and instead explicitly list all architecture.  As an example, my ansi/math.h header now looks like this:

    /* HISTORY
    *
    * 2011-11-28   t-rexky
    *      Disabled the NeXT ARCH_INCLUDE() macro.
    */

    #ifndef _ANSI_MACHINE_MATH_H
    #define _ANSI_MACHINE_MATH_H

    /*
    * ARCH_INCLUDE.h provides a facility for including architecture
    * specific files without enumerating every possible architecture
    * in this file.
    *
    * #include <architecture/ARCH_INCLUDE.h>
    *
    * #include ARCH_INCLUDE(ansi/, math.h)
    *
    * Disable the NeXT ARCH_INCLUDE() macro and instead enumerate
    * every possible architecture.
    */
    #ifdef m68k
    #include <ansi/m68k/math.h>

    #elif defined i386
    #include <ansi/i386/math.h>

    #elif defined hppa
    #include <ansi/hppa/math.h>

    #elif defined sparc
    #include <ansi/sparc/math.h>

    #endif /* m68k */

    #endif /* _ANSI_MACHINE_MATH_H */


    This change to all the affected headers allows the gcc-3 pre-processor to process all the headers.  I would be more than happy to supply a TAR of the modified /NextDeveloper/Headers for NS3.3 to save you time.

  • As a starting point and to practice I built and installed gcc-2.95.3 (with the headers modified per the above).  I also installed most of the kb7sqi's packages, particularly bash, sed, bison, flex and gmake.

  • Using bash, I specified the following environment variables:
    SHELL=/usr/local/bin/bash
    export SHELL
    CONFIG_SHELL=/usr/local/bin/bash
    export CONFIG_SHELL


  • I configured the build from a separate directory as follows:
    .../gcc-3.2.3/configure --prefix=/usr/local \
    --enable-languages='c,objc,c++,f77' \
    --disable-shared --disable-threads --enable-cpp \
    --enable-obsolete m68k-next-nextstep3


  • If you were to bootstrap the compiler now it would fail while processing the crtstuff.c file into crtend.o because our architecture does not support section attributes.  I therefore edited the .../gcc-3.2.3/gcc/crtstuff.c by mixing in some code from an older gcc-3 version to remove the section attribute.  This is a complete hack, BTW, but I hope it will do the job:
    603,606c603,623
    < STATIC int __FRAME_END__[]
    <      __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
    <                    aligned(4)))
    <      = { 0 };
    ---
    >
    > /*
    >  * Revert to previous version of the code to avoid use
    >  * of section attribute and allow compilation on NeXT
    >  *
    >  * STATIC int __FRAME_END__[]
    >  *    __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
    >  *                 aligned(4)))
    >  *    = { 0 };
    >  */
    >
    > #ifndef EH_FRAME_SECTION_ASM_OP
    > #define EH_FRAME_SECTION_ASM_OP "\t.section __TEXT,__eh_frame,regular"
    > #endif /* EH_FRAME_SECTION_ASM_OP */
    >
    > /* Force cc1 to switch to .data section.  */
    > static void * force_to_data[1] __attribute__ ((__unused__)) = { };
    >
    > typedef unsigned int ui32 __attribute__ ((mode (SI)));
    > asm (EH_FRAME_SECTION_ASM_OP);
    > static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };


  • Now we are finally ready for the bootstrap, with a few provisos.  There are subsequent issues with building the libstdc++ library that probably require some additional tweaks to the gcc configuration for the NeXT, but I do not know enough about gcc.  So for now I continued hacking along:
    gmake CFLAGS='-O' LIBCFLAGS='-g -O2' \
    LIBCXXFLAGS='-g -O2 -fno-implicit-templates' bootstrap

    Believe it or not, this will now successfully complete and compare all three stages of the build!  But be prepared to wait for 12+ hours if you are doing this on m68k like I was.[/list:o]

    Beyond this it gets a bit hairy once cc1plus starts building the runtime library.  Now, please be gentle with me, since as I mentioned before I have never written a single line of C++ code.  I used to "play" a bit only with C for my engineering work, mostly because I hated Fortran with a passion 8)...  Here are my rough notes on what I have done to complete the libstdc++ build.  They are in the format of [error_message_excerpt followed by (my_braindead_hack):

    ../../../../gcc-3.2.3/libstdc++-v3/libmath/signbit.c: In function `__signbit':
    ../../../../gcc-3.2.3/libstdc++-v3/libmath/signbit.c:39: `ieee_double_shape_type' undeclared (first use in this function)

    (brute force #define BIG_ENDIAN 4321 & #define BYTE_ORDER BIG_ENDIAN in mathconf.h)


    In file included from ../../../../gcc-3.2.3/libstdc++-v3/libsupc++/eh_alloc.cc:34:
    /Storage2/gcc-3.2.3-bld/m68k-next-nextstep3/libstdc++-v3/include/cstring:89: `strxfrm' not declared

    (brute force declare size_t strxfrm(char *s1, const char *s2, size_t n); in cstring)


    ../../../../gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc:49: `write' undeclared (first use this function)

    (brute force typedef int ssize_t; typedef unsigned long size_t; extern ssize_t write(int fildes, const void *buf, size_t nbyte); in pure.cc)


    /Storage2/gcc-3.2.3-bld/m68k-next-nextstep3/libstdc++-v3/include/cstdio:99: syntax error before `;' token

    (brute force #ifdef FILE #undef FILE #endif typedef struct _iobuf FILE; in cstdio)


    This next one was fun to figure out and I almost threw in the towel!  I could not understand why the compiler was producing Motorola syntax while it was configured with MIT syntax and there was no single occurrence of 'jbne' string in cc1plus!  An hour or two later I discovered that the assembler operator was defined in atomicity.h which is oblivious to the Motorola/MIT syntax differences.  This is the change that will likely need to be implemented somewhere in the gcc/config NeXT specific files for a permanent fix:
    complex_io.cc
    /usr/tmp/ccdowAQh.s:1208:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:1520:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:1642:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:1872:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:2425:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:2639:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:3153:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:3367:"Unknown operator" -- Statement 'jbne 1b' ignored
    /usr/tmp/ccdowAQh.s:3533:"Unknown operator" -- Statement 'jbne 1b' ignored

    (temporary hack - add #ifndef __mc68040__ #define __mc68040__ #endif to ./gcc-3.2.3-bld/m68k-next-nextstep3/libstdc++-v3/include/m68k-next-nextstep3/bits/atomicity.h)


    This one I also could not figure out, so I tried another brute force technique and it worked:
    In file included from /Storage2/gcc-3.2.3-bld/m68k-next-nextstep3/libstdc++-v3/include/ext/rope:60, from ../../../../gcc-3.2.3/libstdc++-v3/src/ext-inst.cc:34:
    /Storage2/gcc-3.2.3-bld/m68k-next-nextstep3/libstdc++-v3/include/ext/stl_rope.h:909:18: macro "index" requires 2 arguments, but only 1 given

    (brute force #ifdef index #undef index #endif in stl_rope.h jus ahead of index())


    ../../../../gcc-3.2.3/libstdc++-v3/src/locale.cc:203: `strdup' undeclared (first use this function)

    (replace with _partial_ locale.cc from GCC branch 3.3 CVS#76124 that is not using strdup())


    NextDeveloper/Headers/ansi/string.h:52: too few arguments to function `size_t strcoll(char*, long unsigned int, const char*)'
    collate_members.cc:46: at this point in file

    (real hack!!! replace strcoll() by strcmp() in collate_members.cc)


    time_members.cc: In member function `void std::__timepunct<_CharT>::_M_put(_CharT*, long unsigned int, const _CharT*, const tm*) const [with _CharT = char]':
    time_members.cc:47: `strdup' undeclared (first use this function)

    (added extern char * strdup(char *s); to time_members.cc)


    c++locale.cc: In function `void std::__convert_to_v(const char*, _Tv&, std::_Ios_Iostate&, int* const&, int) [with _Tv = float]':
    c++locale.cc:123: `strdup' undeclared (first use this function)

    (added extern char * strdup(char *s); to c++locale.cc)


    ../../../../gcc-3.2.3/libstdc++-v3/testsuite/abi_check.cc: In function `int main(int, char**)':
    ../../../../gcc-3.2.3/libstdc++-v3/testsuite/abi_check.cc:295: `R_OK' undeclared (first use this function)

    (brute force include #define R_OK 4 and extern int access(const char *path, int amode); in abi_check.cc)


    All of the above hacks will conclude the build of the libstdc++ library, but of course linking anything to it will fail because we are missing access(), strxfrm(), strdup() and write() in the NeXT libsys_p library:

    /bin/ld: Undefined symbols:
    access(char const*, int)
    ___gxx_personality_sj0
    ___cxa_call_unexpected
    strxfrm(char*, char const*, unsigned long)
    strdup(char*)
    write(int, void const*, unsigned long)
    _strdup


    And this is where I run out of ideas.  Obviously we need to create an additional compatibility library that includes these functions, but I have no idea how to merge this with the gcc project to make it work seamlessly.  I am also a bit concerned with the linker complaining about __gxx_personality_sj0 and __cxa_call_unexpected being undefined.

    I also considered posting on the gcc-help mailing list to see if anyone there can help with how to merge such changes with an existing gcc configuration.  Personally I don't care if the gcc source is hacked and not portable after these changes, as long as the resultant compilers all work...

    Oh, and why am I doing this all?  I hope that availability of a more modern compiler for NEXTSTEP reinvigorates the community a bit to allow porting of some more recent tools.  I probably will not be doing this as I do not know enough about software development.  But I hope that others might benefit from this.

    Thank you!

    Quote from: "oneNeXT"I'm not a gcc specialist but can you make public what you've already done ?
    Maybe i can give a little help !

Andreas

Quote from: "t-rexky"
It would be great if a real developer or anyone familiar with GCC in general could assist to make this happen.  Based on what I have seen I think even newer GCC 3 branches would be possible if we could find a workaround for the broken NeXT libraries.

I can't answer anything, but maybe Rex Dieter's work is s omething usable? AFAIK egcs is a gcc fork ~2.7, ~2,8 and has later merged back to gcc.

http://www.math.unl.edu/~rdieter1/OpenStep/Developer/

t-rexky

Thank you for the pointer Andreas.  I reviewed Rex Dieter's site and also spent a considerable amount of time looking for related info on the net...

I reconfigured the 3.2.3 build to only supply the C compiler, and I have to report that it works fine.  In fact, I used it to build a number of other GNU tools and everything seems to be OK.  The one thing that I have not yet tested is full support for the (broken) POSIX...

Regarding geting the C++ portion working, I am planning on posting something on the GCC listservers, unless I find some documentation that explains how to include additional functions in the C++ library to satisfy the missing NeXT dependencies.

Unfortunately I have to report that 3.2.3 is likely the latest GCC branch that we can build without a significant effort.  I learnt the hard way that GCC 3.3 introduced a completely revamped method for hooking into the system specific stuff...  Coincidentally GCC 3.3 removed a huge list of obsoleted systems from its support - no surprise.  So if anyone would want to put more effort into building later versions of GCC, we might as well concentrate on GCC4.x.

Now, if we could only fix the POSIX implementation in 3.3, things would be a whole lot simpler to port.

In the meantime I also built some support tools such as gawk, sed, bash, etc.  I am going to submit what I built to the file archives for others to use.    Everything was built as m68k binaries only though.  One day I might try to reconstruct my efforts on OS42 Intel...

Quote from: "Andreas"
Quote from: "t-rexky"
It would be great if a real developer or anyone familiar with GCC in general could assist to make this happen.  Based on what I have seen I think even newer GCC 3 branches would be possible if we could find a workaround for the broken NeXT libraries.

I can't answer anything, but maybe Rex Dieter's work is s omething usable? AFAIK egcs is a gcc fork ~2.7, ~2,8 and has later merged back to gcc.

http://www.math.unl.edu/~rdieter1/OpenStep/Developer/

gtnicol

Perhaps porting lcc would be worth the effort? It's usually a lot faster and less resource hungry than gcc.

t-rexky

This suggestion sounds quite intriguing...  I had a quick look at the lcc site and noticed that it supports the i386 architecture, although with NASM as opposed to GAS.  We would be out of luck for the m68k, which the purist in me is currently focusing on :-).

DISCLAIMER: I know absolutely nothing about compiler technologies - just returned to tinkering with code hobby-style...

Quote from: "gtnicol"Perhaps porting lcc would be worth the effort? It's usually a lot faster and less resource hungry than gcc.

oneNeXT

Quote from: "t-rexky"Everything was built as m68k binaries only though.  One day I might try to reconstruct my efforts on OS42 Intel...

I've started working on intel release...

t-rexky

Awesome news!  I've been plugging away at the m68k build, but I am still far away from a full gcc suite.  However, as I mentioned already I have been successfully using C only 3.2.3 to build quite a few recent GNU tools, such as bash, bison, flex, m4, gawk, etc...

I am not sure how far along you are, but I would suggest using the info on rdieter's site as an excellent guideline and starting point (thank you Andreas).  One other stumbling block might be lacking features of the gas assembler on OS.   I noticed that on OS42 Intel, once the compiler starts using the stage1 tools it chokes on cfg.c with the following error message:

/usr/tmp/ccyIsQNm.s:457:Unknown pseudo-op: .quad

Looking at the Apple open source site, .quad was implemented in cctools-590.32, way past OS.  So, we might need a franken-gas to go with the new compiler.  This issue does not appear on m68k, by the way.

Speaking of which, has anyone ever successfully built the NeXT (g)as from sources?  I noticed that some library sources have not been supplied by NeXT, but are present in the Rhapsody sources...

Quote from: "oneNeXT"I've started working on intel release...

t-rexky

Never mind...  I just managed to manually build the OS42 'as' from the NeXT supplied sources.  The supplied libstuff sources, although incomplete, satisfy all of the i386 'as' dependencies.  Hopefully it is not too difficult to roll-in the newer 'as' sources from a recent OS X revision...

Quote from: "t-rexky"Speaking of which, has anyone ever successfully built the NeXT (g)as from sources?  I noticed that some library sources have not been supplied by NeXT, but are present in the Rhapsody sources...

t-rexky

I actually accidentally came across some m68k port of lcc yesterday...  Now,  I have to search through my browser history file to see where it was...

Quote from: "t-rexky"This suggestion sounds quite intriguing...  I had a quick look at the lcc site and noticed that it supports the i386 architecture, although with NASM as opposed to GAS.  We would be out of luck for the m68k, which the purist in me is currently focusing on :-).

Noth

Quote from: "t-rexky"I actually accidentally came across some m68k port of lcc yesterday...  Now,  I have to search through my browser history file to see where it was...

Quote from: "t-rexky"This suggestion sounds quite intriguing...  I had a quick look at the lcc site and noticed that it supports the i386 architecture, although with NASM as opposed to GAS.  We would be out of luck for the m68k, which the purist in me is currently focusing on :-).

It wouldn't be this would it? http://ftp.gwdg.de/pub/misc/languages/lcc/contrib/
NeXT Cube 040 (NeXTSTEP 3.3), SUN SparcStation5 (NeXTSTEP 3.3), SGI Indigo2 R10000 (IRIX 6.5.22), SGI VSW320 (Windows 2000/Slakware 9.1)

gtnicol

From memory there was another project, ldb, which was a retargetable debugger too.

t-rexky

It was actually an early Amiga port that I found originally.  Perhaps it is based on the info that you found?

http://ftp.back2roots.org/geekgadgets/amiga/m68k/alpha/lcc/00readme

Quote from: "Noth"
It wouldn't be this would it? http://ftp.gwdg.de/pub/misc/languages/lcc/contrib/

t-rexky

Just for the sake of sharing the knowledge...

After going through a few chainsaws and sledge hammers I managed to build a new franken-as that uses code from Apple's cctools-622.9.  And it seems to work fine in building the GCC 3.2.3 binaries.  The approach I took was to compare the differences, use all the new code except the write_object module since the new object format would not be recognized by the OPENSTEP linker.  I also eliminated all the references to architectures that are irrelevant for us, such as PPC, etc., in order to allow a successful compile.

It's really just an ugly proof of concept rather then a port, but it shows that it can be done.

Quote from: "t-rexky"Never mind...  I just managed to manually build the OS42 'as' from the NeXT supplied sources.  The supplied libstuff sources, although incomplete, satisfy all of the i386 'as' dependencies.  Hopefully it is not too difficult to roll-in the newer 'as' sources from a recent OS X revision...

Quote from: "t-rexky"Speaking of which, has anyone ever successfully built the NeXT (g)as from sources?  I noticed that some library sources have not been supplied by NeXT, but are present in the Rhapsody sources...