android build system

来源:互联网 发布:sftp用的什么端口 编辑:程序博客网 时间:2024/06/06 15:50

1、gcc编译参数详解

1)-E

指示编译器对输入文件进行预处理,并将结果输出到标准输出(控制台)。预处理包括头文件的包含、宏定义的扩展、条件编译的选择等。

2)-D和-U

-D在命令行定义宏,作用等同于在代码中进程宏定义;-U用于取消宏定义。

例如–DDEBUG=1   <=>#define DEBUG 1

#include <stdio.h>int main(){    printf("hello world!\n");    #ifdef DEBUG      printf("hello debug!\n");    #endif    return 0;}

不带—D进行编译的输出结果

hxiong@www_hxiong_com /cygdrive/e/project/cygwin_project/c_project/debug$ gcc -o main main.chxiong@www_hxiong_com /cygdrive/e/project/cygwin_project/c_project/debug$ ./mainhello world!hxiong@www_hxiong_com /cygdrive/e/project/cygwin_project/c_project/debug$

带—D进行编译的输出结果

hxiong@www_hxiong_com /cygdrive/e/project/cygwin_project/c_project/debug$ gcc -DDEBUG=1 -o main main.chxiong@www_hxiong_com /cygdrive/e/project/cygwin_project/c_project/debug$ ./mainhello world!hello debug!hxiong@www_hxiong_com /cygdrive/e/project/cygwin_project/c_project/debug$

3)-S

指示编译器产生汇编代码文件后停止,汇编代码缺省的文件后缀名是.s

例如gcc –S main.c            

会生成main.s文件,内容如下

.file"main.c".def__main;.scl2;.type32;.endef.section .rdata,"dr".LC0:.ascii "hello world!\0".text.globlmain.defmain;.scl2;.type32;.endef.seh_procmainmain:pushq%rbp.seh_pushreg%rbpmovq%rsp, %rbp.seh_setframe%rbp, 0subq$32, %rsp.seh_stackalloc32.seh_endprologuecall__mainleaq.LC0(%rip), %rcxcallputsmovl$0, %eaxaddq$32, %rsppopq%rbpret.seh_endproc.ident"GCC: (GNU) 4.9.3".defputs;.scl2;.type32;.endef

4)-c

指示编译器只编译源文件,但不进行连接,生成的文件为.o,这是可以重定向的目标程序。

5)-o

指示编译器为生成的可执行文件指定文件名,也就是设置可执行文件的文件名

6)-g

指示编译器产生可以被gnu调试工具进行调试的程序。

7)-l

用来指定程序要连接的库,例如 gcc –lc 实际上是链接libc.so库,也就是去掉了库前面的lib和后面的.so。

8)-L

指定连接的库文件所在的目录,例如gcc –L/usr/lib –lc就是链接/usr/lib目录下的libc.so库。

9)-include和-I

-include指定要包含的头文件,-I用于指定头文件所在的目录。

10)-Wl

WL后面的参数会传给链接程序

11)-shared

生成共享目标文件,通常用于编译动态库文件。

2、编译可执行程序

我们以cameraserve为例,Android.mk指定了编译的规则

frameworks\av\camera\cameraserver\Android.mk

# LOCAL_PATH重新赋值为当前的路径LOCAL_PATH:= $(call my-dir)# 清除之前设置的LOCAL_XXX变量,除了LOCAL_PATHinclude $(CLEAR_VARS)# 设置需要需要编译的源文件LOCAL_SRC_FILES:= \main_cameraserver.cpp# 设置需要链接的动态库LOCAL_SHARED_LIBRARIES := \libcameraservice \libcutils \libutils \libbinder \libcamera_client# 设置编译出来的目标文件名LOCAL_MODULE:= cameraserverLOCAL_32_BIT_ONLY := true# gcc编译参数的设置LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter# 设置rc文件LOCAL_INIT_RC := cameraserver.rc# 指定要编译成可执行程序文件include $(BUILD_EXECUTABLE)

BUILD_EXECUTABLE定义在

build\core\config.mk

…CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mkBUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mkBUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mkBUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mkBUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mkBUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mkBUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mkBUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk…

所以include $(BUILD_EXECUTABLE) 实际上是 include build/core/executable.mk

 

我们继续看executable.mk 做了什么事

差不多是做了一大堆的设置和检查工作,最后include executable_internal.mk

build\core\executable.mk

…# check if non-preferred arch is supportedinclude $(BUILD_SYSTEM)/module_arch_supported.mkifeq ($(my_module_arch_supported),true)# non-preferred arch is supportedOVERRIDE_BUILT_MODULE_PATH :=LOCAL_BUILT_MODULE :=LOCAL_INSTALLED_MODULE :=LOCAL_INTERMEDIATE_TARGETS :=include $(BUILD_SYSTEM)/executable_internal.mkendif…

