Я работаю над проектом Android
, в котором используется класс Java
, который является оберткой для библиотеки C++
.Библиотека C ++ является внутренней библиотекой компании, и у нас есть доступ к ее исходному коду, но в проекте Android она только динамически связана, поэтому она используется только в виде заголовков ( .h ) и совместно используется.объекты ( .so ).Имея доступ к исходному коду библиотеки, можно ли указать Android Studio путь к исходному коду, чтобы я мог войти в библиотеку с помощью отладчика?
Отладчик работает, я могу войти внутрь Java_clory_engine_sdk_CloryNative_nativeInit
function, но я также хотел бы продолжить отладку библиотеки, соответствующей классу 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
s для проекта app.gradle
.aar
s отправляются клиенту, но мы используем проект 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).
EDIT 3:
В *Сессия 1068 *, которая открылась после достижения точки останова 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
не было секции CompileUnit
.Как это возможно, чтобы не было определено source-map (вторая lldb команда), если libclorysdk.so
был встроен в режиме Debug ?Можно ли явно установить его так, чтобы отладчик искал там исходные файлы библиотеки?
РЕДАКТИРОВАТЬ 4:
После поиска я обнаружил, что процесссоздания APK фактически убирает библиотеки *.so
из их символов отладки.Встроенный в режиме отладки libclorysdk.so
занимает около 10 МБ, а извлеченный после разархивирования сгенерированного *.apk
файла libclorysdk.so
всего 350 КБ.Как указано здесь , запуск greadelf --debug-dump=decodedline libclorysdk.so
в отладочной версии выводит ссылки на исходные файлы, но если команда выполняется в извлеченной библиотеке *.apk
, она ничего не выводит.
IsЕсть ли способ остановить Android Studio от зачистки *.so
с?Я попробовал Как избежать удаления символов собственного кода для приложения для Android , но не дал никакого эффекта, файл *.apk
имеет тот же размер, что и раньше, и отладка собственных библиотек все еще не работает.
Я использую Gradle 3.1.4
.
РЕДАКТИРОВАТЬ 5:
Раствор для очистки работает, но в моем случае этонужна была Clean & Build, прежде чем попасть в точки останова в библиотеке.Развертывание *.so
s, которые не были удалены, позволяет вам проводить сеансы отладки и входить в собственные библиотеки.
Примечание:
Если библиотеки построены с использованием цепочки инструментов Qt for Android
, *.so
, развернутые в $SHADOW_BUILD/android-build
, также удаляются (где $SHADOW_BUILD
- каталог сборки, обычно начинающийся с build-*
).Поэтому для их отладки вы должны скопировать их из каталога android-build
, в котором генерируется каждый *.so
.