嵌入式-x86-gcc與arm-linux-gcc分別編譯運行第一個C/C++程序(附安裝詳解與C源碼文件傳輸亂碼問題)

嵌入式-x86-gcc與arm-linux-gcc分別編譯運行第一個C/C++程序(附安裝詳解與C源碼文件傳輸亂碼問題)

很多計算機本科生第一次學習嵌入式arm-linux-gcc在linux上編譯第一個程序時會遇到諸多問題,本篇教程爲入門篇!

我們在linux上運行x86架構的一個C/C++程序
首先我們需要安裝C/C++的編譯器gcc和gcc-c++,由於本人懶得再找一個Ubuntu做實驗,就使用本人的阿里雲CentOS7服務器做演示吧。
使用

#CentOS使用yum或dnf安裝gcc和gcc-c++
yum install gcc gcc-c++ -y
#Ubuntu使用apt或apt-get安裝gcc和gcc-c++
apt install gcc gcc-c++ -y

在這裏插入圖片描述
隨便上傳一個可執行的C/C++程序
在這裏插入圖片描述
發現有亂碼,使用file查看發現是因爲程序是在windows上寫的,沒有使用utf-8字符編碼導致的亂碼
在這裏插入圖片描述
那就先解決一下這個小bug吧

#轉換漢字編碼GB2312UTF-8
#順便改一下文件後綴爲.c(因爲linux上C/C++程序普遍以.c爲後綴,但是linux後綴是可有可無的
#,這裏只是辨別一下兩個文件)
iconv -f GB2312 -t UTF-8 conversion.cpp  -o conversion.c

在這裏插入圖片描述
再使用file查看文件屬性,發現已經爲utf-8格式的c文件
在這裏插入圖片描述
接下來編譯成x86可執行程序

#使用gcc編譯剛纔轉換過編碼的文件
gcc -o conversion conversion.c
#編譯沒有錯誤就會生成一個綠色的可執行二進制文件

在這裏插入圖片描述
如過有人閒得蛋疼想看一下這個二進制文件也可以,使用xxd命令就可以查看二進制文件
在這裏插入圖片描述
接下來改使用arm-linux-gcc編譯一下這個相同的C/C++程序了
當然第一步還是下載安裝,由於官網下載太慢,這裏已經下好了arm-linux-gcc4.4.3的包

#使用tar -zxvf 解壓上傳的包到當前目錄 本人已經事先解壓 opt文件夾即是
tar -zxvf arm-linux-gcc-4.4.3.tar.gz

在這裏插入圖片描述

#創建文件夾
sudo mkdir /usr/local/arm -pv
#注意我現在所在的位置是在我服務器的/root/c++/opt/FriendlyARM/toolschain/4.4.3
#你自己的根據自己解壓縮的位置進入4.4.3這個文件夾然後執行下面命令
#拷貝剛纔解壓的文件到/usr/local/arm目的是爲了讓linux找到arm-linux-gcc的執行文件
sudo cp -r `pwd` /usr/local/arm

在這裏插入圖片描述
做完上述步驟後

#執行下面命令配置環境變量
echo 'export PATH=$PATH:/usr/local/arm/4.4.3/bin' >> /etc/profile |sudo tee -a /etc/profile
cat /etc/profile | tail -1
source /etc/profile

在這裏插入圖片描述
查看是否配置好環境變量
如果配置好環境變量則使用table鍵補全看看會不會出現下面這些
在這裏插入圖片描述
使用arm-linux-gcc編譯一下前面的那個C/C++程序

#使用arm-linux-gcc編譯可執行文件
arm-linux-gcc -o conversion conversion.c
#使用file命令查看編譯二進制文件類型爲ARM架構
file conversion
#使用./conversion程序無法運行 原因是我們的cpu是x86架構,無法運行arm架構程序
./conversion

在這裏插入圖片描述
至此演示結束

對彙編有興趣可以查看我的上篇文章
在Linux下運行你的第一個彙編程序

最後拓展介紹一下arm-linux-gcc
https://www.cnblogs.com/zhangpengshou/p/3587751.html這篇博客講的很好,侵刪
我們需要編譯出運行在ARM平臺上的代碼,所使用的交叉編譯器爲 arm-linux-gcc。下面將arm-linux-gcc編譯工具的一些常用命令參數介紹給大家。
在此之前首先介紹下編譯器的工作過程,在使用GCC編譯程序時,編譯過程分爲四個階段:

  1. 預處理(Pre-Processing)

  2. 編譯(Compiling)

  3. 彙編(Assembling)

  4. 鏈接(Linking)
    Linux程序員可以根據自己的需要讓 GCC在編譯的任何階段結束,以便檢查或使用編譯器在該階段的輸出信息,或者對最後生成的二進制文件進行控制,以便通過加入不同數量和種類的調試代碼來爲 今後的調試做好準備。和其它常用的編譯器一樣,GCC也提供了靈活而強大的代碼優化功能,利用它可以生成執行效率更高的代碼。
    以文件example.c爲例說明它的用法

  5. arm-linux-gcc -o example example.c
    不加-c、-S、-E參數,編譯器將執行預處理、編譯、彙編、連接操作直接生成可執行代碼。
    -o參數用於指定輸出的文件,輸出文件名爲example,如果不指定輸出文件,則默認輸出a.out

  6. arm-linux-gcc -c -o example.o example.c
    -c參數將對源程序example.c進行預處理、編譯、彙編操作,生成example.o文件
    去掉指定輸出選項"-o example.o"自動輸出爲example.o,所以說在這裏-o加不加都可以