我们继续往下看executable_internal.mk 做了什么事

build\core\executable_internal.mk

…ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)  #这里表示编译静态可执行程序$(linked_module): $(my_target_crtbegin_static_o) $(all_objects) $(all_libraries) $(my_target_crtend_o)$(transform-o-to-static-executable)$(PRIVATE_POST_LINK_CMD)else  #否则编译动态可执行程序,需要连接动态库$(linked_module): $(my_target_crtbegin_dynamic_o) $(all_objects) $(all_libraries) $(my_target_crtend_o)$(transform-o-to-executable)$(PRIVATE_POST_LINK_CMD)endif…

$(linked_module):针对cameraserver out/target/product/$(project)/arm/EXECUTABLES/cameraserver_intermediates/LINKED/cameraserver

$( my_target_crtbegin_dynamic_o): out/target/product/$(project)/arm/lib/crtbegin_dynamic.o

$(all_objects):是out/target/product/$(project)/arm/EXECUTABLES/cameraserver_intermediates/main_cameraserver.o

$(all_libraries):是out/target/product/$(project)/arm/lib/cameraservice.so也就是LOCAL_SHARED_LIBRARIES引用的so,当然还包括libc.so libm.so

$(my_target_crtend_o):是out/target/product/$(project)/arm/lib/crtend_android.o

$( transform-o-to-executable) 是执行gcc编译命令的命令行。

定义在build\core\ definitions.mk

define transform-o-to-executable@echo "target Executable: $(PRIVATE_MODULE) ($@)"@mkdir -p $(dir $@)$(transform-o-to-executable-inner)endef
makefile中的define endef可以认为它就是定义了一个函数,里面的内容就是执行的命令。

define transform-o-to-executable-inner$(hide) $(PRIVATE_CXX) -pie \-nostdlib -Bdynamic \-Wl,-dynamic-linker,$(PRIVATE_LINKER) \-Wl,--gc-sections \-Wl,-z,nocopyreloc \$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O) \$(PRIVATE_ALL_OBJECTS) \-Wl,--whole-archive \$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \-Wl,--no-whole-archive \$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_COVERAGE_LIB)) \$(PRIVATE_TARGET_LIBATOMIC) \$(PRIVATE_TARGET_LIBGCC) \$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \-o $@ \$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \$(PRIVATE_LDFLAGS) \$(PRIVATE_TARGET_CRTEND_O) \$(PRIVATE_LDLIBS)endef
transform-o-to-executable-inner里面就是gcc编译出可执行程序的命令,在知道gcc命令参数的情况下,我们把里面的参数还原出来。

$(hide):这里就是一个字符@  @放在命令的前面是在执行的时候不将命令打印出来。

$(PRIVATE_CXX):这里是prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-g++

所以$(hide) $(PRIVATE_CXX) 就是调用g++程序来进行编译,后面就都是gcc/g++的相关参数了,前面有讲一些。

-pie 加了这个参数后,程序的地址是可以变化的。

-Wl,-dynamic-linker 用于设置动态链接器

$(PRIVATE_LINKER):这里是/system/bin/linker64 (64位)

$(PRIVATE_TARGET_GLOBAL_LD_DIRS):这里是-Lout/target/product/$(project)/arm/lib

$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES):这里是out/target/product/$(project)/arm/lib

$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O):这里是out/target/product/$(project)/arm/lib/crtbegin_dynamic.o

$(PRIVATE_ALL_OBJECTS):这里是out/target/product/$(project)/arm/EXECUTABLES/cameraserver_intermediates/main_cameraserver.o

$(PRIVATE_TARGET_LIBGCC) 是prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/lib/gcc/aarch64-linux-android/4.9/libgcc.a

$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES))执行的结果是得到需要连接的lib库,比如 lcameraservice lbinder lc lutils ... 也就是LOCAL_SHARED_LIBRARIES包含的库和必需的库,用空格分开。

$@ 是out/target/product/$(project)/arm/EXECUTABLES/cameraserver_intermediates/LINKED/cameraserver

$(PRIVATE_TARGET_GLOBAL_LDFLAGS)是-WL,-z,noexecstack  –WL,-z,relro –WL,-z,now –WL,…

–WL,-z,now 表示函数立刻绑定

$(PRIVATE_TARGET_CRTEND_O) 是out/target/product/$(project)/arm/lib/crtend_android.o





原创粉丝点击