Я работаю над проектом 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.
