NDK编译log分析

文章详细介绍了ndk-build的执行流程,包括环境初始化、解析mk文件、确定依赖和模块、执行clean、编译源文件、安装SO库以及strip处理,特别是strip选项如何控制优化。

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

ndk-build -B -j64 NDK_LOG=1 V=1

加上V=1,可以把clang++编译每个文件的编译命令打印出来。

可以看到ndk-build的执行流程:

1:初始化环境;确认编译器、platform、abis、查找两个mk,等

2:开始解析Application.mk,再解析Android.mk ;

 3:根据mk,确定依赖,以及编译module;

4:执行clean,删除编译历史文件;

5:开始编译src文件。

6:install so 

7:确认是否需要strip

使用 llvm-strip工具

llvm-strip --strip-unneeded 

使用APP_STRIP_MODE进行控制,默认为 --strip-unneeded 

# APP_STRIP_MODE := none

8:处理shared_lib

使用 clang++  -o进行指定依赖so

<think>好的,用户想要了解如何使用NDK编译一个本地守护进程(native daemon)。首先,我需要确认用户对NDK和守护进程的基本理解程度。可能用户已经知道NDK是用来开发Android应用中的本地代码的,而守护进程是在后台长期运行的程序。但为了确保回答的全面性,我应该先简要介绍这两个概念。 接下来,用户的需求是编译一个native daemon,所以我需要解释如何用NDK工具链进行编译。可能需要提到编写C/C++代码、配置Android.mk或CMakeLists.txt,以及编译步骤。同时,守护进程在Android中的特殊性需要考虑,比如权限问题、进程管理,以及可能的系统限制,因为Android本身对后台进程有严格的管控,特别是在高版本系统中。 然后,用户可能需要具体的步骤示例,比如编写守护进程的主循环,处理信号,防止进程被杀死等。同时,需要注意在Android中,纯粹的原生守护进程可能不如在Linux系统中常见,通常更推荐使用Java/Kotlin的Service组件,但某些情况下如底层硬件操作可能需要native daemon。 此外,权限方面,可能需要系统签名或者root权限,特别是如果用户是在定制系统或需要更高权限的操作。需要提醒用户注意这些限制,避免他们在普通设备上遇到问题。 最后,确保提供的示例代码正确,包括编译脚本和守护进程的基本结构,比如fork、setsid、关闭文件描述符、心跳循环等。同时,要指出可能的陷阱,比如Logcat的使用需要链接Androidlog库,并正确配置Android.mk中的LOCAL_LDLIBS。 总结步骤:编写代码,配置编译文件,编译生成可执行文件,部署到设备,设置权限,运行测试。同时,强调Android中的限制和替代方案,确保用户了解实际应用中的挑战。</think>下面我将分步骤为您介绍如何使用NDK编译Native Daemon: 1. 基本概念 - NDKAndroid Native Development Kit,用于开发C/C++原生代码 - Native Daemon:在Android后台持续运行的原生可执行程序(Linux进程) -Android Service的区别:直接通过init进程启动,不依赖Java层 2. 开发准备 - 安装NDK(最新推荐版本:r25c+) - 配置环境变量:ANDROID_NDK_HOME - 准备交叉编译工具链: ```bash $NDK/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 ``` 3. 编写守护进程代码(示例daemon.c) ```c #include <unistd.h> #include <signal.h> #include <android/log.h> #define TAG "NativeDaemon" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) void signal_handler(int sig) { LOGI("Received signal: %d", sig); } int main() { // 守护进程化 pid_t pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (pid > 0) exit(EXIT_SUCCESS); // 父进程退出 setsid(); // 创建新会话 // 信号处理 signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); // 关闭标准IO close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); // 守护进程主循环 while(1) { LOGI("Daemon is running..."); sleep(5); } return 0; } ``` 4. 编写编译脚本(Android.mk) ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := native_daemon LOCAL_SRC_FILES := daemon.c LOCAL_LDLIBS := -llog # 需要链接Android日志库 include $(BUILD_EXECUTABLE) # 编译为可执行文件 ``` 5. 编译命令 ```bash $NDK/ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=./Application.mk ``` 生成文件路径:./libs/<架构>/native_daemon 6. 部署到Android设备 ```bash adb push native_daemon /system/bin/ adb shell chmod 755 /system/bin/native_daemon ``` 7. 注意事项 - 权限限制:需系统签名或root设备 - SELinux策略:可能需要添加新的策略规则 - Android版本适配:Oreo(8.0)以上版本对后台进程限制更严格 - 保活策略:需要结合系统服务或定时唤醒机制 - 日志查看:使用`adb logcat -s NativeDaemon` 替代方案建议(针对非系统开发者): 1. 使用Android Service + JNI调用原生代码 2. 通过init.rc添加自启动(需要系统权限) 3. 结合JobScheduler实现定时唤醒 最新Android版本(13+)的限制: - 后台进程CPU使用受限 - 无法常驻后台(需前台服务通知) - 严格的电源管理策略 请根据实际需求选择实现方案,系统级daemon开发需要深入理解Android系统架构和Linux进程管理机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值