Как конвертировать библиотеку C в разные ABI с помощью cmake - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь создать общие библиотеки из библиотеки c_speech_features C для различных Android ABI. Я скачал Android NDK и попытался следовать инструкциям cmake для 'Cross Compiling for Android' , чтобы создать библиотеку .so.

Шаги:

  1. Загруженный исходный код библиотеки

  2. Изменил файл CMakeLists.txt на

    cmake_minimum_required (VERSION 3.6)
    project (c_speech_features)
    include(GNUInstallDirs)
    
    ### I ADDED THESE VARIABLES TO COMPILE FOR ANDROID ###
    set(CMAKE_SYSTEM_NAME Android)
    set(CMAKE_SYSTEM_VERSION 23)
    set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
    set(CMAKE_ANDROID_NDK /path_to/android-ndk-r18b/)  
    
    option (ENABLE_DOUBLE "Enable double-precision floats" OFF)
    if (ENABLE_DOUBLE)
      set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dkiss_fft_scalar=double")
    endif ()
    configure_file ("c_speech_features_config.h.in" "c_speech_features_config.h")
    
    add_library (objlib OBJECT c_speech_features.c kiss_fft130/kiss_fft.c kiss_fft130/tools/kiss_fftr.c)
    set_property (TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
    
    include_directories (kiss_fft130 kiss_fft130/tools)
    
    add_library (c_speech_features SHARED $<TARGET_OBJECTS:objlib>)
    add_library (c_speech_features_static STATIC $<TARGET_OBJECTS:objlib>)
    
  3. открыл исходный каталог в терминале
  4. пробег cmake
  5. пробег make

Однако, независимо от того, что я установил для ANDROID_ARCH_ABI, после запуска cmake, а затем make ABI полученной библиотеки .so всегда будет таким же, как в случае, когда вышеуказанные переменные не установлены в CMakeLists.txt файл. Это результат:

~$ readelf -h libc_speech_features.so | grep 'Class\|File\|Machine'
  Class:                             ELF64
  Machine:                           Advanced Micro Devices X86-64

Я пытался сделать это при новых загрузках хранилища библиотеки, поэтому не думаю, что это проблема с кэшированными файлами CMake.

Можно ли таким способом создать библиотеку .so для различных архитектур ABI? Если да, то как мне изменить свой подход? Если есть какой-то другой способ компиляции библиотек, я также буду рад попробовать. Ниже приведены некоторые другие попытки, которые я предпринял.

Редактировать после комментария Цыварева

Я удалил установленные переменные из файла CMakeLists.txt и сейчас пытаюсь использовать файл цепочки инструментов, выполнив команду

cmake -DCMAKE_TOOLCHAIN_FILE=/path_to/android-ndk-r18b/build/cmake/android.toolchain.cmake \
-DCMAKE_ANDROID_NDK=/path_to/android-ndk-r18b \
-DANDROID_PLATFORM=android-24 -DCMAKE_ANDROID_ARCH_ABI=x86 \
.

Затем я запускаю make, чтобы создать файл .so. Однако теперь результирующий .so lib всегда:

  Class:                             ELF32
  Machine:                           ARM

Я неправильно устанавливаю желаемую архитектуру? Как изменить архитектуру при использовании цепочки инструментов cmake?

Другие попытки

Я видел, что есть ряд других способов включить библиотеку C в приложение Android:

  • Мне не удалось добавить код C напрямую и создать библиотека с использованием Android Studio ( описание документов ), так как я не смог получить доступ к любому из методов. Я уверен, что это возможно таким образом, но теперь понял, как включить и использовать уже существующие .so библиотеки, так что создать их проще.

  • Отдельные наборы инструментов Android NDK Я не понял, как запустить на этой библиотеке C с CMakeLists.txt, который определяет, как библиотека построена

  • Я видел Android-Cmake часто упоминается, и я могу быть глупым здесь, но можно было увидеть, как использовать его из README (его тоже довольно старый поэтому не может быть лучше, чем непосредственно с помощью cmake).

  • Я не думаю, что использование Android.mk легче увидеть, так как у меня есть библиотека с файлом CMakeLists.txt уже и поэтому преобразование кажется нравится больше работы

1 Ответ

0 голосов
/ 30 октября 2018

Я неправильно устанавливаю желаемую архитектуру? Как изменить архитектуру при использовании цепочки инструментов cmake?

Да. К сожалению, и Android, и CMake одновременно добавили поддержку другого, поэтому для этого есть два рабочих процесса, и вы их смешиваете и сопоставляете.

Для лучшей поддержки новых NDK вы хотите использовать встроенную поддержку NDK (файл цепочки инструментов, как вы используете), но вам нужно использовать ANDROID_* переменные, а не CMAKE_ANDROID_* переменные.

См. Документацию по Android для CMake для разбивки доступных флагов: https://developer.android.com/ndk/guides/cmake.

Чтобы исправить ваш конкретный вызов, вы хотите:

$ cmake -DCMAKE_TOOLCHAIN_FILE=/path_to/android-ndk-r18b/build/cmake/android.toolchain.cmake \
      -DANDROID_PLATFORM=android-24 -DANDROID_ABI=x86 \
      .

(очевидно, ANDROID_ABI не указан в первой таблице, поскольку пользователю не нужно беспокоиться об использовании CMake через Gradle, но это описано ниже)

Если вы используете NDK до r18 (это не так, но, возможно, кто-то еще приземлится здесь), на этой странице больше нет нескольких дополнительных флагов (например, ANDROID_TOOLCHAIN). Вверху самого файла набора инструментов есть комментарий, в котором перечислены все опции, которые он поддерживает, если вам нужно пойти по этому пути.

...