Я работаю над проектом Android
который использует класс Java
который является оберткой для библиотеки C++
. Библиотека C++ является внутренней библиотекой компании, и у нас есть доступ к ее исходному коду, но в проекте Android она только динамически связана, поэтому она используется только в форме заголовков (.h) и общих объектов (.so). Имея доступ к исходному коду библиотеки, можно ли указать Android Studio путь к исходному коду, чтобы я мог войти в библиотеку с помощью отладчика?
Отладчик работает, я могу войти в функцию Java_clory_engine_sdk_CloryNative_nativeInit
, но я также хотел бы продолжить отладку библиотеки, соответствующей Clory::Engine
которая, как я упоминал, является внутренней библиотекой, к которой у нас есть доступ к исходному коду.
Например, Clory::Engine::instance
является частью библиотеки, и я хотел бы указать Android Studio местоположение файла CloryEngine.cpp
чтобы я мог войти в Clory::Engine::instance
с помощью отладчика, таким образом отлаживая это статическая функция-член.
Я использую Android Studio 3.1.4.
Это возможно?
РЕДАКТИРОВАТЬ:
clory-sdk.gradle
указывает файл CMakeLists.txt
который конфигурирует слой C++.
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
Поэтому я использую внутреннее приложение, которое использует Clory SDK. Внутри файла app.gradle
я использую:
dependencies {
...
compile project(':clory-sdk-core')
compile project(':clory-sdk')
...
}
так что я не думаю, что мы используем aar
для app.gradle
проекта. aar
отправляется клиенту, но мы используем проект app.gradle
чтобы протестировать наши маленькие функциональные возможности SDK, прежде чем делать это. Уровень JNI находится внутри clory-sdk-core
.
РЕДАКТИРОВАТЬ 2:
Вот CMakeLists.txt
который обрабатывает уровень JNI:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_BUILD_TYPE Debug)
add_library(
clory-lib
SHARED
# JNI layer and other helper classes for transferring data from Java to Qt/C++
src/main/cpp/clory-lib.cpp
src/main/cpp/JObjectHandler.cpp
src/main/cpp/JObjectResolver.cpp
src/main/cpp/JObjectCreator.cpp
src/main/cpp/DataConverter.cpp
src/main/cpp/JObjectHelper.cpp
src/main/cpp/JEnvironmentManager.cpp
)
find_library(
log-lib
log
)
target_compile_options(clory-lib
PUBLIC
-std=c++11
)
# Hardcoded for now...will fix later...
set(_QT_ROOT_PATH /Users/jacob/Qt/5.8)
if(${ANDROID_ABI} MATCHES ^armeabi-v7.*$)
set(_QT_ARCH android_armv7)
elseif(${ANDROID_ABI} MATCHES ^x86$)
set(_QT_ARCH android_x86)
else()
message(FATAL_ERROR "Unsupported Android architecture!!!")
endif()
set(CMAKE_FIND_ROOT_PATH ${_QT_ROOT_PATH}/${_QT_ARCH})
find_package(Qt5 REQUIRED COMPONENTS
Core
CONFIG
)
target_include_directories(clory-lib
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src/main/cpp
)
set(_CLORYSDK_LIB_PATH ${CMAKE_CURRENT_LIST_DIR}/src/main/jniLibs/${ANDROID_ABI})
target_link_libraries(clory-lib
${log-lib}
-L${_CLORYSDK_LIB_PATH}
clorysdk
Qt5::Core
)
Библиотека clorysdk
на самом деле является нашей внутренней библиотекой, о которой я говорил, которая содержит, например, Clory::Engine::instance
я хотел бы войти с помощью отладчика. Он был построен с помощью qmake
и построен в режиме отладки (CONFIG+=debug
была добавлена в эффективный вызов qmake).
РЕДАКТИРОВАТЬ 3:
В сеансе LLDB
который открылся после того, как он достиг точки останова Java_clory_engine_sdk_CloryNative_nativeInit
, я получил следующее:
(lldb) image lookup -vrn Clory::Engine::instance
2 matches found in /Users/jacob/.lldb/module_cache/remote-android/.cache/6EDE4F0A-0000-0000-0000-000000000000/libclorysdk.so:
Address: libclorysdk.so[0x0001bb32] (libclorysdk.so..text + 8250)
Summary: libclorysdk.so'Clory::Engine::instance(Clory::Engine::Purpose)
Module: file = "/Users/jacob/.lldb/module_cache/remote-android/.cache/6EDE4F0A-0000-0000-0000-000000000000/libclorysdk.so", arch = "arm"
Symbol: id = {0x0000005e}, range = [0xcb41eb32-0xcb41ebc0), name="Clory::Engine::instance(Clory::Engine::Purpose)", mangled="_ZN4Clory2Engine8instanceENS0_7PurposeE"
Address: libclorysdk.so[0x0001b82c] (libclorysdk.so..text + 7476)
Summary: libclorysdk.so'Clory::Engine::instance(Clory::RuntimeConfiguration const&, Clory::Engine::Purpose)
Module: file = "/Users/jacob/.lldb/module_cache/remote-android/.cache/6EDE4F0A-0000-0000-0000-000000000000/libclorysdk.so", arch = "arm"
Symbol: id = {0x000000bd}, range = [0xcb41e82c-0xcb41e970), name="Clory::Engine::instance(Clory::RuntimeConfiguration const&, Clory::Engine::Purpose)", mangled="_ZN4Clory2Engine8instanceERKNS_20RuntimeConfigurationENS0_7PurposeE"
(lldb) settings show target.source-map
target.source-map (path-map) =
Прежде всего, в результате image lookup -vrn Clory::Engine::instance
команды image lookup -vrn Clory::Engine::instance
не CompileUnit
раздела image lookup -vrn Clory::Engine::instance
. Как это возможно, чтобы не было задано никакой карты-источника (вторая команда lldb), если libclorysdk.so
был libclorysdk.so
в режиме отладки? Можно ли явно установить его так, чтобы отладчик искал там исходные файлы библиотеки?
РЕДАКТИРОВАТЬ 4:
После поиска я обнаружил, что процесс создания APK фактически удаляет библиотеки *.so
из их символов отладки. Встроенный в режиме отладки libclorysdk.so
занимает около 10 МБ, а файл libclorysdk.so
который я извлек после разархивирования сгенерированного файла *.apk
составляет всего 350 КБ. Как указано здесь, выполнение greadelf --debug-dump=decodedline libclorysdk.so
в отладочной версии выводит ссылки на исходные файлы, но если команда выполняется в извлеченной библиотеке *.apk
, она ничего не выводит.
Есть ли способ остановить Android Studio от зачистки *.so
s? Я попробовал, как избежать удаления символов собственного кода для приложения Android, но не дал никакого эффекта, файл *.apk
имеет тот же размер, что и раньше, и отладка собственных библиотек все еще не работает.
Я использую Gradle 3.1.4
.
РЕДАКТИРОВАТЬ 5:
Решение для зачистки работает, но в моем случае ему потребовалась Clean & Build, прежде чем попасть в точки останова в библиотеке. Развертывание *.so
которое не было удалено, позволяет вам проводить сеансы отладки и входить в собственные библиотеки.
Замечания:
Если библиотеки построены с Qt for Android
цепочки инструментов Qt for Android
, *.so
развернутый в $SHADOW_BUILD/android-build
, также $SHADOW_BUILD
(где $SHADOW_BUILD
- это каталог сборки, обычно начинающийся с build-*
). Поэтому для их отладки вы должны скопировать их из директории android-build
где генерируется каждый *.so
.