GCC和交叉編譯中的工具的使用方法
交叉編譯工具簡介
交叉工具鏈名稱 |
i386的工具名稱 |
歸屬 |
作用 |
arm-linux-as |
as |
binutils |
編譯ARM彙編程序 |
arm-linux-ar |
ar |
binutils |
把多個.o合併一個.o或是靜態庫(.a) |
arm-linux-ranlib |
ranlib |
binutils |
爲庫文件建立索引,想當於*.as -s |
arm-linux-ld |
ld |
binutils |
聯接器(Linker),把多個.o或是庫文件鏈接一個可以執行文件 |
arm-linux-objdump |
objdump |
binutils |
查看目標文件的(.o)或是庫(.a)的信息 |
arm-linux-objcopy |
objcopy |
binutils |
轉換成可以執行的ELF的文件 |
arm-linux-strip |
strip |
binutils |
去掉elf可以執行的信息,是可以執行文件變小 |
arm-linux-readelf |
readelf |
binutils |
讀elf的文件頭 |
arm-linux-gcc |
gcc |
gcc |
編譯.c和.S的程序和彙編文件 |
arm-linux-g++ |
g++ |
gcc |
編譯個g++程序 |
c編譯語言的例子
分別通過gcc和交叉編譯的工具進行編譯下面的例子,分別用靜態編譯、編譯成動態庫和反彙編的方法。
hello_first.c
程序源碼:
#include <stdio.h>
void hello_first(void)
{
printf("first function /n");
}
hello_second.c
程序源碼:
#include <stdio.h>
void hello_second(void)
{
printf("second function /n");
}
hello.c
程序源碼:
#include <stdio.h>
void hello_first(void);
void hello_second(void);
int main(int argc,char *argv[])
{
hello_first();
hello_second();
}
編譯方法
編譯動態文件
直接編譯
方法一
#gcc -c hello_first.c
#gcc -c hello_second.c
#gcc -o hello hello.c hello_first.o hello_second.o
方法二
#gcc -c hello_first.c hello_second.c
#gcc -o hello hello.c hello_first.o hello_second.o
方法三
#gcc -c -o first.o hello_first.c
#gcc -c -o second.o hello_second.c
#gcc -o hello hello.c first.o second.o
方法四
#gcc -o hello hello.c hello_first.c hello_second.c
編譯動態庫進行編譯
#gcc -c -fpic hello_first.c hello_second.c
#gcc -shared hello_first.o hello_second.o -o hello.so
#gcc -o hello hello.c hello.so
/*可以把編譯的hello.so拷貝到/lib下或是設定環境變量LD_LIBRARY_PATH指向我們編譯的動態庫的
文件位置,如,我們把hello.so拷貝到 /tmp下設定LD_LIBRARY_PATH=/tmp,然後重新執行
#./hello*/
編譯成靜態庫進行編譯
#gcc -c hello_first.c hello_second.c
/*建立一個靜態的鏈接庫*/
#ar -r libhello.a hello_first.o hello_second.o
/*爲靜態鏈接庫建立索引*/
#ar -s libhello.a
#ranlib libhello.a
/*由靜態庫編譯成可以執行的文件*/
#gcc -o hello hello.c -lhello -L./
或是
#gcc -o hello hello.c libhello.a
/*編譯出來的hello可以脫離libhello.a執行*/
編譯成靜態文件
#gcc -static -o hello hello.c hello_first.c hello_second.c
比較用不同的方便的大小的差異
編譯的大小比較
直接編譯
編譯成動態庫
編譯成靜態庫
編譯成靜態文件
gcc的使用機巧
在對mp3,video,bmp的文件進行讀取的時候,會對文件的頭信息或是具體的結構進行讀取,
是可以通過進行結構 體進行讀取信息,但是在正常編譯的時候(gcc),會出現內存的漏洞,
因爲在正常定義的時候,編譯器會根據具體的系統結構是按整字節處理,這樣我們提出的數值
就會出現問題,可以這樣解決。
例子:
#include <stdio.h>
int main(int argc,char **argv[])
{
struct test
{
int a;
char b[2];
int c;
};
printf("sizeof(struct test)=%d /n",sizeof(struct test));
}
輸出的結果並不是我們所需要的10byte,而是12byte,爲什麼呢?因爲在linux的
4個字節對齊的。在第二個字節裏面得就僅僅用了兩個字節,可是在我們讀取的文件信
息的時候就會出錯,可以這樣解決:
#include <stdio.h>
int main(int argc,char *argv[])
{
struct test
{
int a;
char b[2];
int c;
} __attribute__((packed));
printf("sizeof(struct test)=%d /n",sizeof(struct test))j;
}