手动写Makefile编译Android NDK的so

本文介绍了一种手动编译NDK C代码的方法,通过这种方式可以有效减小.so文件大小并清理无用符号,同时提供了详细的Makefile及编译指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之所以摒弃NDK,是因为NDK编译出来的so太大,而且导出表总有一些没用的符号。而且手动编译的话,可以得到编译过程中间的.i和.s文件,可以删除一些没用的汇编代码。

现在代码列出来:

我的NDK C的代码如下,main.c:

#include <stdio.h>
#include <string.h>
#include <jni.h>
#ifndef __ANDROID_LOGCAT_H__
#define __ANDROID_LOGCAT_H__

#define TEST_DEBUG 1

#ifdef TEST_DEBUG

#include <android/log.h>
	#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
	#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
	#define LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
	#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
	#define LOGF(...)  __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
#else 
	#define LOGI(...) 	{}
	#define LOGD(...)  	{}
	#define LOGW(...)  	{}
	#define LOGE(...)  	{}
	#define LOGF(...)  	{}

#endif 

#endif


#define LOG_TAG "ss"

int encrypt() {
	int i = 0;
	char plaintext[128] = "abcdefg";
	LOGI("in encrypt!");
	return i;
}
JNIEXPORT jint Java_com_ss_jni_JNIUtil_nativec(JNIEnv *env, jclass thizz) {
	encrypt();
	return 1;
}


下面是Makefile文件的写法:

NDK_ROOT=D:\eclipse-android\android-ndk-r9d
TOOLCHAINS_ROOT=$(NDK_ROOT)\toolchains\arm-linux-androideabi-4.6\prebuilt\windows
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)\bin\arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)\lib\gcc\arm-linux-androideabi\4.6\include-fixed
PLATFORM_ROOT=$(NDK_ROOT)\platforms\android-19\arch-arm
PLATFORM_INCLUDE=$(PLATFORM_ROOT)\usr\include
PLATFORM_LIB=$(PLATFORM_ROOT)\usr\lib
CC := $(TOOLCHAINS_PREFIX)-gcc

FLAGS=-I$(TOOLCHAINS_INCLUDE) \
	-I$(PLATFORM_INCLUDE) \
	-L$(PLATFORM_LIB) \
	-fPIC \
	-shared \
	-llog \

MODULE_NAME=hello
CFLAGS  = -Wall -g
LDFLAGS = -llog -shared
SRC =hello.c
EXE =librusteze.so

all:
	$(CC) -E $(MODULE_NAME).c $(FLAGS) -o $(MODULE_NAME).i
	$(CC) -S $(MODULE_NAME).i $(FLAGS) -o $(MODULE_NAME).s
	$(CC) -c $(MODULE_NAME).s $(FLAGS) -o $(MODULE_NAME).o
	$(CC) $(MODULE_NAME).o $(FLAGS) -o lib$(MODULE_NAME).so
	$(TOOLCHAINS_PREFIX)-strip lib$(MODULE_NAME).so

clean:
	$(RM) $(MODULE_NAME).i $(MODULE_NAME).s $(MODULE_NAME).o $(EXE)

可以看到首先gcc -E预编译

接下来gcc -S 编译

gcc -c汇编

strip隐藏符号和函数名字


在Windows平台,CMD命令行执行mingw32-make。(前提是装了MinGW,并且配置了环境变量)

D:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-gcc -E main.c -ID:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.6\include-fixed -ID:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include -LD:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\lib -fPIC -shared -llog  -o main.i
D:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-gcc -S main.i -ID:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.6\include-fixed -ID:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include -LD:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\lib -fPIC -shared -llog  -o main.s
D:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-gcc -c main.s -ID:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.6\include-fixed -ID:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include -LD:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\lib -fPIC -shared -llog  -o main.o
D:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-gcc main.o -ID:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.6\include-fixed -ID:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include -LD:\eclipse-android\android-ndk-r9d\platforms\android-19\arch-arm\usr\lib -fPIC -shared -llog  -o librusteze.so
D:\eclipse-android\android-ndk-r9d\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-strip librusteze.so



编译成功:

得到librusteze.so

新建一个Android工程testso:

public class JNIUtil {
	static {
		System.loadLibrary("rusteze");
	}
	public static native int nativec();
}

在MainActivity中调用JNIUtil.nativec();

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		JNIUtil.nativec();
		
	}
}

可以看到logcat中打印出来的日志。

可以达到缩小so的目的,还有导出表里也没有那些奇怪的导出符号了。

见下图:


但是导入表也没有了,见下图:



android工程代码在github上点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值