记录动态库so 和静态库lib编译,Makefile, Android.mk技巧。
1. gcc 命令编译
1.1 编译静态库
(1)用源文件创建目标文件
gcc -I/**** -c encypt.c -o encypt.o
gcc -c checksum.c -o checksum.o
(2)用创建的.o目标文件,创建.a静态库
ar -rcs libhfsecurity.a encypt.o checksum.o
(3)使用.a静态库,编译最终生成件
gcc bank_vault.c -I . -L . -lhfsecurity -o bank_vault
rcs:r表示如果.a文件存在就更新它
c表示创建存档时不显示反馈信息
s告诉ar要在.a文件开头创建索引
-I告诉编译器头文件存放位置
-L告诉编译器库存放路径
1.2 编译动态so库
gcc -shared hfcal.o -o c:\libs\hfcal.dll #windows上的MinGW
gcc -shared hfcal.o -o /libs/libhfcal.dll.a #windows上的cygwin
gcc -shared hfcal.o -o /libs/libhfcal.so #linux或者unix
gcc -shared hfcal.o -o /libs/libfcal.dylib #mac
gcc -I/include -c elliptical.c -o elliptical.o
gcc elliptical.o -L/libs -lhfcal -o elliptical
1.3 编写Makefile
1.3.1 Makefile生成执行文件
target… : prerequisites … command
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令)
1 test_main: test.o test1.o test2.o
2 cc -o test_main test.o test1.o test2.o
3
4 test.o:test.c
5 cc -c test.c
6 test1.o:test1.c
7 cc -c test1.c
8 test2.o:test2.c
9 cc -c test2.c
10
11 clean :
12 rm test_main test1.o test2.o
上述为最原始简单的makefile文件写法,test_main为目标文件,冒号后面的为生成test_main所需要的文件。
cc才是真正执行的命令。
在Makefile中还可以定义变量引用。
参考文献:其他高级技巧参见已有makefile以及如下网页 http://blog.csdn.net/ruglcc/article/details/7814546/
1.3.2 Makefile生成静态库
#!/bin/bash
#设置编译工具
CC =
LD =
AR =
#头文件路径
DIR_INC = ./
#源码路径
DIR_SRC = ./
#生成目标文件路径
DIR_OBJ = ./
#生成二进制文件路径
DIR_BIN = ./
#生成库文件名称
LIB_OBJECT = $(DIR_BIN)test.a
#源文件路径,wildcard扩展通配符,把DIR_SRC目录下的所有后缀都是.c的文件都展开。
SRC = $(wildcard ${DIR_SRC}/*.c)
#patsubst把$(SRC)中的变量符合后缀是.c的全部替换成.o
OBJ = $(patsubst %.c, %.o, $(SRC))
#配置编译选项
FLAG := -02 -mfloat-abi=softfp -mfpu=neon -fno-exceptions -I${DIR_INC} -std=c11
#生成的库文件需要依赖的文件$(OBJ)
#调用AR工具打包
#$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件
#--strip-debug 去除调试信息
$(LIB_OBJECT):$(OBJ)
$(AR) -rcs -o $@ $^
arm-none-eabi-strip --strip-debug $@
#表示所有的目标文件及其依赖文件
%.o:%.c
$(CC) $(FLAG) -c $< -o $@
#make clean需要删除的文件
clean:
rm -f ./*o ./*.a
2. Android 编译
NDK单独编译或者放到Android源码中编译。
2.1 静态库
2.1.1 NDK-build编译库文件,NDK编译需要使用到两个mk文件.
Android.mk
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := lib***
LOCAL_SRC_FILES := ***.c
include $(BUILD_STATIC_LIBRARY)
Application.mk
#同时支持两种指令集
APP_ABI := arm64-v8a armeabi-v7a
#支持平台
APP_PLATFORM :=android-21
#优化选项APP_OPTIM
此变量是可选的,其值可以为'release'或'debug'.此变量用来修改优先等级.默认情况下为release.在release模式下,将编译生成被优化了的二进制的机器码,而debug模块用来生成便于调试的未被优化的二进制机器码。
APP_OPTIM :=release
#标准库
APP_STL:= gnustl_static
#编译选项
APP_CFLAGS += -Wno-error=format-security
在本地新建jni目录,配置好连个mk文件,在目录下,运行NDK-build即可生成对应的静态文件。
2.1.2 NDK将第三方静态库ndk编译为动态库
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := name
LOCAL_SRC_FILES := lib***.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_STATIC_LIBRARIES := ***
LOCAL_SRC_FILES := *.c
include $(BUILD_SHARED_LIBRARY)
2.2 Android源码中编译动态库及可执行程序
Android.mk与NDK下写法大致一样。 在编译之前需要配置好运行环境
source build/envsetup.sh
Lunch 选择angler相关选项(如果需要编译其他内核,选择对应即可)
make bootimage -j4