[LINUX] Flow from source code to creating executable

Overview

I tried to see the flow from source code to creating an executable using GCC.

environment

x86_64 centos7 gcc4.8.3

helloWorld

include <stdio.h>

int main(){
    printf("Hello world!!");
}

GCC Try to compile

 gcc hello.c -Wall -v
 I'm using the built-in spec.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.3/lto-wrapper
 Target: x86_64-redhat-linux
 configure settings: ../configure --prefix = / usr --mandir = / usr / share / man --infodir = / usr / share / info --with-bugurl = http: //bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads = posix --enable-checking = release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique -object --enable-linker-build-id --with-linker-hash-style = gnu --enable-languages = c, c ++, objc, obj-c ++, java, fortran, ada, go, lto --enable -plugin --enable-initfini-array --disable-libgcj --with-isl = / builddir / build / BUILD / gcc-4.8.3-20140911 / obj-x86_64-redhat-linux / isl-install --with- cloog = / builddir / build / BUILD / gcc-4.8.3-20140911 / obj-x86_64-redhat-linux / cloog-install --enable-gnu-indirect-function --with-tune = generic --with-arch_32 = x86-64 --build = x86_64-redhat-linux
 Thread model: posix
 gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC)
COLLECT_GCC_OPTIONS='-Wall' '-v' '-mtune=generic' '-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/4.8.3/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -Wall -version -o /tmp/ccyCCZPY.s
GNU C (GCC) version 4.8.3 20140911 (Red Hat 4.8.3-9) (x86_64-redhat-linux)
        compiled by GNU C version 4.8.3 20140911 (Red Hat 4.8.3-9), GMP version 5.1.1, MPFR version 3.1.1, MPC version 1.0.1
warning: GMP header version 5.1.1 differs from library version 6.0.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
 Ignore the non-existent directory "/usr/lib/gcc/x86_64-redhat-linux/4.8.3/include-fixed"
 Ignore the non-existent directory "/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../x86_64-redhat-linux/include"
# The search for include "..." begins here:
# The search for include <...> begins here:
 /usr/lib/gcc/x86_64-redhat-linux/4.8.3/include
 /usr/local/include
 /usr/include
 The end of the search list.
GNU C (GCC) version 4.8.3 20140911 (Red Hat 4.8.3-9) (x86_64-redhat-linux)
        compiled by GNU C version 4.8.3 20140911 (Red Hat 4.8.3-9), GMP version 5.1.1, MPFR version 3.1.1, MPC version 1.0.1
warning: GMP header version 5.1.1 differs from library version 6.0.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 0cfa3e41c61de51fe5b3d2388f47f98a
 hello.c: In the function ‘main’:
 hello.c: 5: 1: WARNING: Control reached end of non-void function [-Wreturn-type]
 }
 ^
COLLECT_GCC_OPTIONS='-Wall' '-v' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccYhWWtz.o /tmp/ccyCCZPY.s
 Use GNU Assembler version 2.23.52.0.1 (x86_64-redhat-linux), BFD version 2.23.52.0.1-30.el7_1.2 20130226
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.3/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.3/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.3/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.3/:/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-Wall' '-v' '-mtune=generic' '-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/4.8.3/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 
-dynamic-linker /lib64/ld-linux-x86-64.so.2 
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crt1.o 
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crti.o 
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/crtbegin.o 
-L/usr/lib/gcc/x86_64-redhat-linux/4.8.3
-L/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64 
-L/lib/../lib64 
-L/usr/lib/../lib64 
-L/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../.. 
/tmp/ccYhWWtz.o 
-lgcc --as-needed -lgcc_s --no-as-needed 
-lc 
-lgcc --as-needed -lgcc_s --no-as-needed 
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/crtend.o 
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crtn.o

Built-in specs

What is built-in spec

A specs file is plain text used to control the default behavior for the "gcc" front-end.

It seems that you can usually take it inside and overwrite it if you bring it outside. It looks like that.

COLLECT_LTO_WRAPPER It's a plugin used by GCC, and seems to be used internally to make work more efficient.

configure settings:

You can see the configure settings when building GCC.

compile

/ usr / libexec / gcc / x86_64-redhat-linux / 4.8.3 / cc1 is the actual compiler. The compiled assembler is output to /tmp/ccyCCZPY.s specified by -o.

 /usr/libexec/gcc/x86_64-redhat-linux/4.8.3/cc1 
-quiet -v hello.c -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -Wall -version -o /tmp/ccyCCZPY.s

assembler

Object file /tmp/ccYhWWtz.o with the assembler file /tmp/ccyCCZPY.s output by compilation as the input value Is output.

as -v --64 -o /tmp/ccYhWWtz.o /tmp/ccyCCZPY.s

linker

/ usr / libexec / gcc / x86_64-redhat-linux / 4.8.3 / collect2 is the actual linker. Create an executable file by linking the assembled object file /tmp/ccYhWWtz.o with various objects.

Dynamic linker designation

GCC dynamically links shared libraries unless otherwise specified. Therefore, the dynamic linker that links when the program is executed is specified. If -static is specified, shared libraries will also be linked statically. Dynamic link → Dynamic linker -dynamic-linker /lib64/ld-linux-x86-64.so.2

The one that implicitly links

These below are called before the main of C to prepare various things, and are called before the program ends to clean up. This should normally be statically linked.

  1. crtn.o
  2. crtend.o
  3. crtbegin.o
  4. crti.o
  5. crt1.o
Link other libraries

-l Extract xxx after -l and link libxxx.so for dynamic link and libxxx.a for static link. Even in the case of dynamic link, if there is no so, it seems to look for .a. This time xxx is a dynamic link with c, so link libc.so (standard C library) I feel like I did. (It should be dynamically linked)

ldd a.out 
    linux-gate.so.1 =>  (0xb776e000)
    libc.so.6 => /lib/libc.so.6 (0x49cbd000)
    /lib/ld-linux.so.2 (0x49c95000)

-L Specify the search location of the library

Summary

The compiler creates executable formats in the following order. (Hmm, it seems that the preprocessor is not specified.)

  1. Pre-process
  2. Compile
  3. Assemble
  4. Link

GCC does a lot of work internally. The substance in the narrow sense of the compiler is cc1. However, performing up to linking is also called compilation and building. You can see that various objects are linked just by compiling C, which is just helloworld.

Recommended Posts

Flow from source code to creating executable
Install ansible from source code
I made a package to create an executable file from Hy source code
Migrate from VS Code to PyCharm
Interrupt processing flow seen in source code
[Linux] Flow from power-on to PC startup
Install PostgreSQL from source code on CentOS
[Python] Flow from web scraping to data analysis
I want to make C ++ code from Python code!
Learn how to inflate images from TensorFlow code
Qiskit Source Code Reading ~ Terra: Read from circuit creation to adding gates and measurements
[Python] Django Source Code Reading View Starting from Zero ①
Machine learning python code summary (updated from time to time)
Let Code Day74 starting from zero "12. Integer to Roman"
[Updated from time to time] Review of Let Code NumPy
Steps from installing Python 3 to creating a Django app
Let Code Day68 starting from scratch "709. To Lower Case"
How to create a kubernetes pod from python code
Changes from Python 3.0 to Python 3.5
Transition from WSL1 to WSL2
Build PostgreSQL from source
Install python from source
From editing to execution
Summary from building Python 3.4. * From source to building a scientific computing environment
A quick explanation from creating AWS Lambda Layers to linking
PyArmor ~ Easy way to encrypt and deliver python source code ~