Пользовательская конфигурация сборки XCode вызывает «библиотека / файл не найден» для статических библиотек - PullRequest
43 голосов
/ 15 декабря 2011

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

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

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

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

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 , поскольку у них нет Ad-Hoc конфигурации сборки.

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

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

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

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

Ответы [ 7 ]

28 голосов
/ 05 февраля 2014

Как сказано в аналогичном вопросе Статическая библиотека iOS как подпроект проекта, имеющего пользовательские конфигурации сборки? , исправление заключается в добавлении этой строки

$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

до Framework Search Paths, Header Search Paths и / или Library Search Paths

вашей цели
20 голосов
/ 15 июня 2012

Вот кое-что, что работает для меня.

В проекте с конфигурацией сборки 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
6 голосов
/ 15 февраля 2013

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

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

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

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

  • Компоновщик будет жаловаться, потому что не может найти библиотеку ... хорошо, давайте разберемся с этим.

  • Добавьте фазу сборки Run Script к mainproject, сразу после фазы Target Dependencies. Введите этот скрипт:

<code>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

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

6 голосов
/ 04 января 2012

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

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

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

4 голосов
/ 23 января 2015

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

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

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

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

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

0 голосов
/ 18 октября 2015

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

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

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

sensitive issue

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

0 голосов
/ 25 мая 2012

Вы можете добавить 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...