00001 #! /bin/bash 00002 00003 # This is my script for building a complete MinGW cross-compiler toolchain 00004 # that runs under Linux to produce executables that run under Windows. It 00005 # probably works (or can easily be adapted to work) under any unix system. 00006 # 00007 # It is based in large part on Sam Lantinga's script, which in turn was 00008 # based partly on Ray Kelm's script, which in turn was built on 00009 # Mo Dejong's script for doing the same, but with some added fixes. 00010 # 00011 # My changes: 00012 # 1. Adapted the script to the new packaging of MinGW GCC, which is 00013 # currently split into core and auxiliary components. 00014 # 2. The script now determines the GCC and BINUTILS directory name 00015 # directly from the tar file contents. This gets around common 00016 # problems due to the directory names not always following the 00017 # expected patterns. 00018 # 3. Grouped together and simplified the macros that users need to 00019 # define. 00020 # 4. Made optional components truly optional -- leave the 00021 # corresponding archive names blank and they will be ignored. 00022 # 5. Included an option to he installation directory before 00023 # installing the current cross-compiler. 00024 # 00025 # NOTE: If you choose a destination directory for the installation (set 00026 # in the macro PREFIX) for which you do not have write access, you will 00027 # need to run this script with root (or equivalent) privileges. 00028 # 00029 # 00030 # Updated by Igor Mikolic-Torreira <igormt@alumni.caltech.edu> 00031 # Updated by Adrien Nader <camaradetux@gmail.com> 00032 # - updated to gcc 4.3 (mpfr, gmp, ...) 00033 # Found on http://paste.lisp.org/display/73705 00034 # Updated by Bernhard Döbler <programmer@bardware.de> 00035 00036 #----------------------------------------------------- 00037 # 00038 # BEGIN USER SETTINGS 00039 # 00040 # You need to review and adjust the macros that follow 00041 # 00042 #----------------------------------------------------- 00043 00044 # What flavor of GCC cross-compiler are we building? 00045 00046 TARGET=i686-pc-mingw32 00047 00048 # What GCC-Version will we use 00049 00050 GCC_VER=4.3.3 00051 00052 # What directory will the cross-compiler be built in? 00053 # This is the directory into which source archives will 00054 # be downloaded, expanded, compiled, etc. You need to 00055 # have write-access to this directory. If you leave it 00056 # blank, it defaults to the current directory. 00057 00058 BUILDDIR=$HOME/src 00059 00060 # Where does the cross-compiler go? 00061 # This should be the directory into which your cross-compiler 00062 # will be installed. Remember that if you set this to a directory 00063 # that only root has write access to, you will need to run this 00064 # script as root. 00065 00066 PREFIX=/crossdev-$GCC_VER 00067 00068 # Purge anything and everything already in the $PREFIX 00069 #(also known as the destination or installation) directory? 00070 # Set to "Y" to purge, any other value omits the purge step. 00071 00072 PURGE_DIR="Y" 00073 00074 # Set the following to the files from the current MinGW release 00075 # (or whichever MinGW release you wish to build and install) 00076 # You need to set both the URL they will be downloaded from 00077 # and the exact name of the individual component files. 00078 00079 MINGW_URL="http://heanet.dl.sourceforge.net/sourceforge/mingw" 00080 GCC_URL="ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/gcc-$GCC_VER" 00081 BINUTILS_URL="ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/binutils/releases" 00082 GMP_URL="ftp://ftp.gnu.org/gnu/gmp" 00083 MPFR_URL="http://www.mpfr.org/mpfr-current" 00084 00085 # GCC_CORE is required; the other components are optional. 00086 # Set any you don't want to "". You need binutils, 00087 # mingw runtime and w32api; do not ever set those to "". 00088 00089 GCC_CORE_ARCHIVE="gcc-core-$GCC_VER.tar.bz2" 00090 GCC_GPP_ARCHIVE="gcc-g++-$GCC_VER.tar.bz2" 00091 GCC_G77_ARCHIVE="" 00092 GCC_OBJC_ARCHIVE="" 00093 GCC_JAVA_ARCHIVE="" 00094 GCC_ADA_ARCHIVE="" 00095 GCC_PATCH="" 00096 00097 BINUTILS_ARCHIVE="binutils-2.19.1.tar.bz2" 00098 00099 MPFR_ARCHIVE="mpfr-2.4.1.tar.bz2" 00100 GMP_ARCHIVE="gmp-4.2.4.tar.bz2" 00101 00102 MINGW_ARCHIVE="mingwrt-3.15.2-mingw32-dev.tar.gz" 00103 00104 W32API_ARCHIVE="w32api-3.13-mingw32-dev.tar.gz" 00105 00106 # These are the files from the SDL website 00107 # These are optional, set them to "" if you don't want them) 00108 00109 #SDL_URL="http://www.libsdl.org/extras/win32/common" 00110 #OPENGL_ARCHIVE="opengl-devel.tar.gz" 00111 #DIRECTX_ARCHIVE="directx-devel.tar.gz" 00112 SDL_URL="" 00113 OPEnGL_ARCHIVE="" 00114 DIRECTX_ARCHIVE="" 00115 00116 #----------------------------------------------------- 00117 # 00118 # END USER SETTINGS 00119 # 00120 # The remainder of the script should not neet any edits 00121 # 00122 #----------------------------------------------------- 00123 00124 # Make sure these are initialized as we want them 00125 00126 GCC="" 00127 BINUTILS="" 00128 GCC_LANGS="c,c++" 00129 00130 # Set our build directory and where our sources will go 00131 00132 if [ "x$BUILDDIR" = "x" ]; then 00133 # Default to the current directory 00134 BUILDDIR=$(pwd) 00135 fi 00136 00137 SRCDIR="$BUILDDIR/source" 00138 00139 # Need install directory first on the path so gcc can find binutils 00140 00141 PATH="$PREFIX/bin:$PATH" 00142 00143 #----------------------------------------------------- 00144 # 00145 # Functions that do most of the work 00146 # 00147 #----------------------------------------------------- 00148 00149 function download_files { 00150 # Download a file from a given url, only if it is not present 00151 mkdir -p "$SRCDIR" 00152 00153 # Make sure wget is installed 00154 if test "x`which wget`" = "x" ; then 00155 echo "You need to install wget." 00156 exit 1 00157 fi 00158 download_file "$GCC_CORE_ARCHIVE" "$GCC_URL" 00159 if [ "x$GCC_GPP_ARCHIVE" != "x" ]; then 00160 download_file "$GCC_GPP_ARCHIVE" "$GCC_URL" 00161 fi 00162 if [ "x$GCC_G77_ARCHIVE" != "x" ]; then 00163 download_file "$GCC_G77_ARCHIVE" "$GCC_URL" 00164 fi 00165 if [ "x$GCC_OBJC_ARCHIVE" != "x" ]; then 00166 download_file "$GCC_OBJC_ARCHIVE" "$GCC_URL" 00167 fi 00168 if [ "x$GCC_JAVA_ARCHIVE" != "x" ]; then 00169 download_file "$GCC_JAVA_ARCHIVE" "$GCC_URL" 00170 fi 00171 if [ "x$GCC_ADA_ARCHIVE" != "x" ]; then 00172 download_file "$GCC_ADA_ARCHIVE" "$GCC_URL" 00173 fi 00174 00175 download_file "$BINUTILS_ARCHIVE" "$BINUTILS_URL" 00176 download_file "$GMP_ARCHIVE" "$GMP_URL" 00177 download_file "$MPFR_ARCHIVE" "$MPFR_URL" 00178 download_file "$MINGW_ARCHIVE" "$MINGW_URL" 00179 download_file "$W32API_ARCHIVE" "$MINGW_URL" 00180 00181 if [ "x$OPENGL_ARCHIVE" != "x" ]; then 00182 download_file "$OPENGL_ARCHIVE" "$SDL_URL" 00183 fi 00184 if [ "x$DIRECTX_ARCHIVE" != "x" ]; then 00185 download_file "$DIRECTX_ARCHIVE" "$SDL_URL" 00186 fi 00187 } 00188 00189 function download_file { 00190 cd "$SRCDIR" 00191 if test ! -f $1 ; then 00192 echo "Downloading $1" 00193 wget "$2/$1" 00194 if test ! -f $1 ; then 00195 echo "Could not download $1" 00196 exit 1 00197 fi 00198 else 00199 echo "Found $1 in the srcdir $SRCDIR" 00200 fi 00201 cd "$BUILDDIR" 00202 } 00203 00204 function purge_existing_install { 00205 echo "Purging the existing files in $PREFIX" 00206 if cd "$PREFIX"; then 00207 rm -rf * 00208 fi 00209 cd "$BUILDDIR" 00210 } 00211 00212 function install_libs { 00213 echo "Installing cross libs and includes" 00214 mkdir -p "$PREFIX/$TARGET" 00215 cd "$PREFIX/$TARGET" 00216 00217 tar -xzf "$SRCDIR/$MINGW_ARCHIVE" 00218 tar -xzf "$SRCDIR/$W32API_ARCHIVE" 00219 00220 if [ "x$OPENGL_ARCHIVE" != "x" ]; then 00221 tar -xzf "$SRCDIR/$OPENGL_ARCHIVE" 00222 fi 00223 00224 if [ "x$DIRECTX_ARCHIVE" != "x" ]; then 00225 tar -xzf "$SRCDIR/$DIRECTX_ARCHIVE" 00226 fi 00227 00228 cd "$BUILDDIR" 00229 } 00230 00231 function extract_binutils { 00232 cd "$SRCDIR" 00233 BINUTILS=`tar -tjf "$SRCDIR/$BINUTILS_ARCHIVE" | head -n 1 | cut -d '/' -f 1` 00234 rm -rf "$BINUTILS" 00235 echo "Extracting binutils" 00236 tar -xjf "$SRCDIR/$BINUTILS_ARCHIVE" 00237 cd "$BUILDDIR" 00238 } 00239 00240 function configure_binutils { 00241 cd "$SRCDIR/$BINUTILS" 00242 cd "$BUILDDIR" 00243 rm -rf "binutils-$TARGET" 00244 mkdir "binutils-$TARGET" 00245 cd "binutils-$TARGET" 00246 echo "Configuring binutils" 00247 "$SRCDIR/$BINUTILS/configure" --prefix="$PREFIX" --target=$TARGET --disable-nls \ 00248 --with-gcc --with-gnu-as --with-gnu-ld --disable-werror --disable-shared &> configure.log 00249 cd "$BUILDDIR" 00250 } 00251 00252 function build_binutils { 00253 cd "$BUILDDIR/binutils-$TARGET" 00254 echo "Building binutils" 00255 make -j3 CFLAGS="-O2 -fno-exceptions" LDFLAGS="-s" &> make.log 00256 if test $? -ne 0; then 00257 echo "make of binutils failed - log available: binutils-$TARGET/make.log" 00258 exit 1 00259 fi 00260 cd "$BUILDDIR" 00261 } 00262 00263 function install_binutils { 00264 cd "$BUILDDIR/binutils-$TARGET" 00265 echo "Installing binutils" 00266 make install &> make-install.log 00267 if test $? -ne 0; then 00268 echo "install of binutils failed - log available: binutils-$TARGET/make-install.log" 00269 exit 1 00270 fi 00271 cd "$BUILDDIR" 00272 } 00273 00274 function extract_gmp { 00275 cd "$SRCDIR" 00276 GMP=`tar -tjf "$SRCDIR/$GMP_ARCHIVE" | head -n 1` 00277 rm -rf "$GMP" 00278 echo "Extracting gmp" 00279 tar -xjf "$SRCDIR/$GMP_ARCHIVE" 00280 cd "$BUILDDIR" 00281 } 00282 00283 function configure_gmp { 00284 cd "$BUILDDIR" 00285 rm -rf "gmp-$TARGET" 00286 mkdir "gmp-$TARGET" 00287 cd "gmp-$TARGET" 00288 echo "Configuring gmp" 00289 "$SRCDIR/$GMP/configure" --prefix="$PREFIX" --disable-shared \ 00290 --with-gnu-ld &> configure.log 00291 cd "$BUILDDIR" 00292 } 00293 00294 function build_gmp { 00295 cd "$BUILDDIR/gmp-$TARGET" 00296 echo "Building gmp" 00297 make -j3 CFLAGS="-O2 -fno-exceptions" LDFLAGS="-s" &> make.log 00298 if test $? -ne 0; then 00299 echo "make of gmp failed - log available: gmp-$TARGET/make.log" 00300 exit 1 00301 fi 00302 cd "$BUILDDIR" 00303 } 00304 00305 function install_gmp { 00306 cd "$BUILDDIR/gmp-$TARGET" 00307 echo "Installing gmp" 00308 make install &> make-install.log 00309 if test $? -ne 0; then 00310 echo "install of gmp failed - log available: gmp-$TARGET/make-install.log" 00311 exit 1 00312 fi 00313 cd "$BUILDDIR" 00314 } 00315 00316 function extract_mpfr { 00317 cd "$SRCDIR" 00318 MPFR=`tar -tjf "$SRCDIR/$MPFR_ARCHIVE" | head -n 1` 00319 rm -rf "$MPFR" 00320 echo "Extracting mpfr" 00321 tar -xjf "$SRCDIR/$MPFR_ARCHIVE" 00322 cd "$BUILDDIR" 00323 } 00324 00325 function configure_mpfr { 00326 cd "$BUILDDIR" 00327 rm -rf "mpfr-$TARGET" 00328 mkdir "mpfr-$TARGET" 00329 cd "mpfr-$TARGET" 00330 echo "Configuring mpfr" 00331 "$SRCDIR/$MPFR/configure" --prefix="$PREFIX" --disable-shared \ 00332 --with-gnu-ld --with-gmp="$PREFIX" &> configure.log 00333 cd "$BUILDDIR" 00334 } 00335 00336 function build_mpfr { 00337 cd "$BUILDDIR/mpfr-$TARGET" 00338 echo "Building mpfr" 00339 make -j3 CFLAGS="-O2 -fno-exceptions" LDFLAGS="-s" &> make.log 00340 if test $? -ne 0; then 00341 echo "make of mpfr failed - log available: mpfr-$TARGET/make.log" 00342 exit 1 00343 fi 00344 cd "$BUILDDIR" 00345 } 00346 00347 function install_mpfr { 00348 cd "$BUILDDIR/mpfr-$TARGET" 00349 echo "Installing mpfr" 00350 make install &> make-install.log 00351 if test $? -ne 0; then 00352 echo "install of mpfr failed - log available: mpfr-$TARGET/make-install.log" 00353 exit 1 00354 fi 00355 cd "$BUILDDIR" 00356 } 00357 00358 function extract_gcc { 00359 cd "$SRCDIR" 00360 GCC=`tar -tjf "$SRCDIR/$GCC_CORE_ARCHIVE" | head -n 1` 00361 rm -rf "$GCC" 00362 echo "Extracting gcc" 00363 tar -xjf "$SRCDIR/$GCC_CORE_ARCHIVE" 00364 if [ "x$GCC_GPP_ARCHIVE" != "x" ]; then 00365 GCC_LANGS=${GCC_LANGS}",c++" 00366 tar -xjf "$SRCDIR/$GCC_GPP_ARCHIVE" 00367 fi 00368 if [ "x$GCC_G77_ARCHIVE" != "x" ]; then 00369 GCC_LANGS=${GCC_LANGS}",f77" 00370 tar -xjf "$SRCDIR/$GCC_G77_ARCHIVE" 00371 fi 00372 if [ "x$GCC_OBJC_ARCHIVE" != "x" ]; then 00373 GCC_LANGS=${GCC_LANGS}",objc" 00374 tar -xjf "$SRCDIR/$GCC_OBJC_ARCHIVE" 00375 fi 00376 if [ "x$GCC_JAVA_ARCHIVE" != "x" ]; then 00377 GCC_LANGS=${GCC_LANGS}",java" 00378 tar -xjf "$SRCDIR/$GCC_JAVA_ARCHIVE" 00379 fi 00380 if [ "x$GCC_ADA_ARCHIVE" != "x" ]; then 00381 GCC_LANGS=${GCC_LANGS}",ada" 00382 tar -xjf "$SRCDIR/$GCC_ADA_ARCHIVE" 00383 fi 00384 cd "$BUILDDIR" 00385 } 00386 00387 function patch_gcc { 00388 if [ "$GCC_PATCH" != "" ]; then 00389 echo "Patching gcc" 00390 cd "$SRCDIR/$GCC" 00391 patch -p1 < "$SRCDIR/$GCC_PATCH" 00392 cd "$BUILDDIR" 00393 fi 00394 } 00395 00396 function configure_gcc { 00397 cd "$BUILDDIR" 00398 rm -rf "gcc-$TARGET" 00399 mkdir "gcc-$TARGET" 00400 cd "gcc-$TARGET" 00401 echo "Configuring gcc" 00402 "$SRCDIR/$GCC/configure" -v \ 00403 --prefix="$PREFIX" --target=$TARGET --libexecdir="$PREFIX"/lib \ 00404 --with-mpfr="$PREFIX" --with-gmp="$PREFIX" 00405 --with-headers="$PREFIX/$TARGET/include" \ 00406 --with-gcc --with-gnu-ld --with-gnu-as \ 00407 --enable-threads --disable-nls --enable-languages=$GCC_LANGS \ 00408 --disable-win32-registry --disable-shared \ 00409 --disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug \ 00410 --enable-hash-synchronization \ 00411 --disable-multilib &> configure.log 00412 cd "$BUILDDIR" 00413 } 00414 #--enable-hash-synchronization --enable-libstdcxx-debug --enable-__cxa_atexit \ 00415 #--disable-win32-registry --disable-shared --enable-sjlj-exceptions --enable-libgcj \ 00416 00417 function build_gcc { 00418 cd "$BUILDDIR/gcc-$TARGET" 00419 echo "Building gcc" 00420 make -j3 CFLAGS="-O2" CXXFLAGS="-O2" GCJFLAGS="-O2" LDFLAGS="-s" DEBUG_FLAGS="-g0" &> make.log 00421 if test $? -ne 0; then 00422 echo "make of gcc failed - log available: gcc-$TARGET/make.log" 00423 exit 1 00424 fi 00425 if [ "x$GCC_ADA" != "x" ]; then 00426 cd gcc 00427 make "CFLAGS=-O2" "LDFLAGS=-s" gnatlib_and_tools &> make-gnatlib.log 00428 if test $? -ne 0; then 00429 echo "make of gnatlib and tools failed - log available: gcc-$TARGET/make-gnatlib.log" 00430 exit 1 00431 fi 00432 fi 00433 cd "$BUILDDIR" 00434 } 00435 00436 function install_gcc { 00437 cd "$BUILDDIR/gcc-$TARGET" 00438 echo "Installing gcc" 00439 make install &> make-install.log 00440 if test $? -ne 0; then 00441 echo "install of gcc failed - log available: gcc-$TARGET/make-install.log" 00442 exit 1 00443 fi 00444 cd "$BUILDDIR" 00445 } 00446 00447 function final_tweaks { 00448 echo "Finalizing installation" 00449 00450 # remove gcc build headers 00451 rm -rf "$PREFIX/$TARGET/sys-include" 00452 00453 # Add extra binary links 00454 if [ ! -f "$PREFIX/$TARGET/bin/objdump" ]; then 00455 ln "$PREFIX/bin/$TARGET-objdump" "$PREFIX/$TARGET/bin/objdump" 00456 fi 00457 00458 # make cc and c++ symlinks to gcc and g++ 00459 if [ ! -f "$PREFIX/$TARGET/bin/g++" ]; then 00460 ln "$PREFIX/bin/$TARGET-g++" "$PREFIX/$TARGET/bin/g++" 00461 fi 00462 if [ ! -f "$PREFIX/$TARGET/bin/cc" ]; then 00463 ln -s "gcc" "$PREFIX/$TARGET/bin/cc" 00464 fi 00465 if [ ! -f "$PREFIX/$TARGET/bin/c++" ]; then 00466 ln -s "g++" "$PREFIX/$TARGET/bin/c++" 00467 fi 00468 00469 # strip all the binaries 00470 ls "$PREFIX"/bin/* "$PREFIX/$TARGET"/bin/* | egrep -v '.dll$' | egrep -v 'gccbug$' | 00471 while read file; do 00472 strip "$file" 00473 done 00474 00475 echo "Installation complete!" 00476 } 00477 00478 # 00479 # Main part of the script 00480 # 00481 00482 download_files 00483 00484 if [ "x$PURGE_DIR" = "xY" ]; then 00485 purge_existing_install 00486 fi 00487 00488 install_libs 00489 00490 extract_binutils 00491 configure_binutils 00492 build_binutils 00493 install_binutils 00494 00495 extract_gmp 00496 configure_gmp 00497 build_gmp 00498 install_gmp 00499 00500 extract_mpfr 00501 configure_mpfr 00502 build_mpfr 00503 install_mpfr 00504 00505 extract_gcc 00506 patch_gcc 00507 configure_gcc 00508 build_gcc 00509 install_gcc 00510 00511 final_tweaks 00512 00513 # 00514 # End 00515 #