C/C++

Hướng Dẫn Build Mã Nguồn C/C++ với Terminal (Nâng Cao)

Ở bài viết trước tôi đã giới thiệu cho các bạn cách build mã nguồn C/C++ đơn giản chỉ gồm một file main.c. Cùng nhìn lại bài trước nếu trường hợp đặt ra là mã nguồn của chúng ta gồm nhiều file và nhiều module, có sử dụng thư viện ngoài thì chúng ta phải làm thế nào. Và như đã hứa ở bài viết đó, bài viết này tôi sẽ giới thiệu các build mã nguồn C/C++ một cách nâng cao hơn với gcc như build một module mã nguồn C/C++ và cách link thư viện ngoài mà trong chương trình của chúng ta có sử dụng.

Giới thiệu

Ở bài viết trước tôi đã giới thiệu cho các bạn cách build mã nguồn C/C++ đơn giản chỉ gồm một file main.c. Cùng nhìn lại bài trước nếu trường hợp đặt ra là mã nguồn của chúng ta gồm nhiều file và nhiều module, có sử dụng thư viện ngoài thì chúng ta phải làm thế nào. Và như đã hứa ở bài viết đó, bài viết này tôi sẽ giới thiệu các build mã nguồn C/C++ một cách nâng cao hơn với gcc như build một module mã nguồn C/C++ và cách link thư viện ngoài mà trong chương trình của chúng ta có sử dụng.

Nếu bạn chưa đọc phần 1 của bài viết này thì hãy quay lại đọc bài viết dưới đây trước khi đọc bài viết này.

http://eitguide.com/cach-build-mot-chuong-trinh-cc-bang-terminal/

 

Nhắc lại về kiến thức cũ

Ở bài trước để build một chương trình đơn giản chúng ta sử dụng cú pháp như sau

gcc -Wall -o <file thực thi> <các file nguồn>

Với

  • -Wall chỉ định cho gcc sẽ xuất ra tất cả các warning trong quá trình build.
  • -o chỉ đinh cho gcc sẽ build source file thành file thực thi (excutable).
  • file thực thi là file output sau quá trình build và link các thư viện.
  • các file nguồn đầu vào cho việc build ra file thực thi.

Hoặc

gcc -c <các source cần build>

Để build source file thành các file object (chưa build và link ra file thực thi)

Ví dụ:

gcc -Wall -o main main.c

Hay

gcc -c main.c

gcc -Wall -o main main.o

Và để chạy chương trình chúng ta sử dụng lệnh

./main

Các bước để build một chương trình C/C++

build_cc_terminal_ss0

Quá trình build một chương trình của chúng ta trải qua gồmm bốn bước như dưới đây:

Bước 1: Preprocess

Ở bước này trình biên dịch sẽ thay thế giá trị của các define, marco trong file mã nguồn .h và .cpp.

Bước 2: Bước này trình biên dịch sẽ dịch mã nguồn của chúng ta thành mã assemly.

Bước 3: Từ mã assemly sẽ được build xuống mã nhị phân (hay gọi là mã máy machine code).

Bước 4: Tiến hành link các module và các thư viện ngoài thành file thực thi.

Và đây là 4 bước để build một chương trình C/C++.

Build Module C/C++ với gcc

Giả sử trong Project của tôi có một module math có chức năng tính toán cộng trừ nhân chia.

build_cc_terminal_ss1

Trong thư mục math có hai file là math.h định nghĩa prototype của các hàm và math.c sẽ implement các prototype trong math.h

File math.h

File math.c

File main.c 

Chúng ta thấy rằng trong file main của chúng ta có sử dụng module math vì vậy trước chi build main.c chúng ta phải build math.c sau đó link math.o (file sau khi được build math.c) và main.c

Bước 1: Build module math

gcc -c math/math.c

Sau khi build chúng ta sẽ được file math.o

Bước 2: Link math.o và main.c

gcc -Wall -o main math.o main.c

Sau khi chạy xong sẽ phát sinh file thực thi main.

Chúng ta gõ

./main

Và thấy kết quả xuất ra:

Vậy là chúng ta đã biết cách build module C/C++ sử dụng gcc. Tiếp theo phần dưới đây tôi sẽ bàn về cách link các thư viện ngoài ví dụ như FFMPEG, OPENCV, FREETYPE, SDL….

Link thư viện ngoài với gcc

Trước khi đi vào phần này tôi muốn giới thiệu cho các bạn hai loại thư viện được sử dụng trong C/C++ là

Thư viện liên kết tỉnh (Static Library)

Trong Linux thư viện liên kết tỉnh có đuôi .a. Khi link thư viện liên kết tỉnh với mã của chúng ta để tạo ra file thực thi thì gcc sẽ nạp tất cả mã của thư viện liên kết tỉnh vào file thực thi. Vì vậy kích thước của file thực thì khi này là khá lớn.

Thư viện liên kết động (Dynamic Library)

Trong Linux thư viện liên kết động có đuôi là .so. Khác với thư viện liên kết tỉnh, thì thi link thư viện liên kết động với mã của chúng ta để tạo ra file thực thi thì gcc sẽ không nạp mã của thư viện liên kết động vào file thực thi. Mà khi chương trình runtime thì chương trình mới link các phương thức cần sử dụng trong thư viện liên kết động. Vì vậy mà file thực thi sau khi link xong sẽ có kích thức nhỏ.

Cả hai thư viện này đều chứa mã nhị phân và có những file header .h chứa các prototype của các hàm trong thư viện.

Đa số các thư viện lớn như FFMPEG, OPENCV, SDL sau khi build xong sẽ cho chúng ta thư viện liên kết động và thư viện liên kết tỉnh

Dưới đây là một đoạn mã nguồn sử dụng OpenCV

Vậy làm sao chúng ta build được chương trình này:

Thứ nhất: Cần chỉ định cho gcc đường dẫn chứa các file header của thư viện sử dụng -I

Thứ hai: Cần chỉ định cho gcc đường dẫn chứa các file library của thư viện sử dụng -L

Thứ ba: Cần  link các module thư viện liên kết.

Ví dụ thư viện OpenCV của tôi có

/usr/local/include là đường dẫn chứa header của thư viện

/usr/local/lib là đường dẫn chứa lib của thư viện

Và các module của OpenCV

lib_opencv_eitguide

Và chúng ta gõ lệnh để build như sau:

Vì OpenCV được viết bằng C++ nên tôi sử dụng g++ để build thay vì dùng gcc

Sau khi gõ dòng lệnh ./main để chay chương trình chúng ta thấy xuất ra như sau

Nếu các bạn có sử dụng IDE để làm việc thì việc link các thư viện này hoàn toàn tương tự. Các bạn có thể xem clip link thư viện OpenCV trong Xcode

Kết luận

Cùng nhìn lại bài trước và bài này thì chúng ta có thể build được tất cả các mã nguồn C/C++ từ mộ chương trình đơn giản đến việc build các module, link các thư viện liên kết ngoài. Nhưng chúng ta thấy là một nhược điểm rất lớn là chúng ta gõ trên terminal khá nhiều. Nếu như project của chúng ta có 1000 file .c thì tương đương chúng ta phải gõ 1ooo lần trên terminal. Để khắc phục nhược điểm này chúng ta có thể viết Makefile để khắc phục vấn đề trên. Vấn đề viết makefile để build mã nguồn C/C++ sẽ được tôi đề cập ở bài viết sau. Nếu có bất cứ thắc mắc nào các bạn có thể để lại câu hỏi ở bên dưới phần bình luận.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.