A. 編譯找不到prebuilt_shared_library的庫
編譯找不到prebuilt_shared_library的庫解決方法。必須將自己使用的每個預編譯庫差和敬聲明為棚慶一個獨虛慎立模塊。為此,執行以下步驟。
1、為模塊提供名稱。此名稱不需要與預編譯庫本身的名稱相同。
2、在模塊的android.mk文件中,將指向您提供的預編譯庫的路徑分配到LOCAL_SRC_FILES。指定LOCAL_PATH變數的值的相對路徑。注意:請務必選擇與您的目標ABI對應的預編譯庫版本。要詳細了解如何確保庫支持ABI,請參閱為預編譯庫選擇ABI。
3、根據您使用的是共享庫(.so)還是靜態庫(.a),添加PREBUILT_SHARED_LIBRARY或PREBUILT_STATIC_LIBRARY。
B. 初學c語言時,輸入程序後運行,是執行還是預編譯預編譯是什麼為什麼最開始要有#include如
預編譯是把一個工程中較穩定的代碼預先編譯好放在一個文件里.這些預先編譯好的代碼可以是任何的C/C++代碼。而輸入程序後的運行,只是將代碼編譯成了obj(object)文件,所有obj文件經鏈接(link)成為可執行文件。而你說的執行,應該就是點擊最後生成的.exe文件了。開始要有的#include,是表明要包含的頭文件,或者其它的保存的代碼文件。只有這樣,你才可以引用到那個文件中的代碼,來供目前的文件來使用。
至於你說的什麼大型游戲的編程,應該也是這樣的一套,因為C語言就是上述生成文件的套路。游戲的編程,初學的話可以建議看《游戲編程入門》( 美 哈本),這本書基於windows平台,是為幾乎沒有游戲開發經驗的初學者寫的,循序漸進,從2D講到3D 的一些基本技術,其中的例子也非常經典,看完書基本就可以做出不錯的2D 游戲了,也有了一定的3D基礎了,之後再看一些深入的書籍像《Windows游戲編程大師技巧》。
C. java中什麼是預編譯precompile
預編譯的作用就是把所以的代碼都運行一遍,等你程序運行到模塊A,這個時候需要到B模塊,就可以直接調用,效果是啟動慢,運行快;所以也稱JAVA為靜態語言,動態語言如JavaScript,特性就是當程序運行到C的時候需要調用D模塊,這個時候才會編譯D模塊。希望對你有幫助,謝謝
D. Android 怎麼自定義共享庫
在源碼根目錄下有個 vendor (供應商) 目錄,專門用於存放各個供應商的會有代碼。其中有一個個 sample 目錄,這是 Google 用於示範如何編寫自定義共享庫的示例,它展示了自定義共享庫、JNI 調用、對庫的使用方法及皮膚定製等功能。下面我們通過對該示例進行分析,讓大家熟悉這個輕量級的框架。
1、首先看一下 sample 目錄的結構:
sample
├── Android.mk
├── apps
│ ├── Android.mk
│ ├── client
│ └── upgrade
├── frameworks
│ ├── Android.mk
│ └── PlatformLibrary
├── MODULE_LICENSE_APACHE2
├── procts
│ ├── AndroidProcts.mk
│ └── sample_addon.mk
├── README.txt
├── sdk_addon
│ ├── hardware.ini
│ └── manifest.ini
└── skins
└── WVGAMedDpi
Android.mk: 該文件用於編寫構建規則,默認繼承 Android 的 make 框架。
frameworks: 該目錄在這里的意義等同於 Android 源碼中的 frameworks 。
PlatformLibrary: 該目錄就自定義共享庫。
apps: 該目錄用於編寫依賴該庫的應用程序。經過測試也可以用來編寫不依賴該庫的程序,這有個好處,讓開發商可以把自己特有的應用集成到框架中。
client 與 upgrade: 這是兩個依賴該庫的應用程序示例。
procts: 該目錄中的文件對包含該庫與 Android 框架集成的信息,如模塊名稱等。
AndroidProcts.mk: 指明該模塊的 make 配置文件的在哪裡。
sample_addon.mk :模塊的配置信息。
sdk_addon: 該目錄對該庫的硬體需求進行定義。
hardware.ini: 定義模塊對硬體的需求。
manifest.ini: 模塊的說明文件。名稱、供應商等。
skins: 該目錄用於存放自定義皮膚。
WVGAMedDpi: 已經定義好的一套皮膚。
2.如何封裝 Java 共享庫?
PlatformLibrary 為我們展示了封裝 Java 共享庫的方法。其目錄結構如下: frameworks/PlatformLibrary
├── Android.mk
├── com.example.android.platform_library.xml
├── java
│ └── com
│ └── example
│ └── android
│ └── platform_library
│ └── PlatformLibrary.java
└── README.txt
Android.mk: 該文件說明如何構建該模塊。
com.example.android.platform_library.xml: 該文件是模塊注冊時需要的文件。該文件需要被放置到 /system/etc/permissions 目錄下。
Java /*: Java 源碼所在目錄。具體步驟:
a、編寫 Java 庫,並將源碼放到 java 目錄下。這一步和編寫普通 Java 程序沒有差別。
b、編寫 Android.mk,內容如下:
# 獲得當前目錄,清空環境變數
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) # 源碼所在目錄,all-subdir-java-files 表示所有了目錄中的 Java 文件。
LOCAL_SRC_FILES := \
$(call all-subdir-java-files) # 該模塊是可選的。
LOCAL_MODULE_TAGS := optional # Java 模塊名稱
LOCAL_MODULE:= com.example.android.platform_library # 編譯為 Java 庫。最近以 jar 的形式而不是 apk 的形式存在。
include $(BUILD_JAVA_LIBRARY) # 構建該庫的 API 文檔
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
LOCAL_MODULE:= platform_library
# 文檔對應的庫
LOCAL_DROIDDOC_OPTIONS := com.example.android.platform_library
# 庫的類型
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true # 編譯為 Java API。
include $(BUILD_DROIDDOC)
c、編寫 com.example.android.platform_library.xml,內容如下:
< xml version="1.0" encoding="utf-8" >
<permissions>
<!-- 庫的名稱及對應的 Jar 文件位置 -->
<library name="com.example.android.platform_library"
file="/system/framework/com.example.android.platform_library.jar"/>
</permissions> 現在基本的庫我們已經編寫完成,現在需要對框架中的其它文件進行配置。
d、編寫 sample/frameworks/Android.mk, 內容如下:
# 包含子目錄中的所有 make 文件 include $(call all-subdir-makefiles) 該文件與 sample/Android.mk 文件相同。
e、編寫 sample/sdk_addon/manifest.ini,內容如下: # 該模塊的名稱、供應商及描述
name=Sample Add-On
vendor=Android Open Source Project
description=sample add-on # 構建該模塊的 Android 平台代號
api=3 # 模塊的版本號。必須為整數。
revision=1 # 該模塊中包括的共享庫列表
libraries=com.example.android.platform_library # 對每個庫的詳細定義,格式如下:
# <library.name>=<name>.jar;<desc> # <library.name>: 通過前面 libraies 定義的庫的名稱。
# <name>.jar: 包含庫 API 的 jar 文件。該文件放在 libs/add-on 下面。
com.example.android.platform_library=platform_library.jar;Sample optional plaform library 該文件還可包括該模塊的其它定義,如皮膚等,為了保持該文檔清晰易懂的初衷,這里不做介紹,需要了解可以給我郵件。
f、編寫 sample/procts/sample_addom.mk,內容如下:
# 要植入系統鏡像的應用及可選類庫。可以包括 Java 庫和本地庫。這里我們只有 Java 庫。
PRODUCT_PACKAGES := \ com.example.android.platform_library # 把 xml 文件復制到系統鏡像中相應的位置去。
PRODUCT_COPY_FILES := \ vendor/
sample/frameworks/PlatformLibrary/com.example.android.platform_library.xml:system/etc/permissions/
com.example.android.platform_library.xml # 這個擴展的名稱
PRODUCT_SDK_ADDON_NAME := platform_library # 把模塊的 manifest 和硬體配置文件復制到系統鏡像中相應的位置。 PRODUCT_SDK_ADDON_COPY_FILES := \
vendor/sample/sdk_addon/manifest.ini:manifest.ini \
vendor/sample/sdk_addon/hardware.ini:hardware.in # 把庫的 Jar 包復制到相應的位置。 PRODUCT_SDK_ADDON_COPY_MODULES := \
com.example.android.platform_library:libs/platform_library.jar # 文檔的名稱。必須與。
# LOCAL_MODULE:= platform_library
PRODUCT_SDK_ADDON_DOC_MODULE := platform_library # 這個擴展繼承系統擴展。 $(call inherit-proct, $(SRC_TARGET_DIR)/proct/sdk.mk) # 這個擴展的真實名字。這個名字會用於編譯。
# 用 'make PRODUCT-<PRODUCT_NAME>-sdk_addon' 的形式來編譯此擴展。
PRODUCT_NAME := sample_addon
g、編寫 sample/procts/AndroidProcts.mk,內容如下:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/sample_addon.mk h、最後運行make -j8 PRODUCT-sample_addon-sdk_addon,編譯擴展。
至此,我們就完成了 Java 庫的封裝。
3、接下來我們再來看如何通過 JNI 的方式對 C 代碼進行封裝。
a、在 sample/frameworks/PlatformLibrary 目錄下添加一個文件夾,用於放置 JNI 本地代碼,目錄結構如下:
frameworks/PlatformLibrary/jni
├── Android.mk
└── PlatformLibrary.cpp
b、把 frameworks/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
文件改寫為 JIN 調用介面,代碼如下 : package com.example.android.platform_library; import android.util.Config;
import android.util.Log; public final class PlatformLibrary {
static { / Load the library. If it's already loaded, this does nothing. System.loadLibrary("platform_library_jni");
private int mJniInt = -1; public PlatformLibrary() {} / Test native methods. public int getInt(boolean bad) {
// this alters mJniInt //
int result = getJniInt(bad); // reverse a string, for no very good reason //
String reverse = reverseString("Android!"); Log.i("PlatformLibrary", "getInt: " + result + ", '" + reverse + "'"); return mJniInt; //
/ Simple method, called from native code. private static void yodel(String msg) {
Log.d("PlatformLibrary", "yodel: " + msg); //
/ Trivial native method call. If "bad" is true, this will throw an
/ exception. native private int getJniInt(boolean bad); / Native method that returns a new string that is the reverse of
/ the original. This also calls yodel(). native private static String reverseString(String str);
}
c、在 frameworks/PlatformLibrary/jni/PlatformLibrary.cpp 中編寫 PlatformLibrary.java 中規定本地調用的具體實現。
d、編寫 frameworks/PlatformLibrary/jni/Android.mk,內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional # JNI 模塊的名稱
LOCAL_MODULE:= libplatform_library_jni # 依賴的源代碼文件
LOCAL_SRC_FILES:= \
PlatformLibrary.cpp # 編譯時需要的庫
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libnativehelper \
libcutils \
libutils # 沒有靜態庫
LOCAL_STATIC_LIBRARIES := # 包含必須的 JNI 頭文件
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) # 編譯器選項
LOCAL_CFLAGS += # 對該模塊不進行預編譯。使用預編譯可以提高模塊的性能。
LOCAL_PRELINK_MODULE := false # 把它編譯成動態共享庫
include $(BUILD_SHARED_LIBRARY) 該文件主要定義了本地庫的名字、依賴、編譯選項及編譯方式。
e、修改 frameworks/PlatformLibrary/Android.mk,在末尾添加如下兩行:
include $(CLEAR_VARS) # 調用子目錄中的 make 文件。
include $(call all-makefiles-under,$(LOCAL_PATH))
f、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加該 JNI 本地庫。
PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni
g、編譯即可。至此,添加 JNI 庫完畢。
4、添加接下來我們再看看如何添加原生應用程序
添加原生應用程序就很簡單了,只需要把按照 Android 應用開發的基本方法,寫好一個應用,該應用可以依賴這個擴展,也可以不依賴。如 sample 中的 client 應用,目錄結構如下: apps/client/
├── AndroidManifest.xml
├── Android.mk
└── src
└── com
└── example
└── android
└── platform_library
└── client
└── Client.java
a、在應用根目錄中添加一個 Android.mk 文件,內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := user # 目標名稱
LOCAL_PACKAGE_NAME := PlatformLibraryClient # 只編譯這個apk包中的java文件
LOCAL_SRC_FILES := $(call all-java-files-under, src) # 使用當前版本的 SDK
LOCAL_SDK_VERSION := current # 依賴使用剛才編寫的擴展
LOCAL_JAVA_LIBRARIES := com.example.android.platform_library include $(BUILD_PACKAGE)
b、在 AndroidManifest.xml 中添加一句:
<uses-library android:name="com.example.android.platform_library" />
c、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加該 JNI 本地庫。
PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni \
PlatformLibraryClient
d、編譯即可。至此,添加 JNI 庫完畢。
5、其他功能如添加皮膚等,這里就不一一示範了,請參考<sdk-src>/vendor/sample。
E. 編譯和預編譯有什麼區別。
預編譯又稱為預處理,是做些代碼文本的替換工作。
處理#開頭的指令,比如拷貝#include包含的文件代碼,#define宏定義的替換,條件編譯等
就是為編譯做的預備工作的階段
主要處理#開始的預編譯指令
編譯(compilation , compile) 1、利用編譯程序從源語言編寫的源程序產生目標程序的過程。 2、用編譯程序產生目標程序的動作。 編譯就是把高級語言變成計算機可以識別的2進制語言,計算機只認識1和0,編譯程序把人們熟悉的語言換成2進制的。
F. 第二章:Android.bp語法
注意 :關於Android.bp的權威解釋可以參見 android.bp權威文檔
Google官方語法文檔 https://android.googlesource.com/platform/build/soong
從前面的列子可以看出定義一個模塊從模塊的類型開始,模塊有不同的類型,如前面例子中的cc_library_shared,當然類型還有很多種,譬如 cc_binary、android_app 、cc_library_static 等等。模塊包含一些屬性格式為「property-name:property-value」,其中name屬性必須指定,其屬性值必須是全局唯一的。
其中默認模塊可用於在多個模塊中重復相同的屬性
srcs 屬性以字元串列表的形式指定用於編譯模塊的源文件。您可以使用模塊引用語法 「:」 來引用生成源文件的其他模塊的輸出,如 genrule 或 filegroup。
實例說明:
我們知道Android.mk中可以定義變數,當然作為新編譯系統中替代Android.mk的Android.bp也是一定存在,更加何況Android.mk還可以一定條件的轉換成Android.bp。
變數范圍限定為聲明它們的文件的其餘部分,可以使用 「=」 號賦值, 但是不能使用 「:=」 賦值。變數是不可變的,但有一個例外它們可以附上+= 賦值,但僅在變數被引用之前。
下面我們看一下正確使用變數的列子:
我們知道Android.mk中可以進行注釋,當然Android.bp裡面也可以,Android.mk中使用 # 然後添加註釋,Android.bp使用單行注釋 // 和多行注釋 /* */ 兩種方式。
具體支持以下幾種類型:
String類型、字元串列表類型和Map類型支持操作符 + 。
Android.bp可以支持android_app、cc_binary、cc_binary_host等多種類型,具體定義在Android源碼的 build/soong/androidmk/cmd/androidmk/android.go 可以查看,具體如下:
Android.bp可以支持多種預編譯類型,具體定義在Android源碼的 build/soong/androidmk/cmd/androidmk/android.go 可以查看,如下圖所示:
例如: system/core/libusbhost/Android.bp aosp9.0開始
Android.bp是一門實戰性的東西,光說不練沒有啥用,說再多不如直接開練來得舒服。那就直接開始手撕實例了,讓我們開戰嗎!
下面幾種庫編譯類型:
2.1 動態庫類型
最終編譯為so包
**2.2 java庫類型: **
最終編譯為jar包
2.3 Andorid應用類型
最終編譯為apk包
轉自: https://blog.csdn.net/tkwxty/article/details/104395820