1. Cmake筆記之set_target_properties
第一篇文章,記一個困擾了我很長時間的一個cmake的問題吧。
大家在用cmake時,應該經常會用到第三方so庫,導入第三方so庫中需要使用到set_target_properties,例如這樣寫:
set_target_properties(
Thirdlib
PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/libThirdlib.so
)
CMAKE_CURRENT_SOURCE_DIR 這個變數是系統自定義的,表示CMakeLists.txt文件的絕對路徑
注意CMakeLists.txt文件的路徑,我的這個文件是放在app/src/main 下。
2. CMAKE使用鏈接第三方SO庫
CMake
命名變數
set(INC_DIR /usr/local/include)
set(LINK_DIR /usr/local/lib)
set(SOURCE_FILES main.cpp)
去哪裡找頭文件 相當於gcc/clang 中的-I(i的大寫字母)參數
include_directories(${INC_DIR}) # 用${}引用變數
去哪裡找庫文件 .so .dll .dylib 相當於gcc 中的-L參數
link_directories(${LINK_DIR})
要鏈接的庫文件的名字 相當於gcc中的-l(小寫的l)參數
target_link_libraries(test)
只寫庫名就可以,就是libxxx.so的中間xxx的部分
也可以寫成下面這樣
target_link_libraries(test)
通過上面的這些關鍵詞,我們就可以使用第三方庫了。
cmake_minimum_required(VERSION 2.8.12)
PROJECT (main)
ADD_EXECUTABLE(main main.c)
INCLUDE_DIRECTORIES(/usr/include/hello)
# 靜態鏈接庫
# TARGET_LINK_LIBRARIES(main libhello.a)
# 動態鏈接庫
set(LINK_DIR /usr/local/lib)
link_directories(${LINK_DIR})
target_link_libraries(main libhello.so)
拷貝動態鏈接庫的時候需要注意符號鏈接是否還在
3. android用cmake怎麼導入cpp文件夾,undifined reference to
ndroid Studio升級到2.2之後,我們可以先配置好NDK開發的一些所需工具,如圖,在SDK Tools中勾選安裝CMake、LLDB、NDK。
CMake: 外部構建工具。如果你准備只使用 ndk-build 的話,可以不使用它。
LLDB: Android Studio上面調試本地代碼的工具。
Android Studio自帶DEMO了解CMAKE
Android Studio升級到2.2版本之後,在創建新的project時,界面上多了一個Include C++ Support的選項。勾選它之後將會創建一個默認的C++與java混編的Demo程序。就讓我們先來看看這個官方標准Demo吧。
開始之前最好先下載好NDK,見NDK開發 從入門到放棄(一:基本流程入門了解),即在Project Structure界面Android NDK location處下載或選擇正確的路徑。或者使用上方提供的工具安裝方法來進行下載。否則,創建的新project也會報錯,需要配置好後clean。
File -> New -> New Project,在如下界面中勾選Include C++ Support,然後一路 Next,直到 Finish 為止即可。
項目打開後我們查看目錄結構,與常規項目不同的是多了.externalNativeBuild文件夾、cpp文件夾、CMakeLists.txt文件,如下圖:
這三個東西都是NDK部分:
1. .externalNativeBuild文件夾:cmake編譯好的文件, 顯示支持的各種硬體等信息。系統生成。
2. cpp文件夾:存放C/C++代碼文件,native-lib.cpp文件是該Demo中自帶的,可更改。需要自己編寫。
3. CMakeLists.txt文件:CMake腳本配置的文件。需要自己配置編寫。
Gradle中也有兩處不同:
java代碼:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
}2223
從native-lib.cpp的代碼中我們能看到它使用的是靜態注冊的方式,動態注冊的方式代碼同傳統JNI。
#include <jni.h>
#include <string>
extern "C"
jstring
Java_com_example_person_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}12345678910111234567891011
CMakeLists.txt文件中我們需要注意的是下面這三個地方。兩個library的名字(需一致)以及一個cpp文件的路徑,彼此需要對應一致,當我們自己定義library以及自己創建cpp文件時需要對應修改。
4. android jni cmake和 mk的不同
目錄上的區別:
傳統JNI:
CMake:
這兩種方式在目錄上的區別就是兩點:
1.以前的jni目錄改成cpp,位置不變
2.之前對c文件的編譯配置Android.mk文件放在jni目錄下,現在改成CMakeLists.txt文件
(提示:其實Android.mk文件和CMakeLists.txt可以放在任意目錄下,不過最好放在當前工程目錄下任意位置。後面說build.gradle配置區別就知道了)
5. android cmake為什麼mips
MS nmake,BSD Make(pmake),Makepp,等等。CMake是為了達到一次編寫MAKEFile,則可以在不同的平台上編譯的目的編寫的一款構建工具。我現在也不是太懂,以後學習一下,並寫個CMake自學教程來。這里有個網站http://hahack.com/codes/cmake/,可以參考學習。
6. android stio cmakelists怎麼引用so的
Android開發常常遇到java調用so文件的情況,本文介紹一下Google最近新推出的應用在android studio中的方法–cmakelist.txt格式調用。
so文件分為jni格式的和非jni格式的,java只能調用jni格式的so文件。本文介紹的是針對ndk生成的非jni格式的so文件調用。
首先是對非jni格式的so文件進行處理,聲明一個.h文件,將so文件中的方法包進去,之後將.h文件和so文件放在一個目錄下(之後需要對目錄進行設置),在系統生成的native-lib.cpp中實現對該so文件的調用,即將.h文件包進去就可以調用so文件中的方法。java採用
System.loadlibraty("native-lib")1
的方法,即可對native-lib.cpp方法的調用。
詳細方法詳細
7. 如何在android studio中安裝cmake
下載好Android SDK後,開始安裝,
Android SDK採用了Java語言,所以需要先安裝JDK 5.0及以上版本。直接下載jdk安裝文件安裝,方便。
Android SDK不用安裝,下載後,直接解壓即可,
將下載後的SDK的壓縮包解壓到適當的位置,就這么簡單;
SDK安裝OK。
使用Eclipse進行android應用開發需要給Eclipse裝adt插件,這樣Eclipse就
可以和android sdk建立連接,可以在Eclipse中啟動android模擬器進行程序調試等
下載adt的zip包安裝
安裝完插件後,需要做一些簡單的配置:
1、在Eclipse中,選擇Window > Preference;
2、從左側的菜單中,選擇Android項;
3、設置SDK Location,點Browse選擇SDK的安裝根目錄;
4、OK,完成。
8. android cmake so庫怎麼用
編譯mac靜態庫這個比較簡單,直接Xcode-GXcode,然後用xcodebuild命令即可。編譯Andoird靜態庫編譯android庫我們同樣可以引入一個toolchain文件,這里我是從android-cmake裡面下載的。在使用這個toolchain文件之前,我們先要使用ndk自帶的make-standalone-toolchain.sh腳本來生成對應平台的toolchain.這個腳本位於你的NDK的路徑下面的buil/tools目錄下。比如要生成arm平台的toolchain,我們可以使用下列命令:sh$ANDROID_NDK/build/tools/make-standalone-toolchain.sh--platform=android-$ANDROID_API_LEVEL--install-dir=./android-toolchain--system=darwin-x86_64--ndk-dir=/Users/guanghui/AndroidDev/android-ndk-r9d/--toolchain=arm-linux-androideabi-4.8這里的$ANDROID_NDK為你的NDK的安裝路徑。這段命令可以生成arm的toolchain,最終可以編譯出armeabi和armeabi-v7a靜態庫。如果想生成x86的toolchain,指需要使用下列命令:sh$ANDROID_NDK/build/tools/make-standalone-toolchain.sh--platform=android-$ANDROID_API_LEVEL--install-dir=./android-toolchain-x86--system=darwin-x86_64--ndk-dir=/Users/guanghui/AndroidDev/android-ndk-r9d/--toolchain=x86-4.8最後,我們要告訴CMake使用外部toolchain文件,可以使用參數-DCMAKE_TOOLCHAIN_FILE=xxx。此外,我們還需要在導出兩個環境變數給此toolchain文件:exportPATH=$PATH:./android-toolchain/binexportANDROID_STANDALONE_TOOLCHAIN=./android-toolchaincmake-DCMAKE_TOOLCHAIN_FILE=../android.toolchain.cmake-DANDROID_ABI="armeabi"..
9. Android Studio手動配置Makefile、CMake
在Ubutu上編譯出來的.so文件,怎麼添加到Android項目中去使用呢?目前:可以通過
Makefile方式和CMake方式引入預編譯靜動態庫(靜態庫.a 動態庫.so)到項目中去使用。就目前而言CMake是Goole推薦使用方式,但是加入接手一個老的NDK項目是MakeFile方式,看不懂就GePi了,所以這里我們還是介紹一下MakeFile方式將靜動態庫加入到AS中,完成NDK項目的開發。廢話不多說,直接擼步驟了:
1、在src/main目錄下創建一個ndkBuild文件夾
2、在此文件中創建一個Android.mk文件
3、在此文件中創建一個test.c的源文件
4、將編譯好的的.so庫復制到src/main目錄下
如圖所示目錄結構:
1、編輯Android.mk文件
2、編輯grade(app)文件
3、編輯test.c文件
4、使用編譯好的.so庫裡面的函數
本結果運行在Android 5.1 系統上
再次運行在Android 8.0系統上
看以清楚知道,其實我們的APK包裡面就沒有libMainTest.so庫,所以APP在8.0上會出現奔潰的現象。so...
1、在src/main目錄下創建一個cmake文件夾
include:裡麵包含需要一些頭文件
cmakeTest.c:需要編譯的源文件
2、在app目錄下創建一個文件:CmakeLists.txt
3、編輯grade(app)
4、編輯cmakeTest.c文件
4、引用編譯好的libcmakeTest.so
Android 8.0.0系統:
Android 5.1.1系統:
10. Android基於vsomeIp3與VDC或者VIU通信
部門需要開發一款App用於演示VDC或者VIU的功能,進一步控制汽車部件做出反應
作為一個對硬體,甚至對汽車沒一絲了解的Android開發,第一時間並不想跳出舒適圈,腦子里立馬浮現出一個場景,同一區域網內直接使用Socket通信。說干就干,啪啪啪,編碼完成,一個基於C/S架構的Demo完成,領導看了看,有沒有一種可能,板子上不需要重新寫程序,直接使用板子已有的someIp協議進行通訊。what?
SOME/IP全稱Scalableservice-Oriented Middleware over IP,基於IP的可擴展面向服務的中間件,是一種專用於汽車嵌入式的客戶端/伺服器通信機制,訪問方式分別為事件通知event和RPC遠程調用
Message ID(Server ID) :16bit,服務的ID,標識出一個服務;
Message ID(Method ID) :16bit,方法的ID,表示出一個方法;
Length:報文長度,32bit,標識從request ID到報文結束的總長度;
Request ID(Client ID) :客戶端ID,16bit。區分不同的客戶端;
Request ID(Session ID) :會話ID,區分同一個客戶端的多次調用;
Protocol Version :協議的版本號,固定值為x01;
Interface Version:服務介面版本;
Message Type :報文類型,在AUTOSAR中,總共包含五種,包括REQUEST,REQUEST_NO_RETURN,NOTIFICATION,RESPONSE,ERROR;
Return Code :返回碼,包括四種,REQUEST,REQUEST_NO_RETURN,NOTIFICATION,RESPONSE;
Payload :數據段,用於放置需要傳輸的數據
平時開發App,Android的主要的開發語言是java和kotlin,那如果我們能通過java直接構建Someip消息體是否就能正常通信了?然後悲哀的發現光是按標准組建消息體 就是一個難度不小的挑戰,更別說還要能構建通信通道,正常解析數據。又是一頓google search,發現BMW開源了一個實現someip的庫vSomeIp
查看這個庫的過程中,我發現了一個名字非常數據的文件CMakeLists.txt,Android開發中使用JNI的方式調用函數,通過Cmake構建so庫好像都跟這個文件有關,那是不是意味著Android可以通過JNI 的方式調用vSomeIp庫,從而實現與硬體的通訊
基於上個git項目,其實已經能夠完成單個應用內的someip通訊了,所以對於那個git項目已有的配置就不多做描述了。
但是要想與VDC或者VIU在一個區域網環境內通訊還要另外做配置。
以上是Android作為client端 基於someip協議與硬體通訊的一個大致配置,本人已驗證,可行,撒花~~