This text tries to explain the steps to port gcc 3.3.6 from original sources to a working MiNT port. Current gcc version for MiNT is 2.95.3, albeit working, a more recent version can be needed to compile recent software.
You need original gcc 3.3.6 archive. The archive decompress to a 185 MB of source directory. You will also need autoconf and automake to rebuild needed Makefile.in and configure scripts.
$ tar xvjf gcc-3.3.6.tar.bz2 $ mkdir gcc-3.3.6-mint
You also need a standard C library for the target, like mintlib for example (both standard and debugging versions), because gcc will need to build some stuff for the target (like libiberty and libgcc libraries). You can retrieve current mintlib development files from Sparemint website. They are in RPM format but you can convert them to tar.gz by using alien program.You need to unpack mintlib at the final place ($TARGETPATH/m68k-atari-mint). You should have headers in include subdir, and lib in another subdir.
You also need binutils to create MiNT binaries/libraries. We will start from our previous patch for C language support, so apply it before going further.
Note: TARGETPATH is a directory where gcc-mint will be installed. We modify the PATH variable so the build process will find the binutils needed to build MiNT binaries. We will configure gcc with C language support atm. Change the '/path/to/mintlib' to the absolute path to where you unpacked mintlib development files. This time we add c++ to the list of languages to be built.
$ mkdir gcc-3.3.6-mint $ cd gcc-3.3.6-mint $ export PATH=${TARGETPATH}/bin:PATH $ ../gcc-3.3.6/configure --prefix=${TARGETPATH} --target=m68k-atari-mint --enable-languages="c,c++" --with-sysroot=${TARGETPATH}/m68k-atari-mint $ make
This time, there are many errors, which are all related to libstdc++. This is
the base C++ library, and MiNT support needs to be added to it.
We have these errors, related to missing ctype (character type) definitions:
In file included from libstdc++-v3/include/bits/locale_facets.h:166, from libstdc++-v3/include/bits/basic_ios.h:44, from libstdc++-v3/include/ios:51, from libstdc++-v3/include/ostream:45, from libstdc++-v3/include/bitset:58, from ../../../../../gcc-3.3.6-new/libstdc++-v3/src/bitset.cc:43: libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:46: error: `_U' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:47: error: `_L' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:48: error: `_U' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:48: error: `_L' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:49: error: `_N' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:50: error: `_X' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:50: error: `_N' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:51: error: `_S' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:52: error: `_P' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:52: error: `_U' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:52: error: `_L' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:52: error: `_N' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:52: error: `_B' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:53: error: `_P' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:53: error: `_U' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:53: error: `_L' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:53: error: `_N' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:54: error: `_C' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:55: error: `_P' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:56: error: `_U' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:56: error: `_L' was not declared in this scope libstdc++-v3/include/m68k-atari-mint/bits/ctype_base.h:56: error: `_N' was not declared in this scope
And we have these errors, related to missing math functions:
In file included from libstdc++-v3/include/bits/locale_facets.tcc:41, from libstdc++-v3/include/locale:47, from libstdc++-v3/include/bits/ostream.tcc:37, from libstdc++-v3/include/ostream:535, from libstdc++-v3/include/bitset:58, from ../../../../../gcc-3.3.6-new/libstdc++-v3/src/bitset.cc:43: libstdc++-v3/include/cmath:107: error: `acosf' not declared libstdc++-v3/include/cmath:110: error: `asinf' not declared libstdc++-v3/include/cmath:113: error: `atanf' not declared libstdc++-v3/include/cmath:116: error: `atan2f' not declared libstdc++-v3/include/cmath:119: error: `ceilf' not declared libstdc++-v3/include/cmath:122: error: `coshf' not declared libstdc++-v3/include/cmath:125: error: `expf' not declared libstdc++-v3/include/cmath:128: error: `floorf' not declared libstdc++-v3/include/cmath:131: error: `fmodf' not declared libstdc++-v3/include/cmath:134: error: `frexpf' not declared libstdc++-v3/include/cmath:137: error: `ldexpf' not declared libstdc++-v3/include/cmath:140: error: `logf' not declared libstdc++-v3/include/cmath:143: error: `log10f' not declared libstdc++-v3/include/cmath:146: error: `modff' not declared libstdc++-v3/include/cmath:149: error: `powf' not declared libstdc++-v3/include/cmath:152: error: `sinhf' not declared libstdc++-v3/include/cmath:155: error: `tanf' not declared libstdc++-v3/include/cmath:158: error: `tanhf' not declared libstdc++-v3/include/cmath: In function `float std::acos(float)': libstdc++-v3/include/cmath:184: error: `acosf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::asin(float)': libstdc++-v3/include/cmath:204: error: `asinf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::atan(float)': libstdc++-v3/include/cmath:222: error: `atanf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::atan2(float, float)': libstdc++-v3/include/cmath:240: error: `atan2f' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::ceil(float)': libstdc++-v3/include/cmath:260: error: `ceilf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::cosh(float)': libstdc++-v3/include/cmath:288: error: `coshf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::exp(float)': libstdc++-v3/include/cmath:306: error: `expf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::floor(float)': libstdc++-v3/include/cmath:334: error: `floorf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::fmod(float, float)': libstdc++-v3/include/cmath:352: error: `fmodf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::frexp(float, int*)': libstdc++-v3/include/cmath:372: error: `frexpf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::ldexp(float, int)': libstdc++-v3/include/cmath:391: error: `ldexpf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::log(float)': libstdc++-v3/include/cmath:411: error: `logf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::log10(float)': libstdc++-v3/include/cmath:429: error: `log10f' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::modf(float, float*)': libstdc++-v3/include/cmath:447: error: `modff' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::pow(float, float)': libstdc++-v3/include/cmath:486: error: `powf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::sinh(float)': libstdc++-v3/include/cmath:528: error: `sinhf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::tan(float)': libstdc++-v3/include/cmath:556: error: `tanf' undeclared in namespace `__gnu_cxx::__c99_binding' libstdc++-v3/include/cmath: In function `float std::tanh(float)': libstdc++-v3/include/cmath:574: error: `tanhf' undeclared in namespace `__gnu_cxx::__c99_binding' make[6]: *** [bitset.lo] Erreur 1 make[6]: Leaving directory `gcc-3.3.6-mint/m68k-atari-mint/m68020/libstdc++-v3/src' make[5]: *** [all-recursive] Erreur 1 make[5]: Leaving directory `gcc-3.3.6-mint/m68k-atari-mint/m68020/libstdc++-v3' make[4]: *** [all-recursive-am] Erreur 2 make[4]: Leaving directory `gcc-3.3.6-mint/m68k-atari-mint/m68020/libstdc++-v3' make[3]: *** [multi-do] Erreur 1 make[3]: Leaving directory `gcc-3.3.6-mint/m68k-atari-mint/libstdc++-v3' make[2]: *** [all-multi] Erreur 2 make[2]: Leaving directory `gcc-3.3.6-mint/m68k-atari-mint/libstdc++-v3' make[1]: *** [all-recursive-am] Erreur 2 make[1]: Leaving directory `gcc-3.3.6-mint/m68k-atari-mint/libstdc++-v3' make: *** [all-target-libstdc++-v3] Erreur 2
The biggest part of the work will be done in libstdc++-v3 sub directory. There is a docs sub dir if you want to know more about this library. You should read libstdc++-v3/docs/html/17_intro/porting.html as a starting point.
the config/os/generic subdir used as default does not suit us, so we need to create a new config/os/mint, and make configure use it. This is done in configure.target, case "${target_os}" stuff:
mint*) os_include_dir="os/mint" ;;
As we are building a cross-compiler, configure.in will have to be modified. Search for case "${target}", it will default to newlib usage for libc, and we need/want mintlib. This is the first step, it will be filled later.
*-mint*) os_include_dir="os/mint" ;;
Beware: there is a second case "${target}" switch around line 290!
*-mint*) ;;
So we can create mint subdir in config/os. Don't forget to also run autoconf in libstdc++-v3 subdir when you modify configure.in (Note: autoconf 2.13 required for it).
$ make make[6]: *** No rule to make target « libstdc++-v3/config/os/mint/ctype_base.h », needed for « stamp-target ». Stop.
We need to have a look at mintlib's include/ctype.h to know what to define.
This one is easy, we just take types from mintlib/include/ctype.h, and inspired from config/os/generic/ctype_base.h, used as a template.
// Mint C types, taken from mintlib-0.56/include/ctype.h struct ctype_base { // Non-standard typedefs. typedef const int* __to_type; // NB: Offsets into ctype::_M_table force a particular size // on the mask type. Because of this, we don't use an enum. typedef unsigned int mask; static const mask upper = _CTu; static const mask lower = _CTl; static const mask alpha = _CTu | _CTl; static const mask digit = _CTd; static const mask xdigit = _CTx; static const mask space = _CTs; static const mask print = _CTP; static const mask graph = _CTg; static const mask cntrl = _CTc; static const mask punct = _CTp; static const mask alnum = _CTd | _CTu | _CTl ; };
Will try to explain this file later.
bool ctype:: is(mask __m, char __c) const { return _ctype[(unsigned char)((__c) + 1)] & __m; } const char* ctype :: is(const char* __low, const char* __high, mask* __vec) const { while (__low < __high) *__vec++ = _ctype[(*__low++) + 1] ; return __high; } const char* ctype :: scan_is(mask __m, const char* __low, const char* __high) const { while (__low < __high && !this->is(__m, *__low)) ++__low; return __low; } const char* ctype :: scan_not(mask __m, const char* __low, const char* __high) const { while (__low < __high && this->is(__m, *__low) != 0) ++__low; return __low; }
Will try to explain this file later.
// Information as gleaned from /usr/include/ctype.h const ctype_base::mask* ctype::classic_table() throw() { return 0; } ctype ::ctype(__c_locale, const mask* __table, bool __del, size_t __refs) : __ctype_abstract_base (__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) { } ctype ::ctype(const mask* __table, bool __del, size_t __refs) : __ctype_abstract_base (__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) { } char ctype ::do_toupper(char __c) const { return ::toupper((int) __c); } const char* ctype ::do_toupper(char* __low, const char* __high) const { while (__low < __high) { *__low = ::toupper((int) *__low); ++__low; } return __high; } char ctype ::do_tolower(char __c) const { return ::tolower((int) __c); } const char* ctype ::do_tolower(char* __low, const char* __high) const { while (__low < __high) { *__low = ::tolower((int) *__low); ++__low; } return __high; }
Some OS-dependent definitions.
// These taken from mintlib-0.56/include/unistd.h #define __off_t off_t #define __off64_t off64_t #define __ssize_t ssize_t
As generic files where copied to build directory, we need to delete the current libstdc++-v3 build dir. And just tell make to only rebuild it.
$ rm -rf `find m68k-atari-mint -name libstdc++-v3` $ make all-target-libstdc++-v3
OK, character types are defined, build stops at math functions.
This is done in configure.in (the section we started to create, remember). I just shamelessly copied the section of a different OS. We add this in the first case "$target" switch:
*-mint*) AC_CHECK_HEADERS([sys/types.h locale.h]) GLIBCPP_CHECK_LINKER_FEATURES GLIBCPP_CHECK_COMPLEX_MATH_SUPPORT GLIBCPP_CHECK_WCHAR_T_SUPPORT os_include_dir="os/mint" ;;
Note: you can build the 'bootstrap' target (if you are not cross-compiling),
which is a 3 pass compilation: (1)build gcc with current compiler (2) build gcc
with gcc compiled at stage 1 (3) build gcc with gcc compiled at stage 2, and compare
the two binaries. If they are not the same, gcc produced an incorrect program.
But as we are building a cross-compiler, we can't do that, so we just run make.
$ make
You will notice many warning messages, specially when building the floating point stuff.
$ make install
Apparently the build is ok, but we must be sure the code generated/linked by
all these tools is right. That's the hard part. Most of these tools have testsuite,
but maybe it requires writing MiNT tests as well.
Here is the final patch:
gcc-cpp-3.3.6-mint-1.diff.gz