在Android系统中修改Android.mk使其同时编译rgb2565和rgb2888(向out/host/linux-x86/bin/下新增加一个工具命令)

本文详细介绍了在Android系统中通过修改Android.mk文件来同时编译rgb2565和rgb2888模块的方法,包括理解Android.mk文件中的模块标签、不同编译模式的区别、如何添加rgb2888模块到编译过程以及在不同编译模式下预装模块的策略。

                    修改对应的Android.mk文件使其在源码编译时能够同时编译出rgb2565和rgb2888,rgb2888的源码文件已有,其实实现很简单,这里只是将我在具体测试中不同模块标签的模块在不同编译模式下的所采取的编译方式列举一下,因为我们的改动最好能和源码进行无缝的结合。

      

         

一、           Android系统的四种编译模式

         Android系统有四种编译模式,分别是user、userdebug、eng、test。这个值由编译环境变量TARGET_BUILD_VARIANT保存,在源码编译之前需要我们手动指定。指定方式是,执行$ . build/envsetup.sh命令之后,执行lunch命令,系统会根据我们这一步的选择自动修改TARGET_BUILD_VARIANT的值。如果这个值未指定,系统则将其默认为eng。

         不同的模式决定了不同的模块被安装到目标系统(system.img)中,并适用于不同的发布版本。这样可以使发布版本的系统更轻量,更简洁。下面看一下不同的编译模式之间的主要区别。

eng

This is the default flavor. A plain "make " is the same as "make eng ". droid is an alias foreng .

·         Installs modules tagged with: eng , debug , user , and/or development .

·         Installs non-APK modules that have no tags specified.

·         Installs APKs according to the product definition files, in addition to tagged APKs.

·         ro.secure=0

·         ro.debuggable=1

·         ro.kernel.android.checkjni=1

·         adb is enabled by default.

user

"make user "

This is the flavor intended to be the final release bits.

·         Installs modules tagged with user .

在Android系统中修改Android.mk使其同时编译rgb2565和rgb2888(向out/host/linux-x86/bin/下新增加一个工具命令)

分类: Andriod 175人阅读 评论(1) 收藏 举报

                               在Android系统中修改Android.mk使其同时编译rgb2565和rgb2888(向out/host/linux-x86/bin/下新增加一个工具命令)


                    修改对应的Android.mk文件使其在源码编译时能够同时编译出rgb2565和rgb2888,rgb2888的源码文件已有,其实实现很简单,这里只是将我在具体测试中不同模块标签的模块在不同编译模式下的所采取的编译方式列举一下,因为我们的改动最好能和源码进行无缝的结合。

      

         

一、           Android系统的四种编译模式

         Android系统有四种编译模式,分别是user、userdebug、eng、test。这个值由编译环境变量TARGET_BUILD_VARIANT保存,在源码编译之前需要我们手动指定。指定方式是,执行$ . build/envsetup.sh命令之后,执行lunch命令,系统会根据我们这一步的选择自动修改TARGET_BUILD_VARIANT的值。如果这个值未指定,系统则将其默认为eng。

         不同的模式决定了不同的模块被安装到目标系统(system.img)中,并适用于不同的发布版本。这样可以使发布版本的系统更轻量,更简洁。下面看一下不同的编译模式之间的主要区别。

eng

This is the default flavor. A plain "make " is the same as "make eng ". droid is an alias foreng .

·         Installs modules tagged with: eng , debug , user , and/or development .

·         Installs non-APK modules that have no tags specified.

·         Installs APKs according to the product definition files, in addition to tagged APKs.

·         ro.secure=0

·         ro.debuggable=1

·         ro.kernel.android.checkjni=1

·         adb is enabled by default.

user

"make user "

This is the flavor intended to be the final release bits.

·         Installs modules tagged with user .

·         Installs non-APK modules that have no tags specified.

·         Installs APKs according to the product definition files; tags are ignored for APK modules.

·         ro.secure=1

·         ro.debuggable=0

·         adb is disabled by default.

userdebug

"make userdebug "

The same as user , except:

·         Also installs modules tagged with debug .

·         ro.debuggable=1

·         adb is enabled by default.

tests

