目錄
目錄
一、gcc與g++編譯器
二、使用linux自帶的gcc或g++編譯原始檔生成的可執行檔案
三、編譯android手機可用的可執行檔案
四、編譯動態庫
五、編譯靜態庫
了解c/c++編譯器的基本使用,能夠在後續移植第三方庫進行交叉編譯時,清楚了解應該傳遞什麼引數
gcc與g++是我比較常用的編譯器,關於這兩個編譯器有幾點需要注意:
(1)gcc和g++都能夠編譯c/c++,但是編譯時候行為不同
(2)字尾為.c
的原始檔,gcc把它當作是c程式,而g++當作是c++程式;字尾為.cpp
的,兩者都會認為是c++程式
(3)g++會自動鏈結c++標準庫stl,gcc不會
(4)gcc不會定義__cplusplus巨集,而g++會
linux系統都是自帶這兩種編譯器的,我們可以檢驗一下。
在終端輸入 gcc或g++,出現如下字樣,表明已安裝
如果沒有安裝 使用下面指令安裝
apt install build-essential
(1)編寫乙個簡單的.c的檔案
#includeint main()
(2)使用gcc進行編譯
#-o main.o 表示輸出的檔名是main.o,也可以不帶字尾
gcc -o main.o main.c
這時候有的人就會認為這個生成main.o這個可執行檔案應該可以在android手機中執行,畢竟android手機也是linux系統的。其實並不是這樣,因為ubuntu(我的伺服器系統)與android手機的cpu指令集不一樣,必須使用android ndk中的gcc或g++去編譯才可以
wget
unzip android-ndk-r17b-linux-x86_64.zip
export android_64_arm_gcc=/linux/android-ndk-r17b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
#注意:
(1)這裡填寫的應該是絕對路徑,我們進入到bin這個目錄後輸入 pwd這個指令,就可以輸出絕對路徑了
(2)這裡我們用的64位的
有人認為,使用剛剛設定的臨時變數的gcc去編譯應該沒問題了吧,其實不然。為什麼,這個簡單的c原始檔中引入了stdio.h這個標頭檔案,我們需要給編譯器指定乙個標頭檔案及庫檔案的查詢路徑才行。
關於標頭檔案及庫檔案的路徑的指定有下面幾條指令:
(1)--sysroot=aaa
在aaa這個路徑下的usr/include中查詢標頭檔案;在aaa這個路徑下的usr/lib中查詢庫檔案
(2)-isysroot bbb
在bbb這個路徑下的usr/include中查詢標頭檔案,需要注意的是:這樣設定之後,會覆蓋--sysroot=aaa中的標頭檔案的查詢路徑
(3)-isystem ccc
直接在ccc這個路徑的目錄下去查詢標頭檔案,並不是usr/include中了,需要注意
(4)-iddd
同(3)
而優先順序是:先(4),後(3),再(2)
(5)-leee -lfff
-leee:指定庫檔案查詢目錄
-lfff:指定需要鏈結的庫名
export c_h_path="--sysroot=/linux/android-ndk-r17b/platforms/android-21/arch-arm -isysroot /linux/android-ndk-r17b/sysroot -isystem /linux/android-ndk-r17b/sysroot/usr/include/arm-linux-androideabi -pie"
#注意:結尾處一定要加 -pie,否則執行可執行檔案時會報錯
$android_64_arm_gcc $c_h_path -o main.o main.c
此時生成的main.o檔案就可以在在android手機中執行了
如何測試main.o檔案能否在android手機中執行呢
(1)將main.o檔案copy到桌面,我使用的是xshell,所以指令如下
sz main.o
(2)將windows的cmd切換到桌面路徑,之後執行如下指令
#將檔案傳到手機或虛擬中上(前提是有手機連線或虛擬機器開啟)
adb push main.o /sdcard/
#切換至手機或虛擬機器
adb shell
#進入到sdcard目錄
cd /sdcard
#執行,如果沒有問題的話,就會執行c**
./main.o
注意:手機需要root
$android_64_arm_gcc $c_h_path -o libtest.so test.c
注意:(1)android_64_arm_gcc 與 c_h_path 是上面定義好的環境變數
(2)libtest.so是生成的動態庫檔案
(1)將動態庫放在下面的資料夾下,這個路徑不可變(可在build.gradle中改變這個路徑,預設的話就是這個路徑)
(2)在相應的類中呼叫native-lib-test(動態庫的呼叫在native-lib-test檔案中)
(3)native-lib-test.cpp檔案的內容
紅色的地方一定要特別注意:
⒈動態庫是由.c的原始檔生成的,所以extern "c"不能少
⒉extern in test() 表示宣告動態庫的test()檔案
cmake_minimum_required(version 3.4.1)
add_library(
native-lib-test
shared
src/main/cpp/native-lib-test.cpp)
#cmake_source_dir:當前目錄的位址
#android_abi:jnilibs目錄下的cpu架構
set(cmake_cxx_flags "$ -l$/src/main/jnilibs/$")
find_library(
log-lib
log )
target_link_libraries(
native-lib-test
test
$ )
這樣動態庫就能夠在android手機端執行了
和動態編譯有兩個不一樣的地方
(1)指令不同
第一步:$android_64_arm_gcc $cflags -o statictest.o -c statictest.c
第二步:a r libstatictest.a statictest.o
(2)路徑可隨意指定,在cmakelists.txt中進行引用就好了
set(cmake_cxx_flags "$ -l$/src/main/libs/$")
資源位址 C 交叉編譯器
mingw和cygwin都解決了c 跨平台交叉編譯的問題,使linux下的程式在windows上編譯執行成為可能。mingw給習慣在linux上開發的人員在windows上提供了一套類似的工具集 cygwin主要是對於在linux的程式,無需改動 即可移植到windows上 gnuwin32主要是對...
交叉編譯器
交叉編譯器可以使我們在主機上編譯出可以在嵌入式裝置上執行的程式 install gcc aarch64 linux gnu 安裝64位用於作業系統的交叉編譯器,gcc版本是5.4,安裝位置在 usr bin sudo apt get install gcc arm linux gnueabihf 安...
ubuntu安裝交叉編譯器 安裝交叉編譯器
2 安裝方法二 1 安裝方法一 開啟ubuntu終端 使用sudo apt list gcc arm 可以檢視所有的交叉編譯器,假設安裝gcc arm linux gnueabihf,則使用sudo apt get install gcc arm linux gnueabihf就裝好了。參考 2 安...