- Back to Home »
- Cross compiler , Linux Basic »
- Cross Compiler
Tuesday, April 14, 2015
1. Định nghĩa trình biên dịch Compiler
Trình biên dịch, còn gọi là phần mềm biên dịch, compiler, là một chương trình máy tính làm công việc dịch một chuỗi các câu lệnh được viết bằng một ngôn ngữ lập trình (gọi là ngôn ngữ nguồn hay mã nguồn), thành một chương trình tương đương nhưng ở dưới dạng một ngôn ngữ máy tính mới (gọi là ngôn ngữ đích) và thường là ngôn ngữ ở cấp thấp hơn, như ngôn ngữ máy. Chương trình mới được dịch này gọi mã đối tượng. [trích dẫn]2. Quá trình biên dịch
Sơ đồ đơn giản
Ví dụ có chương trình sau được lưu dưới tên mytest.c
#include <stdio.h>
#include <math.h>
#define PI 3.14
int main(int argc, char **argv)
{
float x, y;
x = PI / 3;
y = cos(x);
printf("gia tri cos(%f) = %f \n", x, y);
return 1;
}
Trong chương trình có sử dụng thư viện toán học math cho hàm cos(x), vậy trong quá trình Linker sẽ tiến hành lấy mã của hàm printf() trong thư viện để kết hợp với mã thông thường khác.
Sơ đồ chi tiết từ Code/Build/Run
3. Cross Compiler /Toolchain là gì
Cross Compiler hay còn gọi là Toolchain được định nghĩa:
A cross compiler is a compiler capable of creating executable code for a platform other than the one on which the compiler is running. For example, a compiler that runs on a Windows 7 PC but generates code that runs on Android smartphone is a cross compiler
Có nghĩa là source code được viết trên máy tính chạy chíp Intel (x86 platform), thông qua một cross compiler sẽ cho ra file nhị phân (mã máy) có khả năng chạy được trên một nên tảng chip khác là ARM (ARM platform). Trên hình native compiler là trình biên dịch để tạo ra file nhị phân chạy trên chính máy tính đang dùng để viết source code.
4. Hệ thống Cross Compiler
Quá trình tạo ra và sử dụng tool chain liên quan đến 3 đối tượng:
+ Build : là hệ thống/platform tạo ra tool chain, thường là các máy tính chạy nền tảng chip Intel x86, x84_64 chạy hệ điều hành Linux hoặc Windows.
+ Host: là hệ thống chạy chương trình tool chain để compile source của một chương trình ứng dụng nào đó, host cũng giống như Build, thường là các máy tính Intel chạy Linux hoặc Windows OS
+ Target: là hệ thống chạy các chương trình (dưới dạng file nhị phân - mã máy) do hệ thống Host tạo ra, target thường là các hệ thống nhúng chạy chip ARM, MIPS, PowerPC, ...; tuy nhiên target cũng có thể là một máy tính bình thường chạy chip Intel.
VD:
BUILD=x86
HOST=x86
TARGTE=arm-linux
5. Các thành phần của compiler
+ Binutils
Là một tập các công cụ để tạo và quản lý file nhị phân (bin) của target CPU
as : là assembler, nó sinh ra mã nhị phân (binary code) từ assembler source code
ld : trình liên kết (linker)
ar, ranlib : sinh ra file nén .a, sử dụng như là thư viện
objdump, readelf, size, nm, strings: phân tích file nhị phân
strip : để loại bỏ những phần thừa trong file nhị phân để giảm kích thước của chúng
Thông thường để cross-compiler một chương trình ta phải cài đặt biến môi trường mới có thể compile đúng được
export PATH=/path/to/compiler/bin:$PATH #đường dẫn đến thư mục chứa as, ld, ...
export CROSS_COMPILE=arm-none-linux-gnueabi-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export CPP=${CROSS_COMPILE}cpp
export AR=${CROSS_COMPILE}ar
export AS=${CROSS_COMPILE}as
export LD=${CROSS_COMPILE}ld
export RANLIB=${CROSS_COMPILE}ranlib
export STRIP=${CROSS_COMPILE}strip
+ C/C++ Library
Library được dùng làm interface giữa applications và kernel, cung cấp các C API chuẩn để dễ dàng phát triển ứng dụng. Một số libb có thể kể đến như: glibc, uClibc, eglibc, dietlibc, newlib, ...
+ Kernel header
Kernel header cần thiết cho Applications và C Library để cung cấp các API giao tiếp với Kernel.
+ GCC compiler
gcc, c++, g++ : compiler
Trình biên dịch trong hệ thống Linux, compile cho rất nhiều ngôn ngữ và nhiều kiến trúc CPU khác nhau như ARM, MIPS, PowerPC, SuperH, x86; tuy nhiên trong blog này chỉ đề cập đến ngôn ngữ C/C++ và kiến trúc CPU là ARM và x86.
+ GDB Debugger
Trình gỡ rối, trợ giúp cho quá trình phát hiện lỗi khi develop application.
6. Cài đặt GCC
Trong blog này đề cập đến GCC Compiler (gcc trên host-x86 và cross gcc cho target-ARM), các compiler được các hãng sản xuất chip làm ra và phân phối đến các khách hàng thông qua website của hãng.
Một số dòng chip phổ biến dựa trên kiến trúc ARM hay MIPS thường dễ dàng có được cross-compiler trên một số nhà cung cấp miễn phí như Sourcery hay Linaro.
GCC chia compiler ra làm 2 phần, gcc là compiler cho C source và g++ cho C++ source, tuy nhiên cũng có thể g++ để compile C source bình thường.
Trên Fedora bạn có thể cài đặt compiler thông qua lệnh sau:
yum install gcc g++Tham khảo thêm mục Linux Development tại đây.
Xét ví dụ:
main.c / main.cpp
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv){
double x;
x = sqrt(4);
printf("x = %f \n", x);
return 1;
}
Terminal command:
$export CFLAGS="-I./include -DDEBUG -Wall -g"
$export LDFLAGS+=" -L./lib -lm"
$gcc -c main.c ${CFLAGS} #tạo file object từ source
$gcc -o prog main.o ${LDFLAGS} #tạo file chương trình nhị phân từ file object
hoặc
$export CXXFLAGS="-I./include -DDEBUG -Wall -g"
$export LDFLAGS+=" -L./lib -lm"
$g++ -c main.cpp ${CXXFLAGS} #tạo file object từ source
$g++ -o prog main.o ${LDFLAGS} #tạo file chương trình nhị phân từ file object
Phía trên là format chung / cơ bản nhất của GCC compiler
+ CFLAGS / CXXFLAGS
C Compiler Flags và C++ preprocessor flags để pass các options vào trong compiler để thực hiện quá trình compile source
code -> object, gồm các thông tin:
- Đường dẫn các file header, bắt đầu với "-I", ví dụ: -I./include
- Các define được bắt đầu với "-D"; ví dụ: -DDEBUG, define DEBUG
- Các options đặc biết khác của compiler; ví dụ: -g (enable chức năng debug gdb của gcc compiler, -Wall (trace các warning trong quá trình compile)
+ LDFLAGS
Linker flags, dùng trong quá trình linking các thư viện, LDFLAGS chứa các thông tin:
- Đường dẫn đến thư viện, được bắt đầu bằng "-L"; ví dụ: -L./lib
- Các thư viện, bắt đầu với "-l", là viết tắt của lib; ví dụ: -lm tương ứng với libm, thư viện toán học, có sẵn trong hệ thống
+ gcc
Compiler cho C source
+ g++
Compiler cho C++ source