Installs modules tagged with user,debug,eng,tests


         上面的表格区分了不同编译模式中,编译系统所做的不同的事情。从上面的表格我们可以得知:

         并不是在对应的编译模式下,对应的编译模块才预装到目标系统中。例如上图中的eng。在eng编译模式下,会预装标签为engdebuguser的模块。在tests编译模式下,会预装模块标签为userdebugengtests的模块。这对于我们修改Android.mk并成功编译rgb2888来说是非常重要的信息。

         其中在user编译模式下,只会预装标签为user的模块。在userdebug模式下,预装的模块除了标签为user的还有标签为debug的模块。

          如果在执行编译时未指定编译模式,则系统将编译模式自动默认为eng模式。

         其他的区别对于编译rgb2888并没有影响。

    

二、           Android.mk文件中的模块标签


         Android.mk文件是Android源码中的编译配置文件,指定了对应的模块以怎样的方式进行编译。Android源码中的编译都是以模块进行的,一个Android.mk文件可以同时编译一个或多个模块。

          Android.mk中以include $(CLEAR_VARS)为开始,以include $(文件格式)为结束算作一个模块。我们可以在其之间指定这个模块的标签,模块的名称,需要的源文件,需要使用的库等等。

          每个模块标签的取值范围是user、eng、tests、optional、samples。系统会根据上面提到的TARGET_BUILD_VARIANT值将对应的模块编译到目标系统中。可以对模 块标签进行如下直观的理解:

                                   user:指该模块在user模式下才编译。

                                   eng:指该模块在eng模式下才编译。

                                   tests:指该模块在tests模式下才编译

                                   optional:指该模块在任何编译模式下都将编译。

                                   samples:还不确定。

         上面官方给出的模块标签的理解,好想是不对的。因为在不同的编译模式下可能会预装不同的模块,比如,eng模式下,会预装标签为user、debug、eng的模块,所以在eng模式下也要编译标签为user,debug的模块。总之,我们可以理解为,编译模式和模块标签共同决定了在实际的编译中对应模块的编译方式,两者相互依赖。

         当模块标签未指定时,默认值是user。

三、           修改Android.mk使其同时编译rgb2565和rgb2888


         首先仿照Android.mk文件中rgb2565模块,编写rgb2888对应的编译配置。如下图所示:

                

         编写完Android.mk并选择eng模式编译。会出现如下的错误提示:


               

         上面提示user标签只支持传统的模块。如果在任何模式下编译该模块,需要指定模块的标签为optional。我们向Android.mk中rgb2888模块中添加对应的模块标签为       optional,然后重新编译,通过。

         将模块标签修改为optional后编译成功。当在对应的目录(out/host/linux-x86/bin/)中查找时,发现rgb2565命令已经生成,而rgb2888并未输出到该目录中。但是我们的编译已经通过,说明rgb2888的模块已经正确编译了。通过查看目录out/host/linux-x86/obj/EXECUTABLES/rgb2888_intermediates/,发现编译的中间生成物的确已经生成,说明我们的编译没有错误。从这一点可以说明,标签为optional的模块虽然在任何模式下都会编译,但是不会预装到目标系统中。

         当使用默认标签user时,提示user标签只支持传统的模块。通过测试发现,在eng模式下如果预装标签为user的模块时,必须显示指定user标签支持的模块。指定方式是修改源码中的build/core/user_tags.mk文件,在GRANDFATHERED_USER_MODULES +=中添加上模块的名称,即我们的rgb2888。然后编译,测试通过,对应的       rgb2888和rgb2565成功输出到了out/host/linux-x86/bin目录下。

          使用标签eng重新编译后,发现也会成功通过,rgb2888也成功输出到了对应的bin目录下(编译模式为eng)。

         通过比较发现,当使用编译模式为eng时,预装标签为user的模块时,要显示的指定,模块使用eng标签时,不需要显示的指定就可以预装该模块。对于eng模式下预装optional标签的模块,能否通过修改对应的支持才可以正确的预装,尚不明确。

         另外,将编译的模块预装到目标系统(system.img)貌似不能等价理解为对应的rgb2888在out/host/linux-x86/bin下正确输出了。这两者好像没有必然的联系。但是这并不影响我们解决问题。

   

