GCC and Make Compiling
GCC and Make Compiling
GCC is portable and run in many operating platforms. GCC (and GNU Toolchain) is currently available on all Unixes. They are
also ported to Windows (by Cygwin, MinGW and MinGW-W64). GCC is also a cross-compiler, for producing executables on
different platform.
GCC Versions
The various GCC versions are:
GCC version 1 (1987): Initial version that support C.
GCC version 2 (1992): supports C++.
GCC version 3 (2001): incorporating ECGS (Experimental GNU Compiler System), with improve optimization.
GCC version 4 (2005):
GCC version 5 (2015):
GCC Version 6 (2016):
GCC Version 7 (2017):
The default mode is C++98 for GCC versions prior to 6.1, and C++14 for GCC 6.1 and above. You can use command-line flag -std to
explicitly specify the C++ standard. For example,
-std=c++98, or -std=gnu++98 (C++98 with GNU extensions)
-std=c++11, or -std=gnu++11 (C++11 with GNU extensions)
-std=c++14, or -std=gnu++14 (C++14 with GNU extensions), default mode for GCC 6.1 and above.
-std=c++17, or -std=gnu++17 (C++17 with GNU extensions), experimental.
-std=c++2a, or -std=gnu++2a (C++2a with GNU extensions), experimental.
$ x86_64-w64-mingw32-gcc -v
Using built-in specs.
COLLECT_GCC=x86_64-w64-mingw32-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-w64-mingw32/6.4.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: .....
Thread model: posix
gcc version 6.4.0 (GCC)
$ x86_64-w64-mingw32-g++ --version
x86_64-w64-mingw32-g++ (GCC) 6.4.0
$ i686-w64-mingw32-g++ --version
i686-w64-mingw32-g++ (GCC) 6.4.0
Other GCCs in Cygwin
Other GCC packages in Cygwin are:
gcc-core, gcc-g++: Basic 64-bit C/C++ compiler target 64-bit Cygwin. You probably should install these two packages too.
However, to distribute the code produced, you need to distribute Cygwin Runtime Environment (cygwin1.dll). This is
because Cygwin is a Unix emulator under Windows.
cygwin32-gcc-core, cygwin32-gcc-g++: Older 32-bit C/C++ compiler for target 32-bit Cygwin (Obsoleted by gcc-
code and gcc-g++?).
mingw-gcc-core, mingw-gcc-g++: Older MinGW 32-bit C/C++ compiler for 32-bit Windows (Obsoleted by MinGW-W64
packages?).
1.5 Post Installation
Versions
You could display the version of GCC via --version option:
$ gcc --version
gcc (GCC) 6.4.0
$ g++ --version
g++ (GCC) 6.4.0
More details can be obtained via -v option, for example,
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/6.4.0/lto-wrapper.exe
Target: x86_64-pc-cygwin
Configured with: ......
Thread model: posix
gcc version 6.4.0 (GCC)
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/6.4.0/lto-wrapper.exe
Target: x86_64-pc-cygwin
Configured with: ......
Thread model: posix
gcc version 6.4.0 (GCC)
Help
You can get the help manual via the --help option. For example,
$ gcc --help
Man Pages
You can read the GCC manual pages (or man pages) via the man utility:
$ man gcc
// or
$ man g++
// Press space key for next page, or 'q' to quit.
Reading man pages under CMD or Bash shell can be difficult. You could generate a text file via:
$ man gcc | col -b > gcc.txt
The col utility is needed to strip the backspace. (For Cygwin, it is available in "Utils", "util-linux" package.)
Alternatively, you could look for an online man pages, e.g., http://linux.die.net/man/1/gcc.
The GCC man pages are kept under "usr/share/man/man1".
$ whereis gcc
1.6 Getting Started
The GNU C and C++ compiler are called gcc and g++, respectively.
To compile the hello.c:
> gcc hello.c
// Compile and link source file hello.c into executable a.exe (Windows) or a (Unixes)
The default output executable is called "a.exe" (Windows) or "a.out" (Unixes and Mac OS X).
To run the program:
// (Windows) In CMD shell
>a
// (Unixes / Mac OS X) In Bash Shell - include the current path (./)
$ chmod a+x a.out
$ ./a.out
You need to use g++ to compile C++ program, as follows. We use the -o option to specify the output file name.
// (Windows) In CMD shell
> g++ -o hello.exe hello.cpp
// Compile and link source hello.cpp into executable hello.exe
> hello
// Execute under CMD shell
// (Unixes / Mac OS X) In Bash shell
$ g++ -o hello hello.cpp
$ chmod a+x hello
$ ./hello
More GCC Compiler Options
A few commonly-used GCC compiler options are:
$ g++ -Wall -g -o Hello.exe Hello.cpp
-o: specifies the output executable filename.
-Wall: prints "all" Warning messages.
-g: generates additional symbolic debuggging information for use with gdb debugger.
GCC compiles a C/C++ program into executable in 4 steps as shown in the above diagram. For example, a "gcc -o hello.exe hello.c" is
carried out as follows:
1. Pre-processing: via the GNU C Preprocessor (cpp.exe), which includes the headers (#include) and expands the macros
(#define).
> cpp hello.c > hello.i
The resultant intermediate file "hello.i" contains the expanded source code.
2. Compilation: The compiler compiles the pre-processed source code into assembly code for a specific processor.
> gcc -S hello.i
The -S option specifies to produce assembly code, instead of object code. The resultant assembly file is "hello.s".
3. Assembly: The assembler (as.exe) converts the assembly code into machine code in the object file "hello.o".
> as -o hello.o hello.s
4. Linker: Finally, the linker (ld.exe) links the object code with the library code to produce an executable file "hello.exe".
> ld -o hello.exe hello.o ...libraries...
Try running the compilation in verbose mode (-v) to study the library-paths (-L) and libraries (-l) used in your system:
> gcc -v -o hello.exe hello.c
......
-L/usr/lib/gcc/x86_64-pc-cygwin/6.4.0
-L/usr/x86_64-pc-cygwin/lib
-L/usr/lib
-L/lib
-lgcc_s // libgcc_s.a
-lgcc // libgcc.a
-lcygwin // libcygwin.a
-ladvapi32 // libadvapi32.a
-lshell32 // libshell32.a
-luser32 // libuser32.a
-lkernel32 // libkernel32.a
Eclipse CDT: In Eclipse CDT, you can set the include paths, library paths and libraries by right-click on the project ⇒ Properties ⇒
C/C++ General ⇒ Paths and Symbols ⇒ Under tabs "Includes", "Library Paths" and "Libraries". The settings are applicable to the
selected project only.
The utility "file" can be used to display the type of object files and executable files. For example,
$ gcc -c hello.c
$ gcc -o hello.exe hello.o
$ file hello.c
hello.c: C source, ASCII text, with CRLF line terminators
$ file hello.o
hello.o: data
2. GNU Make
The "make" utility automates the mundane aspects of building executable from source code. "make" uses a so-
called makefile, which contains rules on how to build the executables.
You can issue "make --help" to list the command-line options; or "man make" to display the man pages.
Create the following file named "makefile" (without any file extension), which contains rules to build the executable, and save in the
same directory as the source file. Use "tab" to indent the command (NOT spaces).
all: hello.exe
hello.exe: hello.o
gcc -o hello.exe hello.o
hello.o: hello.c
gcc -c hello.c
clean:
rm hello.o hello.exe
Running make without argument starts the target "all" in the makefile. A makefile consists of a set of rules. A rule consists of 3 parts:
a target, a list of pre-requisites and a command, as follows:
target: pre-req-1 pre-req-2 ...
command
NOTES:
If the command is not preceded by a tab, you get an error message "makefile:4: *** missing separator. Stop."
If there is no makefile in the current directory, you get an error message "make: *** No targets specified and no makefile
found. Stop."
The makefile can be named "makefile", "Makefile" or "GNUMakefile", without file extension.
2.2 More on Makefile
Comment & Continuation
A comment begins with a # and lasts till the end of the line. Long line can be broken and continued in several lines via a back-slash
(\).
Syntax of Rules
A general syntax for the rules is:
target1 [target2 ...]: [pre-req-1 pre-req-2 ...]
[command1
command2
......]
The rules are usually organized in such as way the more general rules come first. The overall rule is often name "all", which is the
default target for make.
Variables
A variable begins with a $ and is enclosed within parentheses (...) or braces {...}. Single character variables do not need the
parentheses. For example, $(CC), $(CC_FLAGS), $@, $^.
Automatic Variables
Automatic variables are set by make after a rule is matched. There include:
$@: the target filename.
$*: the target filename without the file extension.
$<: the first prerequisite filename.
$^: the filenames of all the prerequisites, separated by spaces, discard duplicates.
$+: similar to $^, but includes duplicates.
$?: the names of all prerequisites that are newer than the target, separated by spaces.
hello.o: hello.c
gcc -c $<
clean:
rm hello.o hello.exe
Pattern Rules
A pattern rule, which uses pattern matching character '%' as the filename, can be applied to create a target, if there is no explicit rule.
For example,
# Applicable for create .o object file.
# '%' matches filename.
# $< is the first pre-requisite
# $(COMPILE.c) consists of compiler name and compiler options
# $(OUTPUT_OPTIONS) could be -o $@
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
# Applicable for create executable (without extension) from object .o object file
# $^ matches all the pre-requisites (no duplicates)
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
# Here is a Make Macro that uses the backslash to extend to multiple lines.
OBJS = \
Test1.o \
Test2.o \
Main.o
# There are two standard Targets your Makefile should probably have:
# "all" and "clean", because they are often command-line Goals.
# Also, these are both typically Artificial Targets, because they don't typically
# correspond to real files named "all" or "clean".
# There is no required order to the list of rules as they appear in the Makefile.
# Make will build its own dependency tree and only execute each rule only once
# its dependencies' rules have been executed successfully.
# Here is a Rule that uses some built-in Make Macros in its command:
# $@ expands to the rule's target, in this case "test_me.exe".
# $^ expands to the rule's dependencies, in this case the three files
# main.o, test1.o, and test2.o.
$(LINK_TARGET) : $(OBJS)
g++ -g -o $@ $^
# These are Dependency Rules, which are rules without any command.
# Dependency Rules indicate that if any file to the right of the colon changes,
# the target to the left of the colon should be considered out-of-date.
# The commands for making an out-of-date target up-to-date may be found elsewhere
# (in this case, by the Pattern Rule above).
# Dependency Rules are often used to capture header file dependencies.
Main.o : Main.h Test1.h Test2.h
Test1.o : Test1.h Test2.h
Test2.o : Test2.h
2.4 Brief Summary
I have presented the basic make features here so that you can read and understand simple makefiles for building C/C++ applications.
Make is actually quite complex, and can be considered as a programming language by itself!!