Конфигурация пользовательской сборки Xcode вызывает "библиотека/файл не найден" для статических библиотек

У меня есть рабочее пространство с проектом, который связан со статическими библиотеками в другом проекте (который также находится в рабочем пространстве). Это проблема в Kobold2D Мне не удалось решить, хотя я понимаю причину, и я предполагаю, что она похожа на этот вопрос.

Все цели проекта и статические библиотеки имеют конфигурации сборки Debug и Release. Все хорошо.

Теперь кто-то добавляет новую конфигурацию сборки в проект и называет ее, например, Ad-Hoc. Теперь цель проекта создает конфигурацию Ad-Hoc, однако статические библиотеки не имеют такой конфигурации. Очевидно, они тогда по умолчанию строят конфигурацию версии.

В конце, когда компоновщик должен собрать все воедино, происходит сбой:

ld: library not found for -lbox2d-ios
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++ failed with exit code 1

Для принудительно загруженных библиотек через -force_load $(BUILT_PRODUCTS_DIR)/libSomeLib.a ошибка похожа, но говорит "файл не найден". Следует отметить, что библиотека "libbox2d-ios.a" находится в списке фаз сборки "связать двоичные файлы с библиотеками".

Очевидно, что проблема заключается в том, что компоновщик предполагает, что библиотеки находятся в папке Ad-Hoc-iphoneos в папке BUILT_PRODUCTS_DIR, а на самом деле они находятся в папке Release-iphoneos, поскольку у них нет Специальная конфигурация сборки.

Как я могу ударить линкер по лицу и сказать ему, чтобы получить библиотеки, где они находятся? Предпочтительно, я ищу решение, которое работает в обоих случаях, то есть библиотеки добавили стандартный способ (связать двоичный файл с фазой сборки библиотек) и библиотеки, которым для работы требуется дополнительный -force_load.

Я надеюсь, что есть какой-то способ:

  • принудительно помещать библиотеки в папку конфигурации сборки целевого приложения
  • запустить посткомпиляцию & скрипт предварительной ссылки, который копирует каждую библиотеку в папку конфигурации сборки
  • указать относительный путь к библиотекам
  • используйте другой макрос, отличный от $ BUILT_PRODUCTS_DIR для -force_load
  • флаг компоновщика, такой как -WTFmake-all-tasks-go-away

Извините, но я должен сказать это... АРГ! :)

Ответ 1

Я не нашел способ сделать это, к сожалению. Лучшим обходным решением, которое я могу найти, является добавление новых целей, а не новых конфигураций сборки. Так, например, в одном из моих проектов у меня есть только конфигурации Release и Debug, но у меня есть дополнительные цели, называемые "MyProject - store app" и "MyProject - ad hoc". Это будет возможно только в том случае, если у вас есть контроль над файлом проекта, конечно.

Дублирование целых целей крайне раздражает, потому что вы можете добавлять файлы к одной цели и забывать добавлять их к остальным, и вы не узнаете, пока не попытаетесь ее построить. Но он создает, что является победой (с xcode в любом случае).

Аналогичный вопрос, который я задал некоторое время назад: Каков правильный способ установки конфигураций сборки в проекте ios с использованием статических библиотек для создания архива в xcode 4?

Ответ 3

Здесь что-то работает для меня.

В проекте с конфигурацией сборки Adhoc переопределите "путь сборки готовых продуктов" (CONFIGURATION_BUILD_DIR) и "путь к промежуточным файлам для конфигурации конфигурации" (CONFIGURATION_TEMP_DIR) для конфигурации сборки Adhoc, чтобы использовать ту же папку, что и релиз.