四、           总结

            综上所述,修改Android.mk文件使其同时编译出rgb2565和rgb2888,可以使用以下三种方式(eng编译模式):


            在对应的rgb2565/Android.mk文件中添加rgb2888的模块(使用默认模块标签),并修改build/core/user_tags.mk添加对rgb2888的支持。

           可以在rgb2565目录所在的位置下,新建rgb2888目录,拷贝对应的源码文件,编写rgb2888模块的编译文件Android.mk(使用默认模块标签),并修改build/core/user_tags.mk添加对rgb2888的支持。这种方式是源码更清晰简介。但也要修改user_tags.mk,这是关键。

           直接在rgb2888模块中显示使用eng标签。

·         Installs non-APK modules that have no tags specified.

·         Installs APKs according to the product definition files; tags are ignored for APK modules.

·         ro.secure=1

·         ro.debuggable=0

·         adb is disabled by default.

userdebug

"make userdebug "

The same as user , except:

·         Also installs modules tagged with debug .

·         ro.debuggable=1

·         adb is enabled by default.

tests

Installs modules tagged with user,debug,eng,tests


         上面的表格区分了不同编译模式中,编译系统所做的不同的事情。从上面的表格我们可以得知:

         并不是在对应的编译模式下,对应的编译模块才预装到目标系统中。例如上图中的eng。在eng编译模式下,会预装标签为engdebuguser的模块。在tests编译模式下,会预装模块标签为userdebugengtests的模块。这对于我们修改Android.mk并成功编译rgb2888来说是非常重要的信息。

         其中在user编译模式下,只会预装标签为user的模块。在userdebug模式下,预装的模块除了标签为user的还有标签为debug的模块。

          如果在执行编译时未指定编译模式,则系统将编译模式自动默认为eng模式。

         其他的区别对于编译rgb2888并没有影响。

    

二、           Android.mk文件中的模块标签


         Android.mk文件是Android源码中的编译配置文件,指定了对应的模块以怎样的方式进行编译。Android源码中的编译都是以模块进行的,一个Android.mk文件可以同时编译一个或多个模块。

          Android.mk中以include $(CLEAR_VARS)为开始,以include $(文件格式)为结束算作一个模块。我们可以在其之间指定这个模块的标签,模块的名称,需要的源文件,需要使用的库等等。

          每个模块标签的取值范围是user、eng、tests、optional、samples。系统会根据上面提到的TARGET_BUILD_VARIANT值将对应的模块编译到目标系统中。可以对模 块标签进行如下直观的理解:

                                   user:指该模块在user模式下才编译。

                                   eng:指该模块在eng模式下才编译。

                                   tests:指该模块在tests模式下才编译

                                   optional:指该模块在任何编译模式下都将编译。

                                   samples:还不确定。

         上面官方给出的模块标签的理解,好想是不对的。因为在不同的编译模式下可能会预装不同的模块,比如,eng模式下,会预装标签为user、debug、eng的模块,所以在eng模式下也要编译标签为user,debug的模块。总之,我们可以理解为,编译模式和模块标签共同决定了在实际的编译中对应模块的编译方式,两者相互依赖。

         当模块标签未指定时,默认值是user。

