Я использую Android Studio (3.4.1) для создания apk, содержащего часть C++. Фаза компиляции работает, а фаза ссылки выдает ошибку.
Ошибка :
clang++: error: no such file or directory: '/Users/homefolder/Library/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86/libgnustl_static.a'
Это происходит из последней строки команды полной ссылки:
/Users/homefolder/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=i686-none-linux-android23 --gcc-toolchain=/Users/homefolder/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64 --sysroot=/Users/homefolder/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -fno-addrsig -Wa,--noexecstack -Wformat -Werror=format-security -O2 -DNDEBUG -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments -Wl,-z,noexecstack -shared -Wl,-soname,libmy_lib.so -o ../../../../build/intermediates/cmake/release/obj/x86/libmy_lib.so CMakeFiles/my_lib.dir/src/main/cpp/my_lib.cpp.o -llog ../../../../libs/x86/libssl.a ../../../../libs/x86/libcrypto.a -latomic -lm "/Users/homefolder/Library/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86/libgnustl_static.a"
Действительно, этой библиотеки нет в моей папке sdk. Папка gnu-lib-stdc++
не существует.
Насколько я понимаю, нативный код компилируется с помощью CMake. CMake генерирует файлы build.ninja и запускает ninja для компиляции. Если я вручную изменю эти сгенерированные файлы build.ninja удалить эту библиотеку, а затем вызову ninja
в терминале (в правильной папке), то он отлично скомпилируется и линкуется.
Эта проблема :
Где мне изменить настройки Android Studio, чтобы эти файлы build.ninja больше не содержали эту библиотеку? Я не хочу изменять сгенерированные файлы каждый раз, когда я создаю apk.
Что я пробовал до сих пор:
Единственный файл параметров, связанный с CMake, который я нашел, — это CMakeList.txt
. И из документации (1) кажется, что эту библиотеку можно настроить с помощью CMAKE_ANDROID_STL_TYPE
. Я поставил это на 'none'
или 'system'
в CMakeList.txt
, но не вижу разницы в файлах build.ninja.
# CMakeList.txt
set(CMAKE_ANDROID_STL_TYPE none)
Конфигурация:
@Tsyvarev Означает ли «-lm» ссылку на математическую библиотеку, а следующий путь является ссылкой на эту библиотеку? Насколько я понимаю, это весь вариант, который я хочу удалить. Это не ?
Нет, -lm
— это опция отдельный для ссылки на математическую библиотеку. Последний аргумент в двойных кавычках тоже является опцией отдельный, и это также означает связывание. Разница между последними двумя вариантами в том, что флаг -l
запрашивает компоновщик поиск библиотеки. Без -l
компоновщики просто используют переданный путь.
Хорошо, я понимаю, спасибо. Я модифицирую тему. Тем не менее, я пробовал много значений для set()
перед вызовом add_library
, и build.file вообще не изменился. Как будто мой set()
не действует.
У вас также установлен NDK, проверьте его в SDK Manager. Проблема, вероятно, связана с версией плагина уровня Android, аналогично случаю это.
После дальнейших исследований благодаря комментариям Цыварева я нашел решение: я вручную изменил все CMakeCache.txt
файлы в .ExternalNativeBuild
папке.
До :
CMAKE_CXX_STANDARD_LIBRARIES:STRING=-latomic -lm "/Users/homefolder/Library/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a"
Ручное исправление:
CMAKE_CXX_STANDARD_LIBRARIES:STRING=-latomic -lm
Затем автоматически сгенерированные файлы build.ninja больше не содержат ссылки на libgnustl_static.a. И apk компилируется.
Это исправление не делает отправить мне. Я думал, что все файлы в .ExternalNativeBuild
автоматически генерируются и стираются при каждой новой сборке. В самом имени есть cache
, поэтому оно не похоже на файл, который пользователь должен изменить. Тем не менее, это было рабочее решение моей проблемы.
Я считаю, что эти файлы CCMakeCaches.txt
генерируются при первой сборке, а затем повторно используются для следующих запросов на сборку. Мне это очень не логично. Не понимаю, почему set(CMAKE_ANDROID_STL_TYPE none)
не сработало.
And from documentation (1) , it seems like this library can be set up using CMAKE_ANDROID_STL_TYPE. I have put this to 'none' or 'system' in CMakeList.txt, but I see no difference in the build.ninja files.
# CMakeList.txt set(CMAKE_ANDROID_STL_TYPE none)
Неправильная документация. Вы хотите https://developer.android.com/ndk/guides/cmake. Установите следующее значение в файле build.gradle:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=none",
}
}
}
}
Заголовок «Как удалить математическую библиотеку по умолчанию…» не отражает проблемы: проблема полностью связана с
libgnustl_static.a
библиотекой. Не знаю, почему вы выделили-lm
в команде ссылки. Правильное имя используемого вами Переменная — CMAKE_ANDROID_STL_TYPE,ANDROID_STL_TYPE
— это имя имущество, для которогоset()
не работает. Также убедитесь, что выset()
переменную доadd_library
вызываете вCMakeLists.txt
.