2.arm-linux-gcc -S -o example.s example.c
-S參數將對源程序example.c進行預處理、編譯,生成example.s文件
-o選項同上

3.arm-linux-gcc -E -o example.i example.c
-E參數將對源程序example.c進行預處理,生成example.i文件(不同版本不一樣,有的將預處理後的內容打印到屏幕上)
就是將#include,#define等進行文件插入及宏擴展等操作。

4.arm-linux-gcc -v -o example example.c
加上-v參數,顯示編譯時的詳細信息,編譯器的版本,編譯過程等。

5.arm-linux-gcc -g -o example example.c
-g選項,加入GDB能夠使用的調試信息,使用GDB調試時比較方便。

6.arm-linux-gcc -Wall -o example example.c
-Wall選項打開了所有需要注意的警告信息,像在聲明之前就使用的函數,聲明後卻沒有使用的變量等。

7.arm-linux-gcc -Ox -o example example.c
-Ox使用優化選項,X的值爲空、0、1、2、3
0爲不優化,優化的目的是減少代碼空間和提高執行效率等,但相應的編譯過程時間將較長並佔用較大的內存空間。

8.arm-linux-gcc -I /home/include -o example example.c
-Idirname: 將dirname所指出的目錄加入到程序頭文件目錄列表中。如果在預設系統及當前目錄中沒有找到需要的文件,就到指定的dirname目錄中去尋找。

9.arm-linux-gcc -L /home/lib -o example example.c

-Ldirname:將dirname所指出的目錄加入到庫文件的目錄列表中。在默認狀態下,連接程序ld在系統的預設路徑中(如/usr/lib)尋找所需要的庫文件,這個選項告訴連接程序,首先到-L指定的目錄中去尋找,然後再到系統預設路徑中尋找。

10.arm-linux-gcc –static -o libexample.a example.c

靜態鏈接庫文件

gcc在命令行上經常使用的幾個選項是:
-c 只預處理、編譯和彙編源程序,不進行連接。編譯器對每一個源程序產生一個目標文件。

-o file 確定輸出文件爲file。如果沒有用-o選項,缺省的可執行文件的輸出是a.out,目標文件和彙編文件的輸出對source.suffix分別是source.o和source.s,預處理的C源程序的輸出是標準輸出stdout。

-Dmacro 或-Dmacro=defn 其作用類似於源程序裏的#define。例如:% gcc -c -DHAVE_GDBM -DHELP_FILE=“help” cdict.c其中第一個- D選項定義宏HAVE_GDBM,在程序裏可以用#ifdef去檢查它是否被設置。第二個-D選項將宏HELP_FILE定義爲字符串“help”(由於 反斜線的作用,引號實際上已成爲該宏定義的一部分),這對於控制程序打開哪個文件是很有用的。

-Umacro 某些宏是被編譯程序自動定義的。這些宏通常可以指定在其中進行編譯的計算機系統類型的符號,用戶可以在編譯某程序時加上 -v選項以查看gcc缺省定義了哪些宏。如果用戶想取消其中某個宏定義,用-Umacro選項,這相當於把#undef macro放在要編譯的源文件的開頭。

-Idir 將dir目錄加到搜尋頭文件的目錄列表中去,並優先於在gcc缺省的搜索目錄。在有多個-I選項的情況下,按命令行上-I選項的前後順序搜索。dir可使用相對路徑,如-I…/inc等。

-O 對程序編譯進行優化,編譯程序試圖減少被編譯程序的長度和執行時間,但其編譯速度比不做優化慢,而且要求較多的內存。

-O2 允許比-O更好的優化,編譯速度較慢,但結果程序的執行速度較快。

-g 產生一張用於調試和排錯的擴展符號表。-g選項使程序可以用GNU的調試程序GDB進行調試。優化和調試通常不兼容,同時使用-g和-O(-O2)選項經常會使程序產生奇怪的運行結果。所以不要同時使用-g和-O(-O2)選項。

-fpic或-fPIC 產生位置無關的目標代碼,可用於構造共享函數庫。

以 上是gcc的編譯選項。gcc的命令行上還可以使用連接選項。事實上,gcc將所有不能識別的選項傳遞給連接程序ld。連接程序ld將幾個目標文件和庫程 序組合成一個可執行文件,它要解決對外部變量、外部過程、庫程序等的引用。但我們永遠不必要顯式地調用ld。利用gcc命令去連接各個文件是很簡單的,即 使在命令行裏沒有列出庫程序,gcc也能保證某些庫程序以正確的次序出現。

gcc的常用連接選項有下列幾個:
-Ldir 將dir目錄加到搜尋-l選項指定的函數庫文件的目錄列表中去,並優先於gcc缺省的搜索目錄。在有多個-L選項的情況下,按命令行上-L選項的前後順序搜索。dir可使用相對路徑。如-L…/lib等。

-lname 在連接時使用函數庫libname.a,連接程序在-Ldir選項指定的目錄下和/lib,/usr/lib目錄下尋找該庫文件。在沒有使用-static選項時,如果發現共享函數庫libname.so,則使用libname.so進行動態連接。

-static 禁止與共享函數庫連接。

-shared 儘量與共享函數庫連接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章