三、           修改Android.mk使其同时编译rgb2565和rgb2888


         首先仿照Android.mk文件中rgb2565模块,编写rgb2888对应的编译配置。如下图所示:

                

         编写完Android.mk并选择eng模式编译。会出现如下的错误提示:


               

         上面提示user标签只支持传统的模块。如果在任何模式下编译该模块,需要指定模块的标签为optional。我们向Android.mk中rgb2888模块中添加对应的模块标签为       optional,然后重新编译,通过。

         将模块标签修改为optional后编译成功。当在对应的目录(out/host/linux-x86/bin/)中查找时,发现rgb2565命令已经生成,而rgb2888并未输出到该目录中。但是我们的编译已经通过,说明rgb2888的模块已经正确编译了。通过查看目录out/host/linux-x86/obj/EXECUTABLES/rgb2888_intermediates/,发现编译的中间生成物的确已经生成,说明我们的编译没有错误。从这一点可以说明,标签为optional的模块虽然在任何模式下都会编译,但是不会预装到目标系统中。

         当使用默认标签user时,提示user标签只支持传统的模块。通过测试发现,在eng模式下如果预装标签为user的模块时,必须显示指定user标签支持的模块。指定方式是修改源码中的build/core/user_tags.mk文件,在GRANDFATHERED_USER_MODULES +=中添加上模块的名称,即我们的rgb2888。然后编译,测试通过,对应的       rgb2888和rgb2565成功输出到了out/host/linux-x86/bin目录下。

          使用标签eng重新编译后,发现也会成功通过,rgb2888也成功输出到了对应的bin目录下(编译模式为eng)。

         通过比较发现,当使用编译模式为eng时,预装标签为user的模块时,要显示的指定,模块使用eng标签时,不需要显示的指定就可以预装该模块。对于eng模式下预装optional标签的模块,能否通过修改对应的支持才可以正确的预装,尚不明确。

         另外,将编译的模块预装到目标系统(system.img)貌似不能等价理解为对应的rgb2888在out/host/linux-x86/bin下正确输出了。这两者好像没有必然的联系。但是这并不影响我们解决问题。

   

四、           总结

            综上所述,修改Android.mk文件使其同时编译出rgb2565和rgb2888,可以使用以下三种方式(eng编译模式):


            在对应的rgb2565/Android.mk文件中添加rgb2888的模块(使用默认模块标签),并修改build/core/user_tags.mk添加对rgb2888的支持。

           可以在rgb2565目录所在的位置下,新建rgb2888目录,拷贝对应的源码文件,编写rgb2888模块的编译文件Android.mk(使用默认模块标签),并修改build/core/user_tags.mk添加对rgb2888的支持。这种方式是源码更清晰简介。但也要修改user_tags.mk,这是关键。

           直接在rgb2888模块中显示使用eng标签。


