Getting started with GCC

From ICO wiki
Revision as of 12:14, 15 October 2015 by Lvosandi (talk | contribs) (Created page with "GCC (GNU Compiler Collection) is a suite of tools aimed at compiling various programming languages for different CPU architectures. Following instructions can be carried out a...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

GCC (GNU Compiler Collection) is a suite of tools aimed at compiling various programming languages for different CPU architectures. Following instructions can be carried out at enos.itcollege.ee via SSH, the software is already installed there so you don't have to run apt-get install lines. On your personal Ubuntu machine you can install GCC via APT:

 apt-get install build-essential

Create a plain-text file libfib.c with following content:

 int fib(n) {
     if (n == 1 || n== 2) {
         return 1;
     } else {
         return fib(n-1) + fib(n-2);
     }
 }

Create another plain-text file to invoke the function described above:

 #include <stdio.h>

 int main(int argc, char **argv) {
   if (argc != 2) {
     printf("Please specify only one argument\n");
     return -1;
   } else {
     int n;
     sscanf("%d", argv[1], &n);
     printf("%dth fibonacci number is %d\n", n, fib(n));
     return 0;
   }
 }

Compiling native binaries

Generate assembly for the C file which contains fib function:

 gcc libfib.c -S -o libfib.s

Investigate the assembly corresponding to fib:

 cat libfib.s


Dynamic vs static linking

Use the compiler to compile assembly from the C source code:

 gcc -fPIC libfib.c -S -o libfib-native.s
 gcc hello.c -S -o hello-native.s

Turn assembly into object files:

 gcc -fPIC -c libfib-native.s -o libfib-native.o
 gcc -c hello-native.s -o hello-native.o

Finally link the object file against system libraries to produce usable binary:

 mkdir mylibs
 gcc -fPIC libfib-native.o -shared -o mylibs/libfib-native.so
 gcc hello-native.o -o hello-native -L mylibs -l fib-native

Invoke the binary to test if it actually works, expect the program to print line Hello, World!:

 LD_LIBRARY_PATH=mylibs ./hello-native 42

The binary was compiled dynamically which means that during it's invocation OS is requested to load dependent libraries to the memory is necessary. You can use ldd to investigate which libraries are required to invoke the binaries:

 LD_LIBRARY_PATH=mylibs ldd hello-native

Alternatively you can compile the binary statically, in that case all the necessary machinery get's bundled into the resulting binary:

 gcc libfib-native.o hello-native.o -static -o hello-native-static

Attempting to run ldd against such binary will result in error not a dynamic executable. Observe the file size of hello-native and hello-native-static, what is the difference and why?

Use objdump to locate the section corresponding to function fib.


Cross-compiling

Use ARM cross-compiler to compile ARM binaries on x86:

 arm-linux-gnueabihf-gcc hello.c -static -o hello
./a.out 

Hello, World! lvosandi@enos:~$ cat hello.c


lvosandi@enos:~$ arm-linux-gnueabihf-gcc -march=armv8-a hello.c -static -O hello arm-linux-gnueabihf-gcc: error: hello: No such file or directory lvosandi@enos:~$ arm-linux-gnueabihf-gcc -march=armv8-a hello.c -static -o hello lvosandi@enos:~$ ./hello Hello, World! lvosandi@enos:~$ file hello hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=f553117e8aa8d9d9e26ae85b29437b5193a1790a, not stripped