Adhoc: CONFIGURATION_BUILD_DIR = $(SYMROOT)/Release$(EFFECTIVE_PLATFORM_NAME)
Adhoc: CONFIGURATION_TEMP_DIR = $(PROJECT_TEMP_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

Теперь, когда вы создаете Adhoc, Xcode поместит libFoo.a и Bar.app в папку Release-iphoneos. Компонент будет счастлив, и вы можете использовать -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a, как обычно.

В качестве альтернативы вы можете добавить папку Release-iphoneos в пути поиска библиотеки для конфигурации сборки Adhoc:

Adhoc: LIBRARY_SEARCH_PATHS = $(inherited) $(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

Но тогда вам придется установить для каждой конфигурации сборки другую -force_load:

Debug: OTHER_LINKER_FLAGS = $(inherited) -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a
Adhoc: OTHER_LINKER_FLAGS = $(inherited) -force_load $(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)
Release: OTHER_LINKER_FLAGS = $(inherited) -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a

Ответ 4

У меня есть аналогичная проблема с использованием CocoaPods и попытка иметь несколько конфигураций Adhoc (или Enterprise или Beta).

Вот что работает (пусть говорят, что оба проекта лежат в одном и том же пространстве xcworks):

  • Добавьте subproject сгенерированную библиотеку в mainproject Link Binary с библиотеками.

  • Поскольку конфигурация Adhoc не известна subproject, Xcode будет использовать конфигурацию Release как резервную (или, возможно, первую конфигурацию списка) при ее создании.

  • Компилятор будет жаловаться, потому что он не может найти lib... ok, пусть обрабатывает этот.

  • Добавьте фазу сборки Script в mainproject сразу после фазы "Зависимые зависимости". Введите script:

if [ "$CONFIGURATION" = "Adhoc" ]; then
    echo "====================================="
    echo "Copying libPods Release into the Adhoc product build dir!"
    echo "====================================="
    cp "$BUILT_PRODUCTS_DIR/../Release-$PLATFORM_NAME/libPods.a" "$BUILT_PRODUCTS_DIR"
else
    echo "No manual lib copy."
fi

Это скопирует lib, сгенерированный конструкцией subproject Release (которая будет выполняться при построении mainproject) в каталоге сборки Adhoc, так что компоновщик найдет lib. И мы должны быть хорошими! Да!

Ответ 5

Мои рамки построены с использованием другого проекта SDK внутри моего проекта приложения. Сначала у меня есть "Debug" и "Release", затем я добавляю новую конфигурацию "TestFlight" . Я не могу архивировать с этим новым. Я закончил добавление новой конфигурации сборки с тем же именем в проект SDK. Другими словами, я включил конфигурацию "TestFlight" в ОСОБЫЕ проекты моего приложения и SDK. Теперь Архив работает.

Я не уверен, что это лучший способ сделать это. Но для меня это выглядит достаточно чистым.:)

О, а для Cocoapods, после дублирования конфигурации, если вы запустите pod install сразу, вы получите это желтое предупреждение:

[!] CocoaPods не установили базовую конфигурацию вашего проекта, потому что у вашего проекта уже есть собственный набор настроек. Чтобы интеграция CocoaPods вообще работала, пожалуйста, либо установите базовые конфигурации цели...

Вам нужно перейти на вкладку "Информация", "Конфигурации", выбрать новую конфигурацию, которую вы только что создали, и установить "Pods.release" всех целей на "Нет" первый. После этого вы можете безопасно запустить pod install.

Ответ 6

Вы можете добавить CONFIGURATION_BUILD_DIR =/Some/Shared/Dir перед запуском xcodebuild. Например:

cd SOURCE_DIR
xcodebuild  -workspace YourProject.xcworkspace -scheme YourScheme -configuration AdHoc -sdk iphoneos clean build CONFIGURATION_BUILD_DIR="`pwd`"/build

Ответ 7

Обычно у меня есть схема AppStore (сопоставлена ​​с моей конфигурацией AppStore).

Одна вещь, которая произошла со мной, была причиной этой проблемы, которая делала Cocoapods для создания папки сборки для Pods.build внутри Release-iphonesimulator (в качестве резервной копии) вместо AppStore-iphonesimulator.

Я предполагаю, что я пропустил клик, когда связал схему и конфигурацию, и только ее удаление и повторное добавление заставило меня понять, что пошло не так. Проверьте diff.

конфиденциальная проблема

Я использовал cocoapods 0.38.2, так что это была явно неправильная конфигурация пользователя, а не Проблема с Cocoapods, которая была разрешена на 0.34

Ответ 8

Это ошибка времени перед компиляцией для Library или Framework

Вы столкнулись с этой проблемой, потому что XCode не может найти местоположение общедоступных заголовков, просто сообщите XCode, где они находятся, добавив правильный путь.

Вы можете получить Module not found, когда:

  • вы не указали путь к библиотеке Build Settings -> Header Search Paths
  • вы не указали путь к Build Settings -> Framework Search Paths