<think>我们正在讨论Android编译错误。用户之前询问了“android-security-9.0.0”Android-9.0.0”的区别,但现在提出了一个的问题:编译时出现失败错误,具体为“FAILED:out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/Main.o”。用户提供了三个引用,但指出这些引用仅供参考,需要结合上一次的问题回答。根据用户提供的引用,我们可以推测:-引用[1]提到在编译emugen时遇到错误,解决办法是修改某个文件(development/tools/emulator/opengl/host/tools/emugen/main.cpp)。但是用户现在的错误是关于aapt的。-引用[2]提到了在编译安卓源码后找到带调试符号的aapt2,并给出了路径。-引用[3]则直接与aapt相关,指出在64位系统编译32位的aapt时可能需要修改Android.mk文件,添加-lpthread库,并且安装lib32z1-dev。用户当前的错误是:“FAILED:out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/Main.o”结合引用[3]的内容,这个错误很可能是因为在64位Linux系统编译32位的aapt时缺少必要的32位库或链接库不正确导致的。引用[3]给出的步骤是:1.安装lib32z1-dev:`sudoapt-getinstalllib32z1-dev`2.修改./framework/base/tools/aapt/Android.mk文件,在LOCAL_LDLIBS行添加-lpthread(修改前后对比见引用[3])。因此,我们推断解决方案应该按照引用[3]的建议。但是,我们还需要考虑以下几点:1.这个错误可能发生在64位Linux系统编译32位目标时。2.错误可能是由于缺少32位的zlib库(由lib32z1-dev提供)或缺少链接pthread库导致。因此,解决方案步骤:1.确保安装了32位的zlib开发包:`sudoapt-getinstalllib32z1-dev`2.修改aapt的Android.mk文件,在适当的位置添加-lpthread。注意:引用[3]中修改的代码行是:```LOCAL_LDLIBS:=-lzifeq($(HOST_OS),linux)LOCAL_LDLIBS+=-lrt```修改为:```LOCAL_LDLIBS:=-lzifeq($(HOST_OS),linux)LOCAL_LDLIBS+=-lrt-lpthread```但注意,在Android.mk中,可能已经存在对线程库的链接,或者需要根据情况添加。所以我们应该按照引用[3]的修改,在链接选项中加入-lpthread。另外,用户可能使用的是较Android版本,而aapt的路径可能已经发生了变化。但根据错误信息中的路径“out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/Main.o”,说明编译的确实是aapt。而aapt的源代码路径在引用[3]中给出的是“./framework/base/tools/aapt/”,这个路径在较老的Android版本(如Android9.0)中可能存在,但在更的版本中可能不同。不过,用户之前提到的是Android9.0,所以很可能这个路径是正确的。所以,我们给出如下解决方案:###解决方案步骤####步骤1:安装32位兼容库在Ubuntu/Debian系统上运行:```bashsudoapt-getupdatesudoapt-getinstalllib32z1-dev```####步骤2:修改aapt的Android.mk文件1.打开文件:`./framework/base/tools/aapt/Android.mk`2.找到以下代码段(通常在文件的后半部分):```makefileLOCAL_LDLIBS:=-lzifeq($(HOST_OS),linux)LOCAL_LDLIBS+=-lrtendif```3.修改为:```makefileLOCAL_LDLIBS:=-lzifeq($(HOST_OS),linux)LOCAL_LDLIBS+=-lrt-lpthreadendif```####步骤3:重编译清理之前编译失败的结果,然后重编译:```bashmakecleanmake-j8```或者使用你之前使用的编译命令(例如`mka`等)。###注意事项-如果修改后仍然出现同样的错误,请检查是否还有其他依赖库缺失,比如32位的其他开发库。-如果是其他环境(如MacOS)则此方法可能不适用,但用户错误出现在Linux上。-在较Android版本中,aapt可能已经被aapt2取代,但错误信息明确提到aapt,所以还是需要修复aapt的编译问题。###相关问题1.如何在64位系统编译32位的Android工具?2.还有哪些常见的Android编译错误及解决方法?3.aaptaapt2有什么区别?</think> Android编译失败错误`FAILED: out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/Main.o`通常是由**64位系统编译32位工具时的库依赖问题**引起的。以下是逐步解决方案: ### 问题原因分析 错误发生在编译`aapt`(Android Asset Packaging Tool)工具时,主要由于: 1. 缺少32位兼容库 2. 链接器配置错误 3. 多线程库依赖未正确处理 4. 本地编译环境与Android构建系统不兼容 ### 完整解决步骤 #### 步骤1:安装32位兼容库 ```bash sudo apt-get update sudo apt-get install -y lib32z1-dev g++-multilib ``` 32位库在64位系统中必需,`lib32z1-dev`提供zlib压缩支持,`g++-multilib`支持32/64位交叉编译[^3]。 #### 步骤2:修改编译配置 定位`aapt`的makefile文件: ```bash cd /path/to/android/source vim frameworks/base/tools/aapt/Android.mk ``` 在`LOCAL_LDLIBS`部分添加线程库支持: ```diff LOCAL_LDLIBS := -lz ifeq ($(HOST_OS),linux) - LOCAL_LDLIBS += -lrt + LOCAL_LDLIBS += -lrt -lpthread endif ``` 补全`-lpthread`确保正确处理POSIX线程[^3]。 #### 步骤3:清理并重编译 ```bash make clean # 清除旧编译结果 source build/envsetup.sh lunch aosp_x86-eng # 选择目标架构 make -j$(nproc) aapt # 单独编译aapt ``` 若仍有错误,尝试重建整个工具链: ```bash make clean make -j$(nproc) ``` ### 扩展排查方案 | 故障现象 | 解决方案 | |---------|---------| | `/usr/bin/ld: cannot find -lz` | `sudo apt-get install zlib1g-dev` | | `undefined reference to pthread_xxx` | 确保`-lpthread`在链接参数最后 | | 文件权限错误 | `repo sync -f --force-sync frameworks/base` | | 内核版本冲突 | 编译环境推荐Ubuntu 18.04/20.04 | ### 验证修复效果 ```bash file out/host/linux-x86/bin/aapt ``` 输出应包含: ```text ELF 32-bit LSB executable, Intel 80386... ``` 同时运行: ```bash ./out/host/linux-x86/bin/aapt version ``` 成功显示版本号即修复完成。 ### 预防措施 1. 使用官方推荐环境:Ubuntu 18.04/20.04 2. 提前安装必要包: ```bash sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip ``` 3. 定期执行`repo sync --force-sync`
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值