Quá Trình Compile Bằng GCC - Dung's Blog
Có thể bạn quan tâm
gcc (GNU Compiler Collection) là tập hợp các chương trình dịch dùng để biên dịch các ngôn ngữ khác nhau. gcc là chương trình dịch chính thức của hệ thống GNU bao gồm hệ điều hành giống-UNIX, Linux, Mac OS và một số hệ điều hành khác. Quá trình biên dịch sẽ phải đi qua một chuỗi các bước để tạo ra file thực thi cuối cùng. Các bước trung gian đó là kết quả của các tool khác nhau được gọi bên trong gcc để hoàn thành quá trình dịch source code.
Toàn bộ quá trình dịch bằng GCC được chia ra làm các bước sau:
- Preprocessing
- Compilation
- Assembler
- Linking
Trong bài viết này chúng ta sẽ sử dụng file hello.c sau làm ví dụ:
#include <stdio.h> #define STRING "Hello World" int main (void) { printf ("My First program - %s\n",STRING); return 0; }1. Preprocessing (tiền xử lý)
Về cơ bản bộ tiền xử lý C có 3 nhiệm vụ chính:
- Text Substitution: thay thế text
- Stripping of Comments: loại bỏ comment
- File Inclusion: nối file (mở rộng file)
Việc thay thế text và nối file đươc yêu cầu trong code bằng cách sử dụng Preprocessor Directives, đó chính là các dòng code bắt đầu với ký tự “#”.
Thường thì ở bước này các file header và các macro được defined sẽ được mở rộng và gộp vào trong source code tạo thành một file tạm, thường gọi là đơn vị dịch ( translation unit hay compilation unit). Bộ tiền xử lý C, hay còn gọi là cpp, là một đơn vị vi xử lý được sử dụng vởi trình biên dịch C để biến đổi chương trình C trước khi dịch. Để thực hiện tiền xử lý ta thường dùng dòng lệnh:
[bash]$ cpp hello.c > hello.iKết quả ta được output là file hello.i chứa source code đã được mở rộng bao gồm các macro. Theo quy ước file mở rộng này sẽ có phần đuôi là .i đối với C và .ii đối với C++.
Note: Mặc định các file output của quá trình tiền xử lý này sẽ không được lưu vào đĩa cứng trừ khi ta dùng gcc với option -save-temps.
Chúng ta có thể trực tiếp thực hiện quá trình tiền xử lý với gcc bằng cách dùng cờ “-E”.
[bash]$ gcc -E hello.c -o hello.iFile output sẽ có dạng như sau. Vì file studio.h quá lớn nên mình xin phép bỏ qua 😀
# 1 "hello.c" # 1 "/usr/include/stdio.h" 1 3 # 1 "/usr/include/_ansi.h" 1 3 # 1 "/usr/include/sys/config.h" 1 3 # 14 "/usr/include/sys/config.h" 3 # 25 "/usr/include/sys/config.h" 3 # 44 "/usr/include/sys/config.h" 3 # 40 "/usr/include/stdio.h" 2 3 # 1 "/usr/include/sys/reent.h" 1 3 int main(void){ printf ("My First Program - %s\n", "HELLO WORLD" ); return 0; }Vì chương trình yêu cầu file stdio.h, từ đó kéo theo yêu cầu thêm các file khác nữa. Vì vậy, bộ tiền xử lý tạo ra các ghi chú về file và dòng trong file nơi thực hiện request file để thực hiện các bước tiếp theo. Do vậy, các dòng,
# 40 "/usr/include/stdio.h" 2 3 # 1 "/usr/include/sys/reent.h" 1 3chỉ ra rằng file reent.h được request ở dòng 40 trong file stdio.h. Bộ tiền xử lý tạo ra số dòng và gắn nhãn file name mà nó có thể dùng tới ở các bước tiếp theo. Nhờ đó nó có thể biết được lỗi xảy ra ở đâu trong quá trình biên dịch.
2. Compilation
Bước tiếp theo là quá trình biên dịch từ source code đã thực hiện tiền xử lý ra file source code assembly. Với mỗi một bộ vi xử lý, mỗi kiến trúc vi xử lý khác nhau thì file source code sẽ được dịch ra ngôn ngữ assembly tương ứng.
Dùng gcc với cờ -S để convert file source code đã tiền xử lý ra ngôn ngữ assembly mà không tạo ra file object :
[bash]$ gcc -Wall -S hello.i -o hello.sKết quả ta có file hello.s dưới dạng ngôn ngữ assembly.
3. Assembler
Chúng ta đã được dạy là máy tình thì chỉ hiểu được ngôn ngữ máy. Vì thế chúng ta phải dịch file hello.s ra ngôn ngữ máy để máy tính có thể hiểu và thực thi. Mặc dù quá trình dịch từ một ngôn ngữ assembly ra ngôn ngữ máy là quá trình mapping 1-1, nhưng nếu thực hiện bằng tay thì đây là công việc nhàm chán và rất dễ gây ra lỗi.
NOTE: ASSEMBLER là một trong những công cụ phần mềm đầu tiên được phát minh sau sự ra đời của máy tính điện tử.
Nếu có một lời gọi hàm nào từ trong code assembly ra bên ngoài file, Assembler sẽ để địa chỉ lời gọi đó là chưa xác định (undefined), và sẽ được điền vào ở bước tiếp theo, Linker.
Assembler trong gcc có thể được gọi như dưới đây:
[bash]$ as hello.s -o hello.oVới gcc, file output được xác định với option -o. File hello.o chính là file mã máy của hello.c.
hoặc dùng option “-c” của gcc để convert:
[bash]$ gcc -c hello.c4. Linker
Bước cuối cùng của quá trình biên dịch là tạo ra một file thực thi duy nhất bằng cách link các file object. Một file object và file thực thi có nhiều định dạng như ELF (Executable and Linking Format) và COFF (Common Object-File Format). Ví dụ, ELF được sử dụng trên các máy Linux, COFF được sử dụng trên máy Windows.
Trong thực tế, một file thực thi gọi đến nhiều hàm bên ngoài từ hệ thống và các thư viện C. Linker sẽ xử lý tất cả các thành phần phụ thuộc và cung cấp địa chỉ của các hàm được gọi.
Linker cũng thực hiện một số nhiệm vụ khác. Nó kết hợp chương trình của chúng ta với một số tác vụ chuẩn cần thiết giúp chương trình có thể chạy. Ví dụ như thiết lập môi trường chạy, truyền các tham số dòng lệnh và các biến môi trường. Ngoài ra, còn cần có code chạy ở cuối chương trình, nơi kết quả được retrun. Do đó khối lượng code là không hề nhỏ.
Thực tế cơ chế được sử dụng bên trong gcc để link các file tương đối phức tạp. Ví dụ, câu lệnh để link hello.c sẽ là:
[bash]$ ld -dynamic-linker /lib/ld-linux.so.2/usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i686/3.3.1/crtbegin.o-L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh/usr/lib/gcc-lib/i686/3.3.1/crtend.o /usr/lib/crtn.oMay mắn là chúng ta sẽ không phải trực tiếp gõ câu lệnh trên — quá trình link sẽ được gcc thực hiện mà khi chúng ta thực hiện câu lệnh sau:
[bash]$ gcc hello.oNó sẽ link file object hello.o với các thư viện chuẩn của C và tạo ra file thực thi a.out.
[bash]$ ./a.out My First Program - Hello WorldTương tự, một file object của một chương trình C++ program có thể được link với các thư viện chuẩn C++ với câu lệnh g++.
Chia sẻ:
Có liên quan
Từ khóa » Câu Lệnh Gcc
-
How To Compile A C Program Using The GNU Compiler (GCC)
-
Thử Thực Hiện 4 Stage Khi Compile C Bằng GCC - Kipalog
-
Khởi Tạo Môi Trường Lập Trình C Trên Linux Với GCC
-
Trình Biên Dịch Gcc - 123doc
-
Gcc Là Gì - Darkedeneurope
-
[PDF] Bài 2: LẬP TRÌNH C TRÊN LINUX
-
Bài 3. Biên Dịch Code C Sử Dụng G++
-
Hướng Dẫn Cài đặt GCC Trên Ubuntu 20.04 - N Support
-
Cách Cài đặt Bộ Sưu Tập Trình Biên Dịch GCC Trên CentOS 8 Và ...
-
Bài 2: Hướng Dẫn Cài đặt C - Học Lập Trình C Cơ Bản
-
C — Hàm ẩn Danh Sử Dụng Biểu Thức Câu Lệnh GCC - Wake-up
-
Cách Cài đặt GCC Trên Ubuntu
-
Cách Biên Dịch Và Chạy Chương Trình C / C ++ Trong Linux