安卓指令集再編譯
❶ 手機的Android系統能在手機上用C/C++編程嗎
可以,有個手機編程軟體叫做C4droid,專門用來編譯C/C++文件的,要下載支持庫,不大的,你可以看看
❷ 新人求教,編譯一個最簡單的Android程序,提示下面的錯誤咋解決
未說明具體問題,以下未說明具體問題,以下供你參考
1、32位系統下的編譯
如果需要在32位系統中編譯android系統,在編譯前需要對部分makefile進行修改
首先修改build/core/main.mk,修改的內容如下所示:
-ifneq (64,$(findstring 64,$(build_arch)))
+ifneq
(i686,$(findstring i686,$(build_arch)))
$(warning
************************************************************) $(warning You are attempting to build on a 32-bit system.)
$(warning Only 64-bit build environments are supported beyond froyo/2.2.)
其次修改如下四個文件:
external/clearsilver/cgi/Android.mk
external/clearsilver/java-jni/Android.mk
external/clearsilver/util/Android.mk
external/clearsilver/cs/Android.mk # This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32即將LOCAL_CFLAGS和LOCAL_LDFLAGS由-m64改為-m32,從而指定使用32位系統進行編譯如果使用 64bit 的操作系統編譯,這些就都不用修改,但記得需要安裝:For 64-bit servers the following extra packages may be needed:
"sudo apt-get install libc6-dev-i386" (libc6-dev-amd64 if AMD CPU)
"sudo apt-get install g++-multilib lib32ncurses5-dev lib32z1-dev"
還有 jdk64bit 的版本編譯2 、build/core/base_rules.mk:128:*** frameworks/opt/emoji/jni:
.... libgl2jni already defined by framwworks/base/opengl/tests/gl2_jni/jni 停止
從編譯規則上看:
# Make sure that this IS_HOST/CLASS/MODULE combination is unique.
mole_id := MODULE.$(if \
$(LOCAL_IS_HOST_MODULE),HOST,TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)
ifdef $(mole_id)
$(error $(LOCAL_PATH): $(mole_id) already defined by $($(mole_id)))
endif
在framwworks/base/opengl/tests/gl2_jni/下面定義的android.mk定義了:
LOCAL_MODULE := libgl2jni
include $(BUILD_SHARED_LIBRARY)
導致生成的動態庫重復,這是不對的,修改tests這個目錄不參與編譯即可,最直接的辦法刪除掉framwworks/base/opengl/tests/gl2_jni這個文件夾
3、AIDL 編譯報couldn't find import for class原因
「AIDL服務只支持有限的數據類型,因此,如果用AIDL服 務傳遞一些復雜的數據就需要做更一步處理。AIDL服務支持的數據類型如下:
Java的簡單類 型(int、char、boolean等)。不需要導入(import)。String和 CharSequence。不需要導入(import)。
List和 Map。但要注意,List和Map對象的元素類型必須是AIDL服務支持的數據類型。不需要導入(import)。AIDL自動生成 的介面。需要導入(import)。
實現 android.os.Parcelable介面的類。需要導入(import)。
其中後兩種數據類 型需要使用import進行導入,傳遞不需要 import的數據類型的值的方式相同。傳遞一個需要import的數據類型的值(例如,實現android.os.Parcelable 介面的類)的步 驟略顯復雜。除了要建立一個實現android.os.Parcelable介面的類外,還需要為這個類單獨建立一個aidl文件,並使用parcelable關鍵字進行定義。」
沒有加LOCAL_AIDL_INCLUDES += xxx ,所以找不到我的parcelable aidl文件。
修改android源碼根目錄下的build/core/pathmap.mk把你的目錄加進去,此時再make update-api
4、老是提示 @Override錯誤 方法未覆蓋其父類的方法
使 用JDK1.6編譯沒有問題,使用JDK1.5編譯,會報@Override方法未覆蓋其父類的方法。實際上這個方法是類實現的介面中方法,
但是,這個語 法的jdk1.6的下面是可以通過的,也就是說jdk1.6認為類覆蓋父類方法與實現介面方法都叫override,而jdk1.5不
是這樣認為的,不知 道這是當初jdk1.5的bug,還是當初就是認為覆蓋父類方法與實現介面方法是不一樣的,不得而知。但是從
OO角度來看,覆蓋父類方法與實現介面方法都 可以認為override,因為他們目的都是一樣的,都是為了重用,都是多態的一種
表現方式。
更改jdk版本為1.6即可
5、編譯alsa-lib庫錯誤
android系統開發移植alsa-lib庫的過程中編譯的時候出現了如下的錯誤
/tmp/cckyaR40.s: Assembler messages:
/tmp/cckyaR40.s:2763: Error: selected processor does not support `mrs ip,cpsr'
/tmp/cckyaR40.s:2764: Error: unshifted register required -- `orr r2,ip,#128'
/tmp/cckyaR40.s:2765: Error: selected processor does not support `msr cpsr_c,r2
字面的意思報的是匯編錯誤,選擇的處理器不支持mrs和msr指令。
原來的ARM指令有32位和16位兩種指令模式,16位為thumb指令集,thumb指令集編譯出的代碼佔用空間小,
而且效率也高,所以android的arm編譯器默認用的是thumb模式編譯,問題在於alsa的代碼中有部分的內容
用到了32位的指令,所以才會報如下的錯誤,修改的方法也很簡單,在Android.mk中加入如下內容即可:
LOCAL_ARM_MODE := arm
android的編譯系統中LOCAL_ARM_MODE變數的取值為arm或者thumb,代表32位和16位兩種arm指令集,默認為thumb
prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
make: *** [out/target/proct/merlin/obj/SHARED_LIBRARIES/libasound_intermediates/LINKED/libasound.so] 錯誤 1
解決此問題將alsa-lib/include/config.h文件中的如下宏定義去掉即可:
#define VERSIONED_SYMBOLS
開發過程中碰到過很多錯誤,後續再一一總結記錄下來,有些忘記了。。
在android.mk中編譯:
include $(CLEAR_VARS)
$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
出現提示需要定義:LOCAL_MODULE_TAGS := optional 一般修改方法是:
build\core\definitions.mk 中的宏定義變數:
define include-prebuilt
include $$(CLEAR_VARS)
LOCAL_SRC_FILES := $(1)
LOCAL_BUILT_MODULE_STEM := $(1)
LOCAL_MODULE_SUFFIX := $$(suffix $(1))
LOCAL_MODULE := $$(basename $(1))
LOCAL_MODULE_CLASS := $(2)
include $$(BUILD_PREBUILT)
endef
在這里增加一個LOCAL_MODULE_TAGS := optional
但是這需要修改android源碼,如果不是自已的android系統,這么做就麻煩了,所以必須想其它辦法解決:
#include $(CLEAR_VARS)
#$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libyfcdca.a
LOCAL_BUILT_MODULE_STEM := libyfcdca.a
LOCAL_MODULE_SUFFIX := lib
LOCAL_MODULE := yfcdca
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)
如此即可了。供你參考
1、32位系統下的編譯
如果需要在32位系統中編譯android系統,在編譯前需要對部分makefile進行修改
首先修改build/core/main.mk,修改的內容如下所示:
-ifneq (64,$(findstring 64,$(build_arch)))
+ifneq
(i686,$(findstring i686,$(build_arch)))
$(warning
************************************************************) $(warning You are attempting to build on a 32-bit system.)
$(warning Only 64-bit build environments are supported beyond froyo/2.2.)
其次修改如下四個文件:
external/clearsilver/cgi/Android.mk
external/clearsilver/java-jni/Android.mk
external/clearsilver/util/Android.mk
external/clearsilver/cs/Android.mk # This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32即將LOCAL_CFLAGS和LOCAL_LDFLAGS由-m64改為-m32,從而指定使用32位系統進行編譯如果使用 64bit 的操作系統編譯,這些就都不用修改,但記得需要安裝:For 64-bit servers the following extra packages may be needed:
"sudo apt-get install libc6-dev-i386" (libc6-dev-amd64 if AMD CPU)
"sudo apt-get install g++-multilib lib32ncurses5-dev lib32z1-dev"
還有 jdk64bit 的版本編譯2 、build/core/base_rules.mk:128:*** frameworks/opt/emoji/jni:
.... libgl2jni already defined by framwworks/base/opengl/tests/gl2_jni/jni 停止
從編譯規則上看:
# Make sure that this IS_HOST/CLASS/MODULE combination is unique.
mole_id := MODULE.$(if \
$(LOCAL_IS_HOST_MODULE),HOST,TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)
ifdef $(mole_id)
$(error $(LOCAL_PATH): $(mole_id) already defined by $($(mole_id)))
endif
在framwworks/base/opengl/tests/gl2_jni/下面定義的android.mk定義了:
LOCAL_MODULE := libgl2jni
include $(BUILD_SHARED_LIBRARY)
導致生成的動態庫重復,這是不對的,修改tests這個目錄不參與編譯即可,最直接的辦法刪除掉framwworks/base/opengl/tests/gl2_jni這個文件夾
3、AIDL 編譯報couldn't find import for class原因
「AIDL服務只支持有限的數據類型,因此,如果用AIDL服 務傳遞一些復雜的數據就需要做更一步處理。AIDL服務支持的數據類型如下:
Java的簡單類 型(int、char、boolean等)。不需要導入(import)。String和 CharSequence。不需要導入(import)。
List和 Map。但要注意,List和Map對象的元素類型必須是AIDL服務支持的數據類型。不需要導入(import)。AIDL自動生成 的介面。需要導入(import)。
實現 android.os.Parcelable介面的類。需要導入(import)。
其中後兩種數據類 型需要使用import進行導入,傳遞不需要 import的數據類型的值的方式相同。傳遞一個需要import的數據類型的值(例如,實現android.os.Parcelable 介面的類)的步 驟略顯復雜。除了要建立一個實現android.os.Parcelable介面的類外,還需要為這個類單獨建立一個aidl文件,並使用parcelable關鍵字進行定義。」
沒有加LOCAL_AIDL_INCLUDES += xxx ,所以找不到我的parcelable aidl文件。
修改android源碼根目錄下的build/core/pathmap.mk把你的目錄加進去,此時再make update-api
4、老是提示 @Override錯誤 方法未覆蓋其父類的方法
使 用JDK1.6編譯沒有問題,使用JDK1.5編譯,會報@Override方法未覆蓋其父類的方法。實際上這個方法是類實現的介面中方法,
但是,這個語 法的jdk1.6的下面是可以通過的,也就是說jdk1.6認為類覆蓋父類方法與實現介面方法都叫override,而jdk1.5不
是這樣認為的,不知 道這是當初jdk1.5的bug,還是當初就是認為覆蓋父類方法與實現介面方法是不一樣的,不得而知。但是從
OO角度來看,覆蓋父類方法與實現介面方法都 可以認為override,因為他們目的都是一樣的,都是為了重用,都是多態的一種
表現方式。
更改jdk版本為1.6即可
5、編譯alsa-lib庫錯誤
android系統開發移植alsa-lib庫的過程中編譯的時候出現了如下的錯誤
/tmp/cckyaR40.s: Assembler messages:
/tmp/cckyaR40.s:2763: Error: selected processor does not support `mrs ip,cpsr'
/tmp/cckyaR40.s:2764: Error: unshifted register required -- `orr r2,ip,#128'
/tmp/cckyaR40.s:2765: Error: selected processor does not support `msr cpsr_c,r2
字面的意思報的是匯編錯誤,選擇的處理器不支持mrs和msr指令。
原來的ARM指令有32位和16位兩種指令模式,16位為thumb指令集,thumb指令集編譯出的代碼佔用空間小,
而且效率也高,所以android的arm編譯器默認用的是thumb模式編譯,問題在於alsa的代碼中有部分的內容
用到了32位的指令,所以才會報如下的錯誤,修改的方法也很簡單,在Android.mk中加入如下內容即可:
LOCAL_ARM_MODE := arm
android的編譯系統中LOCAL_ARM_MODE變數的取值為arm或者thumb,代表32位和16位兩種arm指令集,默認為thumb
prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
make: *** [out/target/proct/merlin/obj/SHARED_LIBRARIES/libasound_intermediates/LINKED/libasound.so] 錯誤 1
解決此問題將alsa-lib/include/config.h文件中的如下宏定義去掉即可:
#define VERSIONED_SYMBOLS
開發過程中碰到過很多錯誤,後續再一一總結記錄下來,有些忘記了。。
在android.mk中編譯:
include $(CLEAR_VARS)
$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
出現提示需要定義:LOCAL_MODULE_TAGS := optional 一般修改方法是:
build\core\definitions.mk 中的宏定義變數:
define include-prebuilt
include $$(CLEAR_VARS)
LOCAL_SRC_FILES := $(1)
LOCAL_BUILT_MODULE_STEM := $(1)
LOCAL_MODULE_SUFFIX := $$(suffix $(1))
LOCAL_MODULE := $$(basename $(1))
LOCAL_MODULE_CLASS := $(2)
include $$(BUILD_PREBUILT)
endef
在這里增加一個LOCAL_MODULE_TAGS := optional
但是這需要修改android源碼,如果不是自已的android系統,這么做就麻煩了,所以必須想其它辦法解決:
#include $(CLEAR_VARS)
#$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libyfcdca.a
LOCAL_BUILT_MODULE_STEM := libyfcdca.a
LOCAL_MODULE_SUFFIX := lib
LOCAL_MODULE := yfcdca
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)
如此即可了。
❸ 華為鴻蒙兼容安卓APP,windows11也支持安卓APP,有什麼不同
6月2日,華為鴻蒙正式發布,而華為的HarmonyOS是兼容安卓APP的,也正因為如此,所以華為鴻蒙系統一直被很多人吐槽,有些噴子直接說是安卓套殼。
6月24日,windows11發布,這次的windows11也給大家帶來了一個巨大的驚喜,那就是windows11也是原生支持安卓APP的。
但這次的windows11卻沒有被人說是安卓套殼了,那麼問題就來了,這兩個系統支持安卓APP,究竟有何區別?
首先說說鴻蒙系統,我們知道鴻蒙系統的基礎是Openharmony這個開源項目,它本身是不支持安卓APP的,是一個相對純凈的系統。
而華為HarmonyOS是基於Openharmony有,再打包了安卓開源項目AOSP中的一些代碼,讓它能夠支持安卓APP。
由於華為HarmonyOS也是用於ARM晶元上的,安卓系統也是基於ARM晶元的,晶元指令集是一樣的,同時安卓與HarmonyOS都是基於linux內核來的,所以只要打包AOSP中的代碼,讓Harmony有一個安卓APP的編譯器就行了。
但windows不一樣,首先windows的內核是WINNT,其次windows主要用於X86架構,這是復雜指令集,與ARM的簡單指令集是不一樣的。
所以windows不是簡單的打包AOSP的代碼,讓windows中有一個安卓APP編譯器就可以的。
windows11是利用了英特爾的 Intel Bridge技術,這是一種運行時後期編譯器,能讓移動應用在基於X86 的 設備上,以「原生應用」形態運行。
估計這樣一說,大家還是雲里霧里的,不明白。 Bridge技術究竟是一種什麼技術?
我們知道intel的晶元是X86的架構的,安卓的APP主要用於ARM架構的,而intel的 Bridge技術,類似於一種所謂的「橋」,在 英特爾的晶元上也可以運行 ARM的二進制文件,這樣解決了指令集的問題。
然後微軟又在w indows中開發了一個「安卓 Windows 子系統」(WSA),與 Windows 中已經存在的「Linux Windows 子系統」相似,然後當然就打包了AOSP中的代碼,提供了與 AOSP 框架的兼容性,最終實現原生運行安卓APP。
所以這華為鴻蒙與windows11支持安卓APP,還真的不一樣,最大的關鍵就是晶元指令集的不同,導致微軟先要解決晶元指令集的問題後,才能搞定安卓的問題,而鴻蒙不需要考慮指令集的問題。
❹ 關於android和x86的幾點疑問。 android基因linux內核,系統除了內核還有其他什麼
android 除了基於 Linux 內核,他的上層運行環境和相關函數庫,命令程序都是自己的。
其實 android 就是一個基於 Linux 內核的 JAVA 虛擬機環境。
實際 Android 程序都是基於 JAVA 虛擬機跑的解釋型語言程序。
但解釋型語言程序性能肯定不如本地二進製程序。所以 Android 還有一種 NDK 程序。
也就是 Android 裡面有部分本地二進製程序的內容。這樣本地程序方式運行,效率可以最高而且可以根據 CPU 功能做優化(比如 neon )。
指令集不同,但他的 JAVA 虛擬機是解釋型語言,基於 JAVA 語言的程序是可以無差別運行的。只要能保證 Android 上面的 JAVA 虛擬機可以在 x86 上面成功運行就行了。
但 Android 有個另外的問題,就是 JAVA 虛擬機是針對 ARM 做性能優化的,在 X86 上面,這種性能優化都沒了,需要另外在 x86 上面重新優化。但聽說 Android 的 JAVA 虛擬機的語言裡面,也有針對 ARM 硬體進行的修改設計,所以這種針對 ARM 性能優化的 JAVA 程序,在 X86 的系統上面性能也有損失。
所以 Android 出來很久後,在 x86 上面的運行效率都一直不怎麼樣。
而且現在還有 NDK 程序的出現, ARM 的二進製程序在 x86 上面是不能運行的。這些程序都不能運行。
不過 x86 有個優勢就是自己的性能很強,而且模擬器技術現在也很強了。在 x86 上面,可以藉助虛擬機(qemu 的 user mode 就值得看看)來運行 ARM 的二進製程序。
不過虛擬機其實還是有性能損失的。
所以未來,Android 的跨 CPU 架構依然還是問題。純 JAVA 程序好說,用了 NDK 的程序就是問題了。
不過 llvm 這個編譯器又給了另外一條路,既可以虛擬機方式運行,又可以編譯成本地程序而成為二進製程序來優化性能運行。或許 Android 會考慮使用這種方法或者類似的讓 NDK 程序可以跨 CPU 實現。代價是 Android 要自帶一個編譯器,體積也不小的。
MAC OS X 還有一種方法。在 MAC 放棄 IBM 的 Power CPU 而改用 Intel 的 CPU 後,他的程序都是裡面附帶兩套二進製程序,老的 G4 CPU 的機器,就用程序裡面的 power 指令集的程序代碼。新的 Intel CPU 的機器,就自動用裡面的 x86 指令來運行程序。從而實現完美的雙指令集運行。不過代價是這樣的程序都是兩套指令集的內容,體積翻倍。
目前來說,似乎用了 NDK 的程序還都不能用的。不排除現在某些 x86 的手機,使用了虛擬機技術來實現運行 NDK 程序。現在 Linux 下面的 qemu 的 usermode 配合內核的 binfmt_misc 功能,可以讓系統自動識別某個架構的程序,去調用 qemu 來執行。