Code::Blocks + Android NDK
How to cross properly Code::Blocks
+ Android NDK
so that the debag also works (pass to ADB?). Perhaps there is a manual, or a ready-made profile of settings.
In the search on this topic, there is very little.. except to mention that it's possible.
P.S. please do not offer to install Android Studio.
1 answers
Let's start small, how to fasten Android NDK
to C::B
There are two ways:
- register your own profile for each platform, with executable files according to the platform. In my opinion, it is tedious, a lot of things and it is not clear why. Taking into account that if you collect the same thing for all platforms, then the volume of body movements with switching configurations is quite large.
I have a default collection of
arm64-v8a, armeabi-v7a, x86, x86_64
.
- register your own profile for each platform, with executable files according to the platform. In my opinion, it is tedious, a lot of things and it is not clear why. Taking into account that if you collect the same thing for all platforms, then the volume of body movements with switching configurations is quite large.
I have a default collection of
- use native build system
ndk-build
. This is the simplest and most elegant solution, which does not conflict with most checksC::B
, but, in the settingsC::B
, every detail is important, the scheme is quite capricious, and with inaccuracies it can easily break.
- use native build system
Android NDK integration
The ideology and manner of building an application using the tulchain Android NDK
is as close as possible to the typical behavior C::B
, the logic of the processes:
Build in
Release
mode-stages: always new build the app, copy it to the device, and launch the app. All actions are displayed in the consoleC::B
.Build in
Debug
mode-steps: always build the app again, copy it to the device, copyNDK-парт
files for debugginggdbserver
,gdb.setup
, runninggdbserver
on the device, waiting for the debugger to connectGDB
.Mode
запуска приложения
- steps: launch the application on the device with the output of the results in the console.Mode
Отладка -> Старт
- stages: always build the app again, copy it to the device, copyNDK-парт
files for debugginggdbserv
,gdb.setup
, startgdbserv
on the device, automatically connect the debuggerGDB
, and switch to debug mode.In the modes
Debug
,Отладка -> Старт
, the window of the startupgdbserver
starts in the minimized state and closes automatically at the end of debugging.
Template files:
The project itself C::B
, important sections:
-
<Build><Option output>
- indicates the remote app launch script on the device -RunRemote.cmd
. The script is generated automatically. -
<Build><Option compiler="android_ndk-build">
is the processed compiler name in the settingsC::B
-Android NDK-Build
. How to create a new compiler account is shown below.
The <Extensions><debugger><remote_debugging>
section contains settings for remote debugging implemented with GDB
:
-
options ip_address="127.0.0.1" ip_port="59999" extended_remote="0"
, if there is a need to change the number port, then this must also be done inMakefile
. If the optionextended_remote
will be non-zero, the window of the remotely launchedgdbserver
will not close automatically after debugging.
AndroidNdkTemplate. cbp - project file
C::B
:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="C::B Android Ndk project Template" />
<Option makefile_is_custom="1" />
<Option pch_mode="2" />
<Option compiler="android_ndk-build" />
<Option check_files="0" />
<Build>
<Target title="Release">
<Option output="RunRemote.cmd" prefix_auto="0" extension_auto="0" />
<Option type="1" />
<Option compiler="android_ndk-build" />
</Target>
<Target title="Debug">
<Option output="RunRemote.cmd" prefix_auto="0" extension_auto="0" />
<Option type="1" />
<Option compiler="android_ndk-build" />
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Unit filename="main.c">
<Option compilerVar="CC" />
</Unit>
<Extensions>
<code_completion />
<envvars />
<debugger>
<search_path add="obj/local/armeabi-v7a" />
<search_path add="obj/local/arm64-v8a" />
<search_path add="obj/local/x86" />
<search_path add="obj/local/x86_64" />
<remote_debugging target="Debug">
<options conn_type="0" serial_baud="115200" ip_address="127.0.0.1" ip_port="59999" additional_cmds_before="set solib-search-path obj/local/armeabi-v7a
file obj/local/armeabi-v7a/hello_world
" />
</remote_debugging>
</debugger>
</Extensions>
</Project>
</CodeBlocks_project_file>
Source files of the build management in the project directory NDK
:
Application.mk - setting build parameters:
APP_ABI := all
APP_STL := c++_static
APP_OPTIM := debug
APP_PLATFORM := android-22
APP_BUILD_SCRIPT := Android.mk
Android.mk - in fact, it is a make-file unique for each
NDK
project (application):
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello_world
LOCAL_SRC_FILES := ./main.c
LOCAL_C_INCLUDES := ./
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
Makefile - directly runs
C::B
:
PLATFORM := armeabi-v7a
NDKROOT := C:\__BuildSource\__LIB__\android-ndk-r20-beta2
PROJECT := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
BUILDTAG := $(filter-out $@,$(MAKECMDGOALS))
BUILDOPT :=
include Application.mk
include $(APP_BUILD_SCRIPT)
ifneq ($(APP_ABI),all)
PLATFORM = $(APP_ABI)
endif
ifeq ($(BUILDTAG),Debug)
BUILDOPT = V=1 NDK_DEBUG=1
else
BUILDOPT = -j 4
endif
all: allndk
Debug: allndk adbsetup adbdebug buildscript rundebug
Release: allndk adbsetup adbexec buildscript
cleanDebug: clean
cleanRelease: clean
cleanall: clean
allndk:
@echo '==== Build $(BUILDTAG) -> $(APP_ABI) platform -> active device: [ $(PLATFORM) ] ===='
@Cmd.exe /C $(NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(PROJECT)Application.mk NDK_PROJECT_PATH=$(PROJECT) $(BUILDOPT)
clean:
@echo '==== Clean ===='
@Cmd.exe /C $(NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(PROJECT)Application.mk NDK_PROJECT_PATH=$(PROJECT) clean
@Cmd.exe /C adb.exe shell rm -f /data/local/tmp/$(LOCAL_MODULE)
adbsetup:
@echo '==== ADB SETUP: [ $(PLATFORM) ] ===='
@Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\$(LOCAL_MODULE) /data/local/tmp/$(LOCAL_MODULE)
@Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/$(LOCAL_MODULE)
adbexec:
@echo '==== ADB RUN: [ $(PLATFORM) ] ===='
@Cmd.exe /C adb.exe shell /data/local/tmp/$(LOCAL_MODULE)
adbdebug:
@echo '==== GDB Debug: [ $(PLATFORM) ] ===='
@Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\gdb.setup /data/local/tmp/gdb.setup
@Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\gdbserver /data/local/tmp/gdbserver
@Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/gdbserver
rundebug:
@Cmd.exe /C DebugRemote.cmd
buildscript:
ifeq (,$(wildcard ./RunRemote.cmd))
@echo "adb.exe shell /data/local/tmp/$(LOCAL_MODULE)" >RunRemote.cmd
endif
ifeq (,$(wildcard ./DebugRemote.cmd))
@echo "adb.exe forward tcp:59999 tcp:59999" >DebugRemote.cmd
@echo "start \"$(PLATFORM) GDB server\" /MIN adb.exe shell /data/local/tmp/gdbserver :59999 /data/local/tmp/$(LOCAL_MODULE)" >>DebugRemote.cmd
@echo "exit" >>DebugRemote.cmd
endif
.PHONY: clean all
The Application.mk
and Makefile
files are universal for all projects built with NDK
and do not require edits.
To understand the structure of where what lies in the project NDK
of the application, I will give a tree:
│ Android.mk
│ AndroidNdkTemplate.cbp
│ Application.mk
│ main.c
│ Makefile
│
├───libs
│ ├───arm64-v8a
│ │ gdb.setup
│ │ gdbserver
│ │ hello_world
│ ├───armeabi-v7a
│ │ gdb.setup
│ │ gdbserver
│ │ hello_world
│ ├───x86
│ │ gdb.setup
│ │ gdbserver
│ │ hello_world
│ └───x86_64
│ gdb.setup
│ gdbserver
│ hello_world
│
└───obj
└───local
├───arm64-v8a
│ │ hello_world
│ ├───objs
│ │ └───hello_world
│ └───objs-debug
│ └───hello_world
│ main.o
│ main.o.d
├───armeabi-v7a
│ │ hello_world
│ │
│ ├───objs
│ │ └───hello_world
│ └───objs-debug
│ └───hello_world
│ main.o
│ main.o.d
├───x86
│ │ hello_world
│ │
│ ├───objs
│ │ └───hello_world
│ └───objs-debug
│ └───hello_world
│ main.o
│ main.o.d
└───x86_64
│ hello_world
│
├───objs
│ └───hello_world
└───objs-debug
└───hello_world
main.o
main.o.d
Project settings view from GUI C::B
:
Be sure to specify the possible paths where the object files with debugging symbols are located:
obj/local/armeabi-v7a
obj/local//arm64-v8a
obj/local/x86
obj/local/x86_64
You need to add the GDB
commands that transmit information about finding debug symbols for the platform of the connected device:
-
set solib-search-path obj/local/armeabi-v7a
- location of debug symbols for the active device. -
file obj/local/armeabi-v7a/<имя приложения>
- name of the application being debugged.
View of the compiler settings in C::B
:
Additional debug menu NDK
of the application:
Both used in the menu the scripts have a fixed name and are generated automatically during execution Makefile
, for convenience, it is reasonable to add them to the menu:
The application debugging method consists of typical actions, for example, via F8
or the Отладка -> Старт
menu. As soon as the debugger is started, you need to call the ADB Debug Remote server
item from the created menu, with this command you will launch GDB сервер
on the device that will launch your application. You are connecting to GDB серверу
remotely and can conduct a debugging session.
In the Debug
mode, the remote server is started automatically and does not require calling this menu item.
See the screenshot of the debugger settings in the project above.
This debug startup scheme also supports non-rooted devices.
The global debugger settings for NDK
look like this:
Debugging on on the device:
The result of building the application by the tolchein NDK
:
Advantages of using NDK:
In contrast to a static build for a specific platform:
No need to compile binaries statically, so the output binary file size will be smaller.
You can use android
C/C++
libraries, such as liblog, to be able to have output in logcat from the application.
Features of this solution:
No rooted device required
Full-fledged debugging of the assembly, without additional tools (NDK toolset)
Full build in
Debug/Release
modesFull launch of the app (from the device)
Auto start / stop
gdbserver
with devices-
No wrappers from the
{[83 device]}Gradle/Java
code required, works directly with the
Full code of HOWTO NDK C::B template
posted on github