GNU Compilers - itzjac/cpplearning GitHub Wiki

This section is completely optional and exclusive to Windows.

Is about getting access to a compiler that supports (at least attempts to) the very latest C++ features. Followed up by lots of configuration and customization workflow for Windows.

Enabling access to the latest C++ standards can be cumbersome and only few compilers might be updated regularly. In practice you don't really need bleeding edge, it can be useful under some circumstances. My experience has demonstrated project after project, a C++ compiler that's around 3 years old will be fine. As a bonus, having a clear understanding on what a compiler is, how is structured, and distributed, is definitely an important tool to solve the typical and basic compilation problems.

Look at the list of the official compiler support in cppreference.

I prefer clang and GCC (GNU Compiler Compilation which include g++), as two of the most active, complete and updated compilers when trying to profile or access newest language features. clang tends to generate better optimized code. In reality, that will have to be proven case by case. Regardless the OS of your choice, having access to any of these two compilers can be of great help when learning modern C++.

GCC and clang are also available for Windows, Mac and many many more OS's. Most Linux distros, already include them as part of their distros. Both compilers are under GNU GPL 3+ & University of Illinois/NCSA OpenSource License respectively. Basically, you can consider almost any OS you can imagine, granted will have access to the compiler's source code and you take it from there.

We continue our topic elaborating instructions for GCC, specifically g++ in a Windows environment. Bear in mind the extensive list of supported platforms for GCC Supported platforms for GCC. After reading this, you should be able to use any other C++ compiler in the platform of your choice.

Installing g++ in Windows

GCC is supported in Windows through a runtime library called mingw contraction of "Minimalist GNU for Windows, is a minimalist development environment for native Microsoft Windows applications. Compared to other C++ IDE's in Windows, MinGW doesn't depend on any 3rd party C-Runtime DLL like MSVCRT.DLL.

An important note about MinGW being minimalist, does not, and never will, attempt to provide a POSIX (Portable Operating System Interface) runtime environment for POSIX application deployment on MS-Windows. If you want POSIX application deployment on this platform, please consider using cygwin, here another chance to learn on your own and try another compiler.

We will install a mingw version for windows that supports x64_x86 platforms and we will show how to compile the applications. Distributable binaries installer is available.

x64 compilation---->

x64-x86 compilation----->

Alternatively, if you want to build the compiler from source code, use this link. Keep in mind is not a mandatory requirement, just you can gain more experience in compiling the source code, familiarize with some standards.

Whatever method you selected, I recommend you to install the compiler in a folder separated from the Windows OS, I will choose a folder called


WINDOWS
C:\compilers\mingw64>

Inside, you will find a typical folder structure of a compiler installation: lib (libraries), include (headers), bin (binaries), documentation and additional tools for debugging and analyzing executables.

mingwfolders

Pay attention to three folders, include, lib and bin, whatever C++ compiler you will ever use, will likely contain these folders or a very similar easily identifiable form.

  • bin, where the actual compiler program is located along with its linker and many more tools, where g++ resides

  • include, all public access to the C++ standard library

  • lib, collection of pre-compiled modules from the C++ standard library, organized for the purposes of being reused by independent programs

If you care on your drive size, at the time of the g++ version 8.1.0, the whole installation size is around 502Mb. In contrast VC2019 Community 11.3Gb.

mingw configuration in Windows

Some installers like TDM-GCC MinGW Compiler, create a global access to the mingw suite by adding the Windows environment variable PATH, to make it available on the command line globally. Without further steps you will be able to access g++ and any other tool contained in the mingw suite from any command console.

Other distributions require that you set the environment variables globally or you open the command line in the folder containing the compiler


WINDOWS
C:\compilers\mingw64\bin>g++ --version
    g++ (x86_64-win32-sjlj-rev0, Built by MinGW-W64 project) 8.1.0
    Copyright (C) 2018 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Alternativelly, if you want to manually create your own environment without touching Windows PATH, follow the next walkthrough.

Manually creating environment variables in Windows

Other mingw suites do not touch windows environment variables, if you open a command console in an arbitrary path, the g++ version command will fail.


WINDOWS
>g++ --version
    'g++' is not recognized as an internal or external command,
    operable program or batch file. 


All the compiler suite was installed in your HDD, along with its tools, but it doesn't mean the OS has global access to execute the tools through commands in the console prompt. You should notice next to your installation folder (or at the root of the compilation result if you compiled mingw on your own), a windows batch called mingw-w64.bat. This file contains all the necessary paths to actually execute g++ or any other tool contained in the mingw suite. Windows batches are a very important tool to automate your work using a script language, it is associated with .bat or .cmd extension. Bat extensions are natively identified as script files that automatically execute command line sequences and logic. As we continue, we will create the most basic batches and you will get familiar with the script language that Windows uses. A more advanced scripted language is PowerShell, available by default from Win10 and on. PowerShell relies on more advanced tools and commands. We apply the KISS law this time, and personally I always prefer the vanilla script batches supported across many different version of Windows natively.

mingwenvvar

NOTE: mingwx64var.bat, mingw64.bat depending on the distribution you choose the name can vary, it will commonly be located at the root folder of the compiler installation.

Open the text of the bats, you will notice a variable named PATH, which will grant the command line to execute binaries in this new folder. Open the command prompt in your installation folder, run the mingw-w64.bat (remember .bat files can be double clicked as executable files in the windows explorer too!).


