From: Scott Blackman Newsgroups: comp.os.msdos.djgpp Subject: Here are egcs and pgcc for DJGPP including g77 Date: Thu, 30 Jul 1998 09:45:13 -0500 Organization: Vanderbilt University Lines: 842 Message-ID: <35C086F9.C3F@vanderbilt.edu> NNTP-Posting-Host: 160.129.157.110 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk A while ago, with some help from Andrew Crabtree, I managed to compile egcs and pgcc (including g77) for DJGPP. Recently, somebody asked me for those instructions. Well, here they are. I did it in a very convoluted way, by building a cross- compiler under Linux, and then using the cross-compiler to make the DOS executables. I have two shell scripts: the first which makes the cross-compiler, and the second which makes the DOS-native compiler. They are tacked onto the end of this post. I would be happy to provide .ZIP files of egcs or pgcc (C, C++, G77) compilers for DJGPP, if somebody can tell me how to contribute them. Scott Blackman scott DOT blackman AT vanderbilt DOT edu ---------------------------------------------------------- #!/bin/sh # # Make gcc-dos (a cross-compiler for MS-DOS running under Linux) # # Version 1.0 4/17/1998 Scott Blackman # # Requirements: # You need to have a working C compiler (preferably the same version # as the cross-compiler, i.e. egcs- or pgcc-${EGCS_VER}) # This script needs write permissions to $PREFIX # # Credits: # The overall plan is based on the DJGPP FAQ answer 22.7 about building # a cross-compiler. # http://www.delorie.com/djgpp/v2faq/faq168.html#Cross-DJGPP # # For compiling pgcc, I incorporated information from Andrew Crabtree's # binary distribution of pgcc for DJGPP. See his readme for other # useful information. # http://www.goof.com/pcg/binaries-djgpp.html # or # # PGCC NOTE: When peep-spills is enabled (starting at -O3), the fortran # f/intrin.o compiles incorrectly, causing the MS-DOS native # f771 to segfault. So I routinely disable this optimization. # if [ x$1 != xpgcc -a x$1 != xegcs ]; then echo Please specify egcs or pgcc as the first argument. exit 1 fi if [ x$1 == xpgcc ]; then echo building pgcc PGCC=1 else echo building egcs fi # set -e set -x # # 1. Set up the variables to control how it all works # if [ $PGCC ]; then PREFIX=/usr/local/pgcc-local GCC_VERSION=pgcc-2.90.29 CFLAGS_FOR_BUILD="-O6 -fno-peep-spills -mpentium" # If DJLIBS is set, copy the libraries from that dir instead of from djcrx. DJLIBS=/dos/d/djgpp/lib-pgcc else PREFIX=/usr/local/egcs-local GCC_VERSION=egcs-2.90.29 CFLAGS_FOR_BUILD="-O3 -m486" # If DJLIBS is set, copy the libraries from that dir instead of from djcrx. DJLIBS=/dos/d/djgpp/lib fi EGCS_VER=1.0.3a PGCC_VER=1.0.3 BINUTILS_VER=2.8.1 DJCRX=/dos/d/djgpp1/djcrx201.zip DJLSR=/dos/d/djgpp1/djlsr201.zip CC_FOR_BUILD=$PREFIX/bin/gcc CC_FOR_CROSS=$PREFIX/i386-go32-msdos/bin/gcc AR_CROSS=$PREFIX/i386-go32-msdos/bin/ar # Symbolic links to (p)gcc and (p)g77 are put into $BINDIR if it is set BINDIR=/home/blackman/bin BASE=`pwd` cd $BASE # # 2. Build and install a binutils targeted to i386-coff-go32 # tar -xzf binutils-${BINUTILS_VER}.tar.gz cd binutils-${BINUTILS_VER} env CC=$CC_FOR_BUILD ./configure --target=i386-coff-go32 --prefix=$PREFIX make CFLAGS="$CFLAGS_FOR_BUILD" mkdir -p $PREFIX/i386-go32-msdos/bin cd binutils cp addr2line ar c++filt objcopy objdump ranlib size strings \ $PREFIX/i386-go32-msdos/bin cp nm.new $PREFIX/i386-go32-msdos/bin/nm cp strip.new $PREFIX/i386-go32-msdos/bin/strip cd ../gas cp as.new $PREFIX/i386-go32-msdos/bin/as cp gasp.new $PREFIX/i386-go32-msdos/bin/gasp cd ../ld cp ld.new $PREFIX/i386-go32-msdos/bin/ld # # Clean up # cd ../.. rm -rf binutils-${BINUTILS_VER} # cd $PREFIX/i386-go32-msdos/bin strip addr2line ar c++filt objcopy objdump ranlib size \ strings nm strip as gasp ld # # 3. Set up the cross-compiler's auxiliary files in $PREFIX # mkdir -p $PREFIX/djgpp cd $PREFIX/djgpp unzip -a $DJCRX # # patch the djgpp.djl per the djgpp faq 22.7 # cd lib patch < ../cross/patch.lib rm djgpp.djl.orig # # If pgcc, patch the specs file to be like Andrew Crabtree's pgcc distribution # if [ $PGCC ]; then # no quotes around !EOF! to evaluate $GCC_VERSION patch specs << !EOF! --- specs.orig Wed Sep 11 20:41:04 1996 +++ specs Thu Apr 16 11:11:56 1998 @@ -5,10 +5,10 @@ *cpp: -%{posix:-D_POSIX_SOURCE} +%(cpp_cpu) %[cpp_cpu] %{posix:-D_POSIX_SOURCE} *cc1: - +%(cc1_spec) *cc1plus: @@ -30,8 +30,11 @@ *lib: -lc +*libgcc: +-lgcc + *startfile: -%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}} +%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}} *switches_need_spaces: @@ -40,8 +43,29 @@ %{funsigned-char:-D__CHAR_UNSIGNED__} *predefines: --Dunix -Di386 -DGO32 -DMSDOS -DDJGPP=2 -DDJGPP_MINOR=1 +-Dunix -Di386 -DGO32 -DMSDOS -DDJGPP=2 -DDJGPP_MINOR=1 -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386) *cross_compile: 0 + +*version: +$GCC_VERSION + +*multilib: +. ; + +*multilib_defaults: + + +*multilib_extra: + + +*multilib_matches: + + +*cpp_cpu: +-Di386 -Di586 -Asystem(unix) -Acpu(i386) -Amachine(i386) %{mcpu=i486:-Di486} %{m486:-Di486} %{mpentium:-Dpentium -Di586} %{mcpu=pentium:-Dpentium -Di586} %{mamdk5:-DAMDK5 -Dpentium -Di586} %{mcpu=amdk5:-DAMDK5 -Dpentium -Di586} %{mamdk6:-DAMDK6 -Dpentium -Di586} %{mcpu=amdk6:-DAMDK6 -Dpentium -Di586} %{mcyrix:-DCYRIX -Dpentium -Di586} %{mcpu=cyrix:-DCYRIX -Dpentium -Di586} %{mpentiumpro:-Dpentiumpro -Di686} %{mcpu=pentiumpro:-Dpentiumpro -Di686} + +*cc1_cpu: +%{!mcpu*: %{m386:-mcpu=i386 -march=i386} %{mno-486:-mcpu=i386 -march=i386} %{m486:-mcpu=i486 -march=i486} %{mno-386:-mcpu=i486 -march=i486} %{mno-pentium:-mcpu=i486 -march=i486} %{mpentium:-mcpu=pentium} %{mno-pentiumpro:-mcpu=pentium} %{mamdk5:-mcpu=amdk5 -march=i486} %{mamdk6:-mcpu=amdk6 -march=i486} %{mcyrix:-mcpu=cyrix -march=i486} %{mpentiumpro:-mcpu=pentiumpro}} %{ffast-math:%{!mieee-fp:-mno-ieee-fp}} !EOF! fi # # If you have set DJLIBS, then use those libs instead of the ones in djcrx. if [ $DJLIBS ]; then mv libc.a libc-old.a cp -p $DJLIBS/libc.a . mv libm.a libm-old.a cp -p $DJLIBS/libm.a . mv libdbg.a libdbg-old.a cp -p $DJLIBS/libdbg.a . mv libemu.a libemu-old.a cp -p $DJLIBS/libemu.a . mv crt0.o crt0-old.o cp -p $DJLIBS/crt0.o . mv gcrt0.o gcrt0-old.o cp -p $DJLIBS/gcrt0.o . fi # # If pgcc, use either a user-supplied lib, or patch the one from djcrx. # if [ $PGCC ]; then if [ $DJLIBS ]; then ls -l $DJLIBS/libc.a echo Please be sure this libc is okay for pgcc sleep 10 else ls -l libc.a echo THIS IS REPORTED NOT TO WORK WITH PGCC. echo A fixed version will be built after building the cross-compiler. sleep 10 fi fi # # stubify needs to go into gcc-lib/i386-go32-msdos/$GCC_VERSION # instead of $PREFIX/i386-go32-msdos/bin cd $PREFIX/djgpp/src/stub $CC_FOR_BUILD -s $CFLAGS_FOR_BUILD -o stubify stubify.c mkdir -p $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION cp stubify $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION # stubedit is not needed for a working cross-compiler, but it comes in handy, # and we need it for building a native cc1 and f771. $CC_FOR_BUILD -s $CFLAGS_FOR_BUILD -o stubedit stubedit.c cp stubedit $PREFIX/i386-go32-msdos/bin # cd $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION mv $PREFIX/djgpp/lib/* . if [ -d ./include ]; then rm -rf ./include fi mv $PREFIX/djgpp/include . # # If pgcc, patch include/math.h and include/libm/math.h for cc1plus # if [ $PGCC ]; then patch << "!EOF!" --- include/math.h.orig Mon Sep 9 19:28:04 1996 +++ include/math.h Tue Apr 14 08:47:37 1998 @@ -70,7 +70,13 @@ /* These are in libm.a (Cygnus). You must link -lm to get these */ /* See libm/math.h for comments */ +#ifdef __cplusplus +#define exception __math_exception +#endif struct exception { +#ifdef __cplusplus +#undef exception +#endif int type; char *name; double arg1; --- include/libm/math.h.orig Sat Aug 26 20:44:18 1995 +++ include/libm/math.h Tue Apr 14 08:48:09 1998 @@ -67,7 +67,13 @@ #define _XOPEN_ fdlibm_xopen #define _POSIX_ fdlibm_posix +#ifdef __cplusplus +#define exception __math_exception +#endif struct exception { +#ifdef __cplusplus +#undef exception +#endif int type; char *name; double arg1; !EOF! rm include/math.h.orig include/libm/math.h.orig cd .. fi cd $PREFIX rm -r djgpp # # 4. Build and install the cross-compilers: c c++ f77 # cd $BASE tar -xzf egcs-${EGCS_VER}.tar.gz cd egcs-${EGCS_VER} # # If pgcc, apply the pgcc patches # # NOTE: This will fail at the very end of the pgcc-1.0.3 diff file I have, # and you'll have to restart the shell script after editing it to bypass # all the stuff it's already done. Sorry. # if [ $PGCC ]; then gunzip < ../egcs-${EGCS_VER}-pgcc-${PGCC_VER}.diff.gz | patch -p1 -N -E # find . -name \*.rej -print # find . -name \*.orig | xargs rm fi cd gcc env CC="$CC_FOR_BUILD" ./configure --target=i386-go32-msdos --prefix=$PREFIX \ --with-gnu-as --with-gnu-ld # touch libgcc1.a # # Patch the config/i386/go32.h file for building libgcc2.a # cat >go32.diff <<"!EOF!" --- go32.h.orig Mon Aug 11 10:57:16 1997 +++ go32.h Thu Mar 19 17:43:04 1998 @@ -19,6 +19,8 @@ #define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS \ -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)" +#define HAVE_ATEXIT + #undef EXTRA_SECTIONS #define EXTRA_SECTIONS in_ctor, in_dtor !EOF! patch config/i386/go32.h #include + #include /* for _osmajor/_osminor */ /* Global variables */ *************** *** 133,136 **** --- 134,147 ---- size_t __PROXY_LEN = sizeof(__PROXY)-1; + static void + setup_os_version(void) + { + unsigned short v; + v = _get_dos_version(0); /* Get the reported version */ + _osmajor = (v >> 8) & 0xff; /* paranoia */ + _osminor = v & 0xff; + } + + void __crt1_startup(void) *************** *** 139,142 **** --- 150,154 ---- __bss_count ++; __crt0_argv = 0; + setup_os_version(); setup_core_selector(); setup_screens(); !EOF! # # (fixing libc for pgcc) Apply the patch to crt1.c for using pgcc # patch << "!EOF!" --- src/libc/crt0/crt1.c.orig Mon Apr 13 18:14:42 1998 +++ src/libc/crt0/crt1.c Tue Apr 14 07:42:02 1998 @@ -165,6 +165,15 @@ _npxsetup(pn); _crt0_init_mcount(); __main(); - exit(main(__crt0_argc, __crt0_argv, environ)); + asm(" + andl $0xFFFFFFF8,%%esp + pushl %%eax + pushl %0 + pushl %1 + pushl %2 + call _main + pushl %%eax + call _exit + " :: "m" (environ), "m" (__crt0_argv), "m" (__crt0_argc)); } !EOF! # cd src/libc/crt0 make CC=$CC_FOR_CROSS crt1.o cp -p $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION/libc.a \ $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION/libc-nopgcc.a $AR_CROSS rvs $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION/libc.a crt1.o # Done with fixing libc for pgcc rm -r $PREFIX/djgpp fi fi # # 4.2. Build and install the c++ compiler # make LANGUAGES=c++ CFLAGS="$CFLAGS_FOR_BUILD" CC="$CC_FOR_BUILD" # note that cc1plus needs to be in the gcc-lib/$ARCH/$GCC_VERSION strip cc1plus cp cc1plus $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION # # 4.3. Build and install the f77 compiler # # This requires having an already-installed C cross-compiler to # build libf2c.a # # If we just make the g77 compiler now, we'll get an error trying # to build the libf2c.a runtime library (./xgcc cannot produce executables). # Therefore, patch the Makefile to use the newly built gcc cross-compiler # (Be careful with the modification times on Makefile to keep from having # to rebuild the C compiler) # cd $BASE/egcs-${EGCS_VER}/gcc cp -p Makefile Makefile.orig cat >Makefile.diff << "!EOF!" --- Makefile.orig Sun May 3 08:30:34 1998 +++ Makefile Sun May 3 08:30:34 1998 @@ -142,7 +142,7 @@ # The GCC to use for compiling libgcc2.a, enquire, and libgcc1-test. # Usually the one we just built. # Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS). -GCC_FOR_TARGET = ./xgcc -B./ +GCC_FOR_TARGET = insert-prefix-here/i386-go32-msdos/bin/gcc # This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET. # It omits XCFLAGS, and specifies -B./. !EOF! cat Makefile.diff | sed "s#insert-prefix-here#$PREFIX#" | patch Makefile touch -r Makefile.orig Makefile # # Now build and install the g77 compiler and library # make LANGUAGES=f77 CFLAGS="$CFLAGS_FOR_BUILD" CC="$CC_FOR_BUILD" strip f771 cp libf2c.a f771 $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION strip g77 cp g77 $PREFIX/i386-go32-msdos/bin if [ $BINDIR ]; then if [ $PGCC ]; then ln -sf $PREFIX/i386-go32-msdos/bin/g77 $BINDIR/pg77-dos else ln -sf $PREFIX/i386-go32-msdos/bin/g77 $BINDIR/g77-dos fi fi cp -p include/f2c.h $PREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION/include # # Clean up # cd ../.. rm -rf egcs-${EGCS_VER} ------------------------------------------------------------------ #!/bin/sh # # Compile c, c++, and f77 native compilers for MS-DOS (i386-go32-msdos) # Output is a pair of zip files (e.g. pgcc103[bd].zip) of DJGPP executables. # # Version 1.0 4/17/1998 Scott Blackman # # Requirements: # Working native and cross-compilers installed in $CROSSPREFIX # (preferably the same version as being compiled now, i.e. $EGCS_VER) # i586-pc-linux-gnulibc1 (native): gcc cc1 # i386-go32-msdos (cross-compiler for MS-DOS): gcc cc1 cc1plus # The cross-c++ compiler is needed to build the native c++ compiler, # since ./xgcc won't run. # Of course, the appropriate binutils and cross-binutils. # Info-ZIP zip archiver for making a zip file at the end # # Credits: # For compiling pgcc, I incorporated information from Andrew Crabtree's # binary distribution of pgcc for DJGPP. See his readme for other # useful information. # http://www.goof.com/pcg/binaries-djgpp.html # or # # PGCC NOTE: When peep-spills is enabled (starting at -O3), # the fortran file f/intrin.o compiles incorrectly, # causing the f771 to segfault. # if [ x$1 != xpgcc -a x$1 != xegcs ]; then echo Please specify egcs or pgcc as the first argument. exit 1 fi if [ x$1 == xpgcc ]; then echo building pgcc PGCC=1 else echo building egcs fi # set -e set -x # # 1. Set up the variables to control the whole thing # # $PREFIX is meaningless in the MS-DOS executable; set it to something generic PREFIX=/usr/local if [ $PGCC ]; then CROSSPREFIX=/usr/local/pgcc-local GCC_VERSION=pgcc-2.90.29 CFLAGS_FOR_BUILD="-O6 -fno-peep-spills -mpentium" SPECS_PGCC=$CROSSPREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION/specs else CROSSPREFIX=/usr/local/egcs-local GCC_VERSION=egcs-2.90.29 CFLAGS_FOR_BUILD="-O3 -m486" fi EGCS_VER=1.0.3a EGCS_ZIPVER=103 PGCC_VER=1.0.3 PGCC_ZIPVER=103 DJCRX=/dos/d/djgpp1/djcrx201.zip CC_FOR_BUILD=$CROSSPREFIX/i386-go32-msdos/bin/gcc RANLIB_CROSS=$CROSSPREFIX/i386-go32-msdos/bin/ranlib STRIP_CROSS=$CROSSPREFIX/i386-go32-msdos/bin/strip STUBIFY=$CROSSPREFIX/lib/gcc-lib/i386-go32-msdos/$GCC_VERSION/stubify STUBEDIT=$CROSSPREFIX/i386-go32-msdos/bin/stubedit # # 2. Build the MS-DOS native compilers: c c++ f77 # tar -xzf egcs-${EGCS_VER}.tar.gz cd egcs-${EGCS_VER} # # Apply the pgcc patches # # NOTE: This will fail at the very end of the pgcc-1.0.3 diff file I have, # and you'll have to restart the shell script after editing it to bypass # all the stuff it's already done. Sorry. # if [ $PGCC ]; then gunzip < ../egcs-${EGCS_VER}-pgcc-${PGCC_VER}.diff.gz | patch -p1 -N -E # find . -name \*.rej -print # find . -name \*.orig | xargs rm fi # cd gcc env CC=$CC_FOR_BUILD ./configure --prefix=$PREFIX --target=i386-go32-msdos --build=i586-pc-linux-gnulibc1 --host=i386-go32-msdos --with-gnu-as --with-gnu-ld # The --build=i586-pc-linuxgnulibc1 is needed; it guesses wrong otherwise. # # I made 2 changes to Makefile: # 1. Add definitions for build and target into the Makefile. # 2. Change GCC_FOR_TARGET from ./xgcc -B./ to $CC_FOR_BUILD # # no quotes around !EOF! so that $CC_FOR_BUILD gets evaluated. # the backslashes are removed by the evaluation. # cat >Makefile.diff <collect2.c.diff <<"!EOF!" --- collect2.c.orig Sun Feb 22 08:06:35 1998 +++ collect2.c Wed Mar 18 10:26:17 1998 @@ -1,3 +1,4 @@ +#define NO_SYS_SIGLIST /* Collect static initialization info into data structures that can be traversed by C++ initialization and finalization routines. Copyright (C) 1992, 93-7, 1998 Free Software Foundation, Inc. !EOF! patch collect2.c go32.diff <<"!EOF!" --- go32.h.orig Mon Aug 11 10:57:16 1997 +++ go32.h Thu Mar 19 17:43:04 1998 @@ -19,6 +19,8 @@ #define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS \ -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)" +#define HAVE_ATEXIT + #undef EXTRA_SECTIONS #define EXTRA_SECTIONS in_ctor, in_dtor !EOF! patch config/i386/go32.h djgpp/manifest/pgcc${PGCC_ZIPVER}b.ver touch djgpp/manifest/pgcc${PGCC_ZIPVER}b.mft find djgpp -print | cut -d/ -f2- | grep -v djgpp > djgpp/manifest/pgcc${PGCC_ZIPVER}b.mft else echo "egcs${EGCS_ZIPVER}b GNU EGCS $EGCS_VER for DJGPP V2 " > djgpp/manifest/egcs${EGCS_ZIPVER}b.ver touch djgpp/manifest/egcs${EGCS_ZIPVER}b.mft find djgpp -print | cut -d/ -f2- | grep -v djgpp > djgpp/manifest/egcs${EGCS_ZIPVER}b.mft fi # # Zip up the compiler binaries into one file, and the docs in another # cd djgpp if [ $PGCC ]; then zip -r pgcc${EGCS_ZIPVER}b.zip bin lib manifest include cross-1.sh native-2.sh pgcc.txt zip -r pgcc${EGCS_ZIPVER}d.zip info else zip -r egcs${EGCS_ZIPVER}b.zip bin lib manifest include cross-1.sh native-2.sh zip -r egcs${EGCS_ZIPVER}d.zip info fi cd ..