Visual Studio Android встраивает файлы сборки в приложение

У нас есть решение Visual Studio Android с (среди прочего) проектом статической библиотеки, которая содержит функциональные возможности, реализованные в сборке. Подобно:

my.S -> libMine.a -> libMyApp.so

Некоторые обручи (ниже) уже были перепрыгнуты, чтобы получить его для компиляции. Затем происходит сбой связывания проекта общей библиотеки приложения (на обеих архитектурах, которые нас интересуют - x64 и arm64), с неопределенными ссылками на функции, которые реализованы в [the] assembly [file].

Похоже, что Visual Studio (или ее подключаемый модуль Cross Platform Mobile Dev / Android) не обрабатывает элементы проекта файла сборки достаточно корректно - рассматривается как файлы компилятора C/C++, он выдает ошибку в первом символе точки (т.е. в .text); и Microsoft Macro Assembler "не поддерживается на этой платформе". Поэтому я посмотрел на настройку пользовательского шага сборки с помощью следующей команды:

$(ClangToolExe) %(FullPath) --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o

Это будет предварительной обработкой, компиляцией и связыванием, но с неправильным компоновщиком: вместо того, что используется для конкретного набора инструментов Android, он пойдет для того, что в моей установке MinGW, который не распознает режим эмуляции - в любом случае, это не расположение моего набора инструментов NDK.

Мы можем пока пропустить связывание объекта (добавить -c на вышеуказанную команду). К нашему большому разочарованию, результирующий объектный файл все еще не добавляется в статическую библиотеку, что подтверждается {Rest of the toolchain path}ar t libMine.a, И действительно, библиотека будет иметь неопределенные символы для наших функций, как показано {Rest of the toolchain path}objdump -t libMine.a,

Давайте добавим объектный файл в результирующую библиотеку вручную, в качестве шага после сборки. Команда:

$(ToolChainPrebuiltPath){Rest of the toolchain path}ar.exe ru $(TargetPath) $(IntDir)my.o

objdump -t libMine.a теперь покажет, что у нас есть символы. Однако существует также определенная пара *UND*.

Перемотка вперед:

  • Добавление my.o с ar rub otherObjectThatReferencesMyFunctions.o libMine.a, чтобы хорошие символы отображались до того, как неопределенные не будут иметь значения.
  • Связывание моего скомпилированного файла сборки со вторым пользовательским шагом сборки, $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o не имеет существенного значения.
  • Повторный запуск компоновщика в статической библиотеке, как второй шаг после сборки $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath) не имеет существенного значения.
  • Последние два шага приводят к предупреждению о пропущенном символе _start (точка входа?). Я предполагаю, что это связано со связыванием исполняемого файла, который нам не нужен.

Что я делаю неправильно? Как я могу разрешить эти неопределенные ссылки?

1 ответ

Решение

То, что, кажется, сработало, было:

1, убедитесь, что расширение файла сборки .S, т. е. заглавная S. Это один из немногих случаев, которые я обнаружил, когда регистр имени файла имеет значение для Windows.

2. Настройте проект так, чтобы файл сборки был создан с clang.exe {full/path/to/assembly.S, i.e. %(FullPath)} -c --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o, В случае VS Android, мы должны указать выходные данные сборки отдельно, то есть $(IntDir)%(FileName).o расстаться снова и снова.

3, запустить ar как команда пост-сборки: {correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}, для каждого файла сборки.

Единственное, чего не хватает этому решению, - это обнаружению [отсутствия] изменений, что означает, что файл сборки будет перестраиваться при каждой компиляции, а также все, что от него зависит.

Другие вопросы по тегам