WINDOWS
>mingw-w64.bat
>g++ --version
g++ (x86_64-win32-sjlj-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling, debugging and analyzing a C++ program using GCC tools will be available in arbitrary paths from the command line. Would be nice to create another bat file where you can encapsulate this setup and include the mingw-w64.bat.

Customizing mingw execution

Let's create a more automated compilation environment by creating our own batch file. Given the following paths for your your working and compiler installation folders.


WINDOWS
C:\Courses\lessons>


BATCH
@ECHO OFF
CALL "C:\compilers\mingw64\mingw-w64.bat"

Invoke the batch, and verify the compiler version at the prompt again with g++ --version.

A Worse case scenario. No mingw64.bat was found. We can create our own facilities to grant the access.


BATCH
@ECHO OFF
SET PATH=C:\compilers\mingw64\bin;%PATH%
CALL cmd

Last step, remove the hard coded path in the batch file by using Environment Variables in Windows. Using hard coded paths in scripts or code is not a good practice. Let's provide windows with a bit more information to handle the path where mingw-w64.bat is located. This process is what's usually performed through installers and is an involved process that modifies Registry Entries in the OS, it can be a dangerous and spiky operation. For the newbies long story short, you can affect the global behavior of the OS. You don't need to touch any of that.

Method 1, using Path

This method grant global access to any arbitrary Path from the command line.

Open system environment variables: Advanced System Settings->Environmental variables->Path

envsettings

mymingw


BATCH

Update the batch file accordingly removing the hardcoded path and directly invoking the command line at that path.

@ECHO OFF
CALL cmd

Method 2, user variable

Limit global access, grant to only a command line instance and does NOT need to setup anything from Method 1.

image

Update the batch file accordingly replacing the hardcoded path with the environment variable we just created.


BATCH

Update the batch file accordingly removing the hardcoded path and directly invoking the command line at that path.

@ECHO OFF
SET PATH=%mymingw%;%PATH%
CALL cmd

There are more methods, try google the startup method in your user system path. The 2 alternatives listed here serve you as good introduction for more advanced configuration methods.

Extending batch functionality

We will extend the batch file to contain a SETUP tag, for the Mingw compiler, and another tag END, that terminates the program. This way we will be able to notify the user a possible error when trying to execute g++.


BATCH
@ECHO OFF
IF DEFINED mymingw (GOTO SETUP) ELSE (ECHO Mingw GCC is not installed)
GOTO END
:SETUP
SET PATH=%mymingw%;%PATH%
CALL cmd
:END

Without further introduction, we just used one of the instructions with worst reputation in computer science ** GOTO **statements, but don't spread the word. Djistra can explain it all GOTO statament considered harmful.

Revisiting compilation steps with Mingw

Introducing a new batch file, build.bat that will serve to automate the compilation process step by step. With the source code main.cpp

int main()
{
   return 0;
}

Add the COMPILE tag automating the g++ commands. Taking as a reference the step by step reference to g++ commands.

  1. Pre-process
  2. Generate machine code
  3. Dump machine code is readable form
  4. Link

BATCH
:COMPILE
    g++ -E main.cpp > preprocessmain.cpp 
    g++ -c preprocessmain.cpp -o main.obj
    objdump  -D main.obj > main.asm
    g++ -o main.exe main.obj

An active and continuous development of main.cpp, means editing the file many times using the same compilation environment. It is good idea to structure bat files that optimize the necessary calls, just what big IDEs generally do at a large scale.

The result now will create the different files with extensions .asm, .obj, pre-processed cpp and .exe. exe is a standard only in Windows platforms. An important difference when generating .asm with g++ compilers is the AT&T syntax. Compare to that generated with Microsoft compilers which is by default a Intel syntax. The section of main should look like this

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 20          	sub    $0x20,%rsp
   8:	e8 00 00 00 00       	callq  d <main+0xd>
   d:	b8 00 00 00 00       	mov    $0x0,%eax
  12:	48 83 c4 20          	add    $0x20,%rsp
 16:	5d                   	pop    %rbp

Switching target platform with the compiler tools

Mingw64 will by default produce x64 platform executables, you can verify it by using a program like EXE explorer for Windows. In UNIX-like OS's, usually the command file is already installed or available install, it will display detailed information of the executable.

In order to generate x86 binaries we need to specify in the g++ command a compiler flag specifying the platform -m32 (or -m64 if the compiler is by default compiling x86 executables). We will extend the bat by supporting both platforms. Run the bat using either x64 or x86 to produce the appropriate executables.


BATCH
 SET platform="-m64"
    SET platformname="x64"
    IF "%1"=="x64" ( GOTO COMPILE )
    IF "%1"=="x86" (
    SET platform="-m32"
    SET platformname="x86"
    ) ELSE ( GOTO COMPILE )
    :COMPILE

    g++ -E "%platform%" main.cpp > preprocessmain"%platformname%".cpp 
    g++ -c preprocessmain"%platformname%".cpp -o main"%platformname%".obj
    objdump  -D main"%platformname%".obj > main"%platformname%".asm
    g++ -o main"%platformname%".exe "%platform%" main"%platformname%".obj

Notice we have added the option platform (-m32 or -m64) to all g++ commands, take look at the linking stage. Without specifying the platform will fail! The linker needs to know what kind of code do the obj contain, therefore the platforms for both steps must match. An expansion when using x86 will produce the linking command


WINDOWS
>g++ -o main mainx86.exe -m32 mainx86.obj


Using GNU compilers with IDE's

Once you start feeling happy with the compiler and using some of the compiler flags like optimization, debugging, enabling language standards, etc... you will probably want to move to larger projects or join a team.

It is perhaps the time where you can take a look at some of the IDE's that provide access to GNU compilers there it is Clion and CodeBlocks to help you. More in the Setup And Configuration chapter. With the compiler command line knowledge you have at this point, you will still have a lot of power in your hands.

In the next lesson we will continue using all the tools created so far but with a set of programs that actually do something.

⚠️ **GitHub.com Fallback** ⚠️