Biên Dịch Chương Trình Dạng Thư Viện Trong C - NTEAM

1. Các dạng thư viện

Các phần xử lý có mục đích dùng chung (dùng lại) thường được biên dịch thành các file thư viện. Có 2 loại thư viện là thư viện liên kết động và thư viện liên kết tĩnh.

Thư viện liên kết tĩnh:

Các chương trình muốn sử dụng thư viện liên kết tĩnh, thì khi biên dịch sẽ đóng gói luôn cả phần thư viện vào trong chương trình. Và khi chương trình chạy thì cả chương trình cùng thư viện sẽ được load vào bộ nhớ.

Các file thư viện liên kết tĩnh trên windows là các file .lib, trên linux là các file .a

Khi các chương trình sử dụng các file thư viện liên kết tĩnh, nếu thư viện có thay đổi, thì toàn bộ các chương trình sử dụng thư viện đều phải compile lại.

Thư viện liên kết động

File thư viện và chương trình độc lập nhau. Khi biên dịch cần chỉ đường dẫn đến folder chứa file thư viện để trình biên tạo link liên kết khi chương trình gọi thư viện. Khi chương trình chạy thì chỉ phần chương trình sẽ được load trước vào bộ nhớ. Khi nào các xử lý trong thư viện được gọi thì thư viện mới được load vào bộ nhớ.

Các file thư viện liên kết động trên windows là các file .dll, trên linux là các file .so

Khi các chương trình sử dụng file thư viện liên kết động thì khi thư viện có thay đổi, thì các chương trình cũng không phải compile lại.

2. Biên dịch

Có 2 trình biên dịch phổ biến là cc của Sun Solaris và gcc của GNU. Trong bài này sẽ lấy ví dụ dùng cả 2 trình biên dịch này. Các file source ví dụ có nội dung như sau.

file1.c

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Show hidden characters
int sum(int a, int b)
{
return a + b;
}

view raw file1.c hosted with ❤ by GitHub

file2.c

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Show hidden characters
static const int MAX = 100;
static const int MIN = 0;
int isOver(int a)
{
return (a > MAX);
}
int isUnder(int a)
{
return (a < MIN);
}

view raw file2.c hosted with ❤ by GitHub

main.c

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Show hidden characters
#include<stdio.h>
int sum(int, int);
int isOver(int);
int isUnder(int);
int main(void)
{
int a = 19;
int b = 82;
int sumVal = sum(a, b);
printf("\n The result sumary of %i and %i is %i\n", a, b, sumVal);
if ( isOver(sumVal) ) {
printf("\n The result is over the limit value\n");
}
if ( isUnder(sumVal) ) {
printf("\n The result in under the floor value\n");
}
return 0;
}

view raw main.c hosted with ❤ by GitHub

※ Script biên dịch ví dụ này chạy trên linux.

Biên dịch thư viện tĩnh

Trong script biên dịch dưới đây, có thể dùng trình biên dịch gcc thay thế cho cc đều cho kết quả tương tự.

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Show hidden characters
ls -l
# total 24
# -rw-r–r– 1 luongvandu staff 43 Apr 10 14:48 file1.c
# -rw-r–r– 1 luongvandu staff 143 Apr 10 14:48 file2.c
# -rw-r–r– 1 luongvandu staff 375 Apr 10 14:55 main.c
cc -Wall -c file1.c file2.c
# option -Wall có nghĩa view tất cả các warning khi compile
# option -c có nghĩa compile đến file object. Nếu option la -o thì sẽ compile đến file chạy cuối cùng
ls -l
# total 40
# -rw-r–r– 1 luongvandu staff 43 Apr 10 14:48 file1.c
# -rw-r–r– 1 luongvandu staff 616 Apr 10 16:47 file1.o
# -rw-r–r– 1 luongvandu staff 143 Apr 10 14:48 file2.c
# -rw-r–r– 1 luongvandu staff 756 Apr 10 16:47 file2.o
# -rw-r–r– 1 luongvandu staff 375 Apr 10 14:55 main.c
# Xem các hàm có trong object file
nm file1.o
# 0000000000000000 T _sum
nm file2.o
# 0000000000000000 T _isOver
# 0000000000000020 T _isUnder
# Gói các file object vào trong file thư viện tĩnh
ar -cqv libcommon.a file1.o file2.o
# q – file1.o
# q – file2.o
# Check lại nội dung nằm trong gói thư viện tĩnh
ar -t libcommon.a
# __.SYMDEF SORTED
# file1.o
# file2.o
# Compile chương trình dùng gói thư viện tĩnh
cc -o main main.c -L/Users/luongvandu/src/c -lcommon
# option -L để chỉ đường dẫn đến thư mục chứa file thư viện. Cần sửa phù hợp với bạn.
# option -l chỉ tên gói thư viện tĩnh sử dụng. Chữ "lib" ở đầu được lược bỏ.
ls -l
# total 72
# -rw-r–r– 1 luongvandu staff 43 Apr 10 14:48 file1.c
# -rw-r–r– 1 luongvandu staff 616 Apr 10 16:47 file1.o
# -rw-r–r– 1 luongvandu staff 143 Apr 10 14:48 file2.c
# -rw-r–r– 1 luongvandu staff 756 Apr 10 16:47 file2.o
# -rw-r–r– 1 luongvandu staff 1664 Apr 10 16:59 libcommon.a
# -rwxr-xr-x 1 luongvandu staff 8544 Apr 10 17:01 main
# -rw-r–r– 1 luongvandu staff 428 Apr 10 16:57 main.c
# Chạy chương trình và kết quả
./main
# The result sumary of 19 and 82 is 101
#
# The result is over the limit value
# Thư viện đã được include tĩnh vào trong chương trình nên file thư viện có thay đổi thi CT vẫn hoạt động bình thường.
mv libcommon.a libcommon.a.bak
./main
# The result sumary of 19 and 82 is 101
#
# The result is over the limit value

