Управление файлом Xcode заголовка проекта будет включать
Мой проект Xcode основывается на вариациях одного и того же продукта с использованием двух целей. Разница между ними заключается только в том, какая версия включенной библиотеки используется. Для исходных файлов .c легко назначить правильную версию правильной цели с помощью целевого флажка. Однако, включая заголовочный файл, он всегда включает один и тот же файл. Это правильно для одной цели, но неправильно для другой.
Есть ли способ контролировать, какой заголовочный файл включен каждой целью?
Вот моя иерархия файлов проекта (которая реплицируется в Xcode):
MyProject
TheirOldLib
theirLib.h
theirLib.cpp
TheirNewLib
theirLib.h
theirLib.cpp
myCode.cpp
и myCode.cpp делает такие вещи, как:
#include "theirLib.h"
…
somecode()
{
#if OLDVERSION
theirOldLibCall(…);
#else
theirNewLibCall(…);
#endif
}
И, конечно, я определяю OLDVERSION
для одной цели, а не для другой.
Обратите внимание: #include
должен быть таким, как показано. Оба этих файла не работают с ошибкой файла:
#include "TheirOldLib/theirLib.h"
#include "TheirNewLib/theirLib.h"
Итак, есть способ рассказать Xcode, который theirLib.h
для включения в цель?
Ограничения:
- два заголовочных файла имеют одинаковое имя. В крайнем случае я мог бы переименовать одну из них, но я бы предпочел избежать этого, поскольку это приведет к тому, что крупные волосы потянутся на другие платформы.
- необходимость менять ссылку #include
для добавления ссылки на прилагаемую папку также я бы предпочел избежать, потому что мне нужно будет сделать это дважды с условной компиляционной директивой.
- Я свободен для настройки моего проекта, поскольку я в других отношениях вижу
Спасибо за любую помощь.
Ответы
Ответ 1
Ключевой частью ответа является использование USE_HEADERMAP = NO, как было предложено Крисом в комментарии. Вот подробности.
Короткий рецепт (отмечен в Xcode 3.2.2):
-
добавьте настраиваемую настройку сборки USE_HEADERMAP = NO для каждой целевой цели. Вот как:
1.1. Откройте информационную панель цели на панели "Сборка".
1.2. Выдвиньте всплывающее меню действий в левом нижнем углу окна, выберите "Добавить пользовательскую настройку".
1.3. В новой добавленной строке установите первый столбец ( "Настройка" ) на USE_HEADERMAP
, а второй столбец ( "Значение" ) на NO
.
-
добавить правильный путь включения к каждой цели (целевые параметры сборки "Контуры поиска заголовков" ). В моем примере это будет:
2.1. добавить TheirOldLib
для "старой" цели
2.2. добавить TheirNewLib
для "новой" цели
Шаг 1 отключает функцию автоматической записи заголовка Xcode, через которую любой заголовочный файл, включенный в проект, напрямую доступен через его имя, независимо от его фактического пути. Когда два заголовка имеют одно и то же имя, эта функция приводит к неразрешимой двусмысленности.
Шаг 2 позволяет работать #include "theirLib.h"
без указания имени фактического пути файла заголовка.
Эти два шага вместе выполняют мои два ограничения.
Наконец, USE_HEADERMAP
не документируется Apple, насколько я могу судить. Я напишу отчет об ошибке, так как этот параметр имеет решающее значение в ряде случаев, так как поисковая система раскрывает его. Сообщается как rdar://7840694. Также на открытом радаре http://openradar.appspot.com/radar?id=253401
Ответ 2
USE_HEADERMAP = НЕТ - это избыток для некоторых проектов. Достаточно просто использовать HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT = NO. Документация здесь: https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW159
Ответ 3
Почему вы не можете использовать разные пути включения в каждую цель?
Ответ 4
Используйте USE_HEADERMAP = NO и в поле "Пути поиска по заголовкам пользователей" сначала укажите свой пользовательский каталог, а затем рекурсивно второй каталог проекта: $ {PROJECT_DIR}/ItsNewLib $ {PROJECT_DIR}/**