processus de compilation du programme GCC-

Dans cet article, l'outil gcc compilateur pour le processus de compilation pour enregistrer le programme


Compilation (total)

Lorsque nous écrivons un programme simple, HelloWord, besoin de programmer dans un fichier exécutable, vous devez passer par l'étape suivante consiste à compiler.

hello.c
-----------------------------------------------
#include <stdio.h>

#define X 1

int main()
{
        int i=0;
        printf("hello world X = %d i=%d !\n",X,i);
        return 0;
}

Si vous utilisez l'outil de compilateur gcc, hello.c gcc besoin que d'une sortie peut être compilé a.out fichier. Mais la simple compilation contient plusieurs étapes - Précompilation, décompiler, assembler, lien (le lien ne parle pas strictement partie du processus de construction, ici pour parler directement ensemble), la compréhension de ces étapes aident à approfondir la compréhension du processus.

précompilés

langage C avec un « # » au début des pré-instructions, y compris #ifdef, #include #define et appartiennent à la directive pré-compilateur. étape précompilés, directive compilateur gcc fera un prétraitement sera utilisé pour placer la définition macro #define étendue en valeur réelle, attribuer des fichiers d'en-tête #include fichier à moyen, mais ne vérifie pas correctement après la copie, à l'exactitude l'écoulement ultérieur du processus.

gcc -E -o hello.i hello.c

Comme ci - dessus, de sorte que seule la mise en œuvre des processus gcc précompilés doivent ajouter -E option en général fichier de sortie précompilé .i suffixe. Les résultats de cette parties de fichier extrait, voir les états et les fichiers d' en- tête pertinents sont copiés dans le fichier après #include progresser, tandis que la fonction principale de l' utilisation du #define X est remplacé par les lieux réels 1.

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 367 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 410 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 411 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 368 "/usr/include/features.h" 2 3 4
# 391 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 392 "/usr/include/features.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4

...
...


extern int fprintf (FILE *__restrict __stream,
      const char *__restrict __format, ...);


extern int printf (const char *__restrict __format, ...);

...
...

# 5 "hello.c"
int main()
{
 int i=0;
 printf("hello world X = %d i=%d !\n",1,i);
 return 0;
}

Compile

Dans le document sur la base du processus suivante consiste à effectuer, la compilation et la compilation du début de cet article n'est pas la même chose ici, est compilé au début de cet article est d'expliquer plusieurs processus pour faire court. Compilé ce document fait référence au pré-compilateur pour compiler, dans lequel un seul processus. Compilateur génère le code assembleur correspondant à la machine, de même hello.c précompilés complété exemple hello.i, l'utilisation -S  paramètres de processus de compilation.

gcc -S -o hello.s hello.i
        .file   "hello.c"
        .section        .rodata
.LC0:
        .string "hello world X = %d i=%d !\n"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movl    $0, -4(%rbp)
        movl    -4(%rbp), %eax
        movl    %eax, %edx
        movl    $1, %esi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
        .section        .note.GNU-stack,"",@progbits

Assemblez, lien

étape de compilation à faire est de compiler le code assembleur processus de sortie est converti en code machine binaire, mais il ne dépend pas exécuté directement sur la nécessité de lier la bibliothèque ou d'un fichier afin d'obtenir le fichier exécutable final. processus de l' Assemblée à l' aide du  -c paramètre, le lien vous amène directement un lien les fichiers .o peuvent être exécutées directement gcc.

gcc -c -o hello.o hello.s
gcc -o hello hello.o

listes de liens que l'exemple de notre propre hello.o, je ne voyais pas les autres bibliothèques dépendantes, mais encore être en mesure de lien avec succès et peut effectuer la normale, parce que le système est dépendant des bibliothèques dans ce processus est chargé par défaut, ici directement dans le gcc au lien -v paramètre peut être observé,

 gcc -v -o hello  hello.o
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.12' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/ccLdFZul.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o hello /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. hello.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o

Utilisez les paramètres de sortie -v ci-dessus, utilisez Ctrl + f recherche -lc peut voir les paramètres apparaissent, qui est lié libc système de bibliothèque, commande ldd utilisation directe peut également voir le bonjour de fichier exécutable résultant dépend bibliothèque.

CryptonymAMS$: ldd hello
        linux-vdso.so.1 =>  (0x00007ffc397a6000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a8ed33000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4a8f0fd000)

Bonjour ici utilise une bibliothèque de liens dynamiques de lié au système, vous pouvez utiliser la commande de fichier pour afficher le lien dynamique, qui est, liaison dynamique.

hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=ac17e411d6f0b61087de124ee029056f09f4c990, not stripped

Jusqu'à présent, tout le processus du compilateur gcc est terminée, la sortie de fichier exécutable.

 

supplément

gcc paramètres couramment utilisés

-E :执行到预编译流程就停止,不执行后续编译、汇编等流程
-S :只执行到编译流程,不执行后续汇编等流程
-c :只执行到汇编流程,不执行链接流程

-o :指定输出文件的名字

-I :指定头文件路径
-L :指定库文件路径
-l :指定需要链接的库(如libc.so,只需要 -lc 即可)

-static :静态链接方式(可执行文件包含执行需要的所有信息,但是文件大小会比较大)
-nostdlib :不链接标准库

-v :查看gcc版本信息,编译过程使用时用于打印编译过程的输出

paramètres plus peuvent être directement ou homme gcc vue --help gcc.

Publié 19 articles originaux · a gagné les éloges 7 · vues 6927

Je suppose que tu aimes

Origine blog.csdn.net/G_METHOD/article/details/104163168
conseillé
Classement