view raw static_lib_compile.sh hosted with ❤ by GitHub

Biên dịch thư viện động

Trong script biên dịch dưới có thể dùng trình biên dịch cc thay cho gcc đều cho kết quả tương tự.

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Show hidden characters
ls -l
# total 24
# -rw-r–r– 1 luongvandu staff 43 Apr 10 14:48 file1.c
# -rw-r–r– 1 luongvandu staff 143 Apr 10 14:48 file2.c
# -rw-r–r– 1 luongvandu staff 375 Apr 10 14:55 main.c
gcc -Wall -c file1.c file2.c
# option -Wall có nghĩa view tất cả các warning khi compile
# option -c có nghĩa compile đến file object. Nếu option la -o thì sẽ compile đến file chạy cuối cùng
ls -l
# total 40
# -rw-r–r– 1 luongvandu staff 43 Apr 10 14:48 file1.c
# -rw-r–r– 1 luongvandu staff 616 Apr 10 20:19 file1.o
# -rw-r–r– 1 luongvandu staff 143 Apr 10 14:48 file2.c
# -rw-r–r– 1 luongvandu staff 756 Apr 10 20:19 file2.o
# -rw-r–r– 1 luongvandu staff 428 Apr 10 16:57 main.c
# Xem các hàm có trong object file
nm file1.o
# 0000000000000000 T _sum
nm file2.o
# 0000000000000000 T _isOver
# 0000000000000020 T _isUnder
# Biên dịch thành file thư viện liên kết động
gcc -shared -fPIC -o libcommon.so file1.o file2.o
# option -shared có nghĩa compile thành thư viện.
# option -fPIC viết tắt của Position Independent Code, option này được đi cùng với -shared để tránh việc giới hạn global offset table
# Check lại nội dung nằm trong gói thư động
nm libcommon.so
# 0000000000000f50 T _isOver
# 0000000000000f70 T _isUnder
# 0000000000000f30 T _sum
# U dyld_stub_binder
# Compile chương trình liên kết đến gói thư viện động
gcc -L/Users/luongvandu/src/c -Wall main.c -o main -lcommon
# option -L để chỉ đường dẫn đến thư mục chứa file thư viện. Cần sửa phù hợp với bạn.
# option -l chỉ tên gói thư viện tĩnh sử dụng. Chữ "lib" ở đầu được lược bỏ.
ls -l
# total 80
# -rw-r–r– 1 luongvandu staff 43 Apr 10 14:48 file1.c
# -rw-r–r– 1 luongvandu staff 616 Apr 10 20:19 file1.o
# -rw-r–r– 1 luongvandu staff 143 Apr 10 14:48 file2.c
# -rw-r–r– 1 luongvandu staff 756 Apr 10 20:19 file2.o
# -rwxr-xr-x 1 luongvandu staff 4264 Apr 10 20:20 libcommon.so
# -rwxr-xr-x 1 luongvandu staff 8568 Apr 10 20:20 main
# -rw-r–r– 1 luongvandu staff 428 Apr 10 16:57 main.c
# Chạy chương trình và kết quả
./main
# The result sumary of 19 and 82 is 101
#
# The result is over the limit value
# Thư viện được link vào trong chương trình nên file thư viện thay đổi thì CT sẽ gặp lỗi không load được thư viện.
mv libcommon.so libcommon.so.bak
./main
# dyld: Library not loaded: libcommon.so
# Referenced from: /Users/luongvandu/src/c/./main
# Reason: image not found
# Trace/BPT trap: 5

view raw dynamic_lib_compile.sh hosted with ❤ by GitHub

Khi sử dụng thư viện liên kết động, thư mục chứa thư viện thường được định nghĩa trong biến môi trường, và khi biên dịch sẽ trỏ link đến thư viện thông qua biến môi trường.

Hết.

Chia sẻ:

  • Twitter
  • Facebook
Thích Đang tải...

Từ khóa » Thư Viện Gcc