Clion配置C++程序用Android NDK编译,并用真机远程调试(临时目录和termux)

关键词:ndk, clion, cmake, usb, tcp, ssh, remote debug, remote gdb debug, termux, tabby

前言

假设已经有了一个在windows下能正常编译运行的C++控制台程序,本文仅说明如何在windows下交叉编译到android并调试。C++库类似。

要点提示:

  • 对于unity用户,建议用unity 2022自带的ndk r23。理论上可以用新版,但请找到和版本一致的gdb和gdbserver(r23是有预编译的)

  • 和ndk自带的例子不同,没有app,而是纯粹的控制台程序。无论是上传到临时目录还是termux执行,都不需要root

  • 本文调试基于真机(arm64-v8a,红米,安卓11),如果是虚拟机需要自行修改配置

  • 真机通过USB连接,请使用adb确认已连接成功。理论上可以将本文连接方式改为TCP直接连接,真机设置静态IP

  • 本文使用clion 2023.2,使用其他IDE的读者需要自行探索。对于其他版本的clion,配置可能会有出入,请找到所用版本中最接近的配置

  • 本文忽略了大量细节,仅作为经验笔记供参考,默认读者学习过cmake的命令行使用、cmakelists的编写、linux常用命令、ssh配置和连接等

示例程序(直接改clion新建示例项目):

#include 

int main() {
    std::cout << "Hello, World!" <> a;
    if (a == 1) {
        std::cout << "abc";
    } else {
        std::cout << a;
    }
    return 0;
}

编译流程

参考链接 https://www.quarkay.com/code/701/use-clion-and-ndk-to-compile-and-debug-android-executable-binary

  • 找到ndk位置
C:\Program Files\Unity\Hub\Editor\2022.3.8f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK
  • 在clion工具链中配置关键工具位置

cmake, build tool无所谓,build tool可以不用ndk的make,本文用clion默认的ninja

需要配置C, C++, debugger

C:\Program Files\Unity\Hub\Editor\2022.3.8f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe
C:\Program Files\Unity\Hub\Editor\2022.3.8f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe
C:\Program Files\Unity\Hub\Editor\2022.3.8f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK\prebuilt\windows-x86_64\bin\gdb.exe
  • 继续配置CMake
-G Ninja 
-DCMAKE_TOOLCHAIN_FILE="C:\Program Files\Unity\Hub\Editor\2022.3.8f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK\build\cmake\android.toolchain.cmake"
-DCMAKE_SYSTEM_NAME=Android
-DANDROID_ABI=arm64-v8a
-DCMAKE_ANDROID_NDK="C:\Program Files\Unity\Hub\Editor\2022.3.8f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK"
-DANDROID_PLATFORM=android-30
-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang

全部配置完成后就能直接编译。这部分配置可能需要简化或补充,感兴趣的读者可以进一步研究。

  • 编译成功后直接用adb传到手机上执行,参考命令如下
adb shell rm -rf /data/local/tmp/androidtest
adb shell mkdir /data/local/tmp/androidtest
#adb shell ls /data/local/tmp
adb push ./bin/androidndktest /data/local/tmp/androidtest
adb shell chmod a+x /data/local/tmp/androidtest/androidndktest
adb shell /data/local/tmp/androidtest/androidndktest

远程调试流程

  • 上传gdbserver到临时目录

找到gdbserver位置

C:\Program Files\Unity\Hub\Editor\2022.3.8f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK\prebuilt\android-arm64\gdbserver

切换到该文件夹输入以下命令

adb push gdbserver /data/local/tmp/
adb shell chmod a+x /data/local/tmp/gdbserver
  • 端口转发并启动调试服务
adb forward tcp:11015 tcp:1234
adb shell /data/local/tmp/gdbserver 0.0.0.0:1234 /data/local/tmp/androidtest/androidndktest
  • 在clion配置Remote Debug

debugger:选择上文的ndk自带debugger gdb

‘target remote’ args:tcp:127.0.0.1:11015

  • 在想要的位置打断点,假设是在cin之后,那么在打开了adb shell的窗口(不是clion内置的控制台)中输入任意数字后按下回车就会命中断点
  • 至此已完成普通的调试

自动远程调试流程

预备:termux,ssh(tabby)

  • 用端口反弹,将termux sshd命令公开的端口反弹到本地,ssh配置方法和网上相同
adb forward tcp:11016 tcp:8022
  • 在用tabby测试连接成功后,tabby配置好sftp,确保功能正常

参考链接:https://github.com/Eugeny/tabby/wiki/Shell-working-directory-reporting

下文将作出以下假设:

用户名:u0_a370(ssh密码自己设)

主目录位置:/data/data/com.termux/files/home

  • 用tabby的sftp上传gdbserver到远程位置,并改变执行权限,可以手动运行一遍看看是否成功
chmod a+x ./gdbserver

假设最终gdbserver的位置为

/data/data/com.termux/files/home/gdbserver

实际上在这一步,就可以将编译产物(本文为androidndktest)用sftp上传到主目录位置并执行。

chmod a+x ./androidndktest
./androidndktest

如果执行失败,请先排查原因,也有可能是本文所述的方法不具有普遍性,仅供参考。

  • (重点)配置clion的Remote GDB Server

新建一个,然后填入以下配置

Target和Executable选择要调试的程序androidndktest

GDB选择上文提到的gdb.exe完整路径

Credentials建立ssh连接

Upload Executable选择Always

Upload path: /data/data/com.termux/files/home/tmp/CLion/debug

‘target remote’ args: 127.0.0.1:11015

GDB Server: /data/data/com.termux/files/home/gdbserver

GDB Server args: :1234 /data/data/com.termux/files/home/tmp/CLion/debug/androidndktest

  • 配置完成,应该能进入调试了。假设断点打在cout。clion的调试控制台好像无法输入。如果有需要只能自己重定向输入到文件。

效果如图

调试器界面

调试控制台输出

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/3ada828544.html