HOME | CERN |
- compile on Windows (Cygwin) - execute on Renesas MCU |
|
As I spent a lot of time to understand and make this working so I decided to write a
little guide to save time and effort for other newbies like me.
This guide is to build the GNU GCC cross compiler on a Windows (Cygwin) machine, later you will use a Windows (Cygwin) machine to run the cross-compiler and generate code for your favorite Renesas MCU. |
|
other guides |
1 -
build on Linux, compile on Linux, execute on Renesas MCU
2 - build on Linux, compile on Windows, execute on Renesas MCU 4 - build on Windows (Cygwin), compile on Windows, execute on Renesas MCU 5 - build on Windows (MYSY, Mingw), compile on Windows, execute on Renesas MCU |
sources |
The source code of the GNU GCC cross compiler we will build can be downloaded from several places. The official websites are:
The corresponding git Mirrors sites are:
/home/johndoe/gitMirror/binutils /home/johndoe/gitMirror/gcc /home/johndoe/gitMirror/newlib /home/johndoe/src/gmp-v.v.v /home/johndoe/src/mpfr-v.v.v /home/johndoe/src/mpc-v.v |
What we'll do |
Using a cross-compiler (Cygwin "Linux-Windows") installed in your Windows machine we will compile the source code to
generated the cross-compiler (Cygwin "Windows"-Renesas) and libraries. This produced cross-compiler is what you will run on the Windows machine to generate the executable code for Renesas MCU. To deal with the different machine codes that can be involved during the process of producing the cross-compiler the gcc people have defined three arguments
i386-pc-linux-gnu pentium4-pc-linux-gnu i686-pc-linux-gnu i386-pc-mingw32msvc i386-pc-mingw32 i586-pc-mingw32 i686-pc-mingw32 i686-w64-mingw32 x86_64-w64-mingw32 i686-pc-cygwin x86_64-pc-cygwin examples of --target are m32c-elf rx-elf |
Prerequisites |
On your Windows machine you need to have installed and running Cygwin GCC cross-compiler: mingw-gcc-core and mingw-gcc-g++ for i686-w32-mingw32 mingw64-i686-gcc-core and mingw64-i686-gcc-g++ for i686-w64-mingw32 mingw64-x86_64-gcc-core and mingw64-x86_64-gcc-g++ for x86_64-w64-mingw32 cygwin-gcc-core and cygwin32-gcc-g++ for i686-pc-cygwin gcc-core and gcc-g++ for x86_64-pc-cygwin Make Perl Bison (used by several scripts like ylwrap of binutils) GNU M4 (interpreters) used by Bison Flex libncursesw-devel (libncurses.a) |
Hands on! |
You can go by hand or use some scripts. The variables I'll explain are the ones used by the scripts. Note:my skills on linux are very limited and the main goal is to be very explicit so for sure the scripts can be improved a lot. The very first thing is the correct setup of the variables used by the scripts (in the build_vars.sh) for the --build (the building ON machine) we'll use the variable THIS_PLATFORM, in this guide we can use any of the linux values i.e.: THIS_PLATFORM=i686-pc-linux-gnu for the --host (the building FOR machine) we'll use the variable WANTED_COMPILER_PLATFORM, in this guide we can use any of the mingw values i.e.: WANTED_COMPILER_PLATFORM=i686-pc-mingw32 for --target (the machine that the cross-compiler will produce code for) we can choose: WANTED_COMPILER_CODE=m32c-elf or WANTED_COMPILER_CODE=rx-elf if you choose m32c-elf it supports only C language COMPI_LANGUAGES=c MAKE_LANGUAGES="c" for the rx-elf it supports both C and C++ languages COMPI_LANGUAGES=c,c++ MAKE_LANGUAGES="c c++" now the place where you decided to put the source files SRC_DIR_NEWLIB=/home/johndoe/gitMirror/newlib SRC_DIR_BINUTILS=/home/johndoe/gitMirror/binutils SRC_DIR_GCC=/home/johndoe/gitMirror/gcc SRC_DIR_GMP=/home/johndoe/src/gmp-5.0.2 SRC_DIR_MPFR=/home/johndoe/src/mpfr-3.1.0 SRC_DIR_MPC=/home/johndoe/src/mpc-0.9 these are the destination directories, where the final produced cross-compiler will be stored WANTED_COMPILER_PLATFORM_PREFIX=/home/johndoe/rx/pre/win32 WANTED_COMPILER_PLATFORM_PREFIX_GMP=/home/johndoe/rx/pre/win32/gmp WANTED_COMPILER_PLATFORM_PREFIX_MPFR=/home/johndoe/rx/pre/win32/mpfr WANTED_COMPILER_PLATFORM_PREFIX_MPC=/home/johndoe/rx/pre/win32/mpc if you try to build in the same directory as the sources you will run into troubles, you need a place to store the intermediate files while producing the cross-compiler WANTED_COMPILER_PLATFORM_BUILD_DIR=/home/johndoe/rx/bld/win32 WANTED_COMPILER_PLATFORM_BUILD_BINUTILS=binutils WANTED_COMPILER_PLATFORM_BUILD_GCC=gcc WANTED_COMPILER_PLATFORM_BUILD_NEWLIB=newlib WANTED_COMPILER_PLATFORM_BUILD_GMP=gmp WANTED_COMPILER_PLATFORM_BUILD_MPFR=mpfr WANTED_COMPILER_PLATFORM_BUILD_MPC=mpc the place of the extra cross-compiler (Linux, Windows) we are using to build the cross-compiler (Windows, Renesas) EXTRA_CROSS_COMPILER_PATH=/home/johndoe/mingw the place of the native cross-compiler (Linux, Renesas) used to build the libraries EXTRA_NATIVE_CROSS_COMPILER_PATH=/home/johndoe/rx/pre/linux now you are ready to run ./build_all.sh |
Step 1 - building binutils |
The standard procedure with GNU products is configure, make and make install. cd $WANTED_COMPILER_PLATFORM_BUILD_DIR/$WANTED_COMPILER_PLATFORM_BUILD_BINUTILS $SRC_DIR_BINUTILS/configure --build=$THIS_PLATFORM --host=$WANTED_COMPILER_PLATFORM --target=$WANTED_COMPILER_CODE --prefix=$WANTED_COMPILER_PLATFORM_PREFIX --disable-werror make make install configure prepares all the scripts needed by make and make install and then make and make install do the job. The --disable-werror changes the default behavior where warnings are treated as errors and stops the compilation. |
Step 2 - building GMP |
cd $WANTED_COMPILER_PLATFORM_BUILD_DIR/$WANTED_COMPILER_PLATFORM_BUILD_GMP $SRC_DIR_GMP/configure --disable-shared --build=$THIS_PLATFORM --host=$WANTED_COMPILER_PLATFORM --prefix=$WANTED_COMPILER_PLATFORM_PREFIX_GMP make make install we can't run make check because the generated code is for Windows and we are running in Linux. Normally in embedded system we don't use shared libraries (--disable-shared). |
Step 3 - building MPFR |
cd $WANTED_COMPILER_PLATFORM_BUILD_DIR/$WANTED_COMPILER_PLATFORM_BUILD_MPFR $SRC_DIR_MPFR/configure --disable-shared --build=$THIS_PLATFORM --host=$WANTED_COMPILER_PLATFORM --with-gmp=$WANTED_COMPILER_PLATFORM_PREFIX_GMP --prefix=$WANTED_COMPILER_PLATFORM_PREFIX_MPFR make make install Build of MPFR needs GMP this is why this is done afterwards. |
Step 4 - building MPC |
cd $WANTED_COMPILER_PLATFORM_BUILD_DIR/$WANTED_COMPILER_PLATFORM_BUILD_MPC $SRC_DIR_MPC/configure --disable-shared --build=$THIS_PLATFORM --host=$WANTED_COMPILER_PLATFORM --with-gmp=$WANTED_COMPILER_PLATFORM_PREFIX_GMP --with-mpfr=$WANTED_COMPILER_PLATFORM_PREFIX_MPFR --prefix=$WANTED_COMPILER_PLATFORM_PREFIX_MPC make make install Build of MPC needs GMP and MPFR this is why this is done afterwards. |
Step 5 - building gcc (start) |
cd $WANTED_COMPILER_PLATFORM_BUILD_DIR/$WANTED_COMPILER_PLATFORM_BUILD_GCC $SRC_DIR_GCC/configure -v --disable-shared --with-newlib=yes --enable-lto --enable-gold --disable-libstdcxx-pch --build=$THIS_PLATFORM --host=$WANTED_COMPILER_PLATFORM --enable-languages=$COMPI_LANGUAGES --target=$WANTED_COMPILER_CODE --with-gmp=$WANTED_COMPILER_PLATFORM_PREFIX_GMP --with-mpfr=$WANTED_COMPILER_PLATFORM_PREFIX_MPFR --with-mpc=$WANTED_COMPILER_PLATFORM_PREFIX_MPC --prefix=$WANTED_COMPILER_PLATFORM_PREFIX make configure-build-libiberty make all-build-libiberty make all-gcc make install-gcc You see, gcc needs GMP, MPFR and MPC this is why we were forced to compile them. --with-newlib tells the compiler to use newlib headers wherever possible (also for other libraries than libgcc). --without-headers tells the compiler to build libgcc (only it) without any headers at all. (Note that --without-headers is the default for a cross-compiler.) So if we use --without-headers --with-newlib, libgcc will be built without requiring the presence of any header, and other libraries will be built with newlib headers. If we use --without-headers alone, libgcc will be built without requiring the presence of any headers, and other libraries will be built with libc headers. (When building a cross-compiler, in practice what will happen is that libgcc will build and the other libraries will fail to build.) If I use --with-newlib alone, libgcc and other libraries will be built with newlib headers. (When building a cross-compiler, you do need to provide some headers for the libraries other than libgcc. In other words, at build time, the compiler needs to be able to find the libc headers. This is typically done using one of --with-newlib, --with-sysroot, or --with-build-sysroot.) If we use nothing, libgcc and other libraries will be built with libc headers. You can disable unwanted parts with --disable-threads --disable-libmudflap --disable-libssp --disable-libgomp --disable-libquadmath --disable-target-libiberty --disable-target-zlib You can run configure --help to get the complete list of available options. |
Step 6 - building newlib |
cd $WANTED_COMPILER_PLATFORM_BUILD_DIR/$WANTED_COMPILER_PLATFORM_BUILD_NEWLIB $SRC_DIR_NEWLIB/configure --disable-libquadmath --disable-libada --disable-libssp --build=$THIS_PLATFORM --host=$WANTED_COMPILER_PLATFORM --target=$WANTED_COMPILER_CODE --prefix=$WANTED_COMPILER_PLATFORM_PREFIX make make install |
Step 7 - building gcc final (libraries) |
cd $WANTED_COMPILER_PLATFORM_BUILD_DIR/$WANTED_COMPILER_PLATFORM_BUILD_GCC make make install Ta.. daaa!!!! You can go to $WANTED_COMPILER_PLATFORM_PREFIX copy the files to the Windows machine and run there your cross-compiler to generated code for the Renesas MCU |
Notes |
The GMP, MPFR and MPC directories are not necessary. For newlib I want the specific defines REENTRANT_SYSCALLS_PROVIDED, INTERNAL_NEWLIB, DEFINE_MALLOC, DEFINE_FREE DEFINE_REALLOC, DEFINE_CALLOC. Because my targets are rx-elf and m32c-elf when I try via CFLAGS is not a complete sucess. I finish patching source/newlib/newlib/configure.host adding in the last case "${host}" in the case rx-*-*) default_newlib_io_long_long="yes" newlib_cflags="${newlib_cflags} -Os -DREENTRANT_SYSCALLS_PROVIDED -DINTERNAL_NEWLIB -DDEFINE_MALLOC -DDEFINE_FREE -DDEFINE_REALLOC -DDEFINE_CALLOC" syscall_dir= ;; (and similar for m32c-*-* ) because the case rx-*-* was not defined and was passing at default adding always -DMISSING_SYSCALL_NAMES what is not good for me. |