- PVSM.RU - https://www.pvsm.ru -
Семейство языков Си/Objective C/C++ нуждается в препроцессоре. Препроцессор пропускает компилируемый исходник через себя, прежде чем отдать текст на вход компилятору. Пожалуй самая важная часть работы препроцессора заключается в подстановке на место директив #include<имя-файла> содержимого указанного файла. Обычно указывают относительный путь (ex: stdio.h, sys/stat.h). Возникает закономерный вопрос — как препроцессор находит заголовочные файлы?
Классический ответ такой: препроцессор последовательно перебирает пути в INCLUDE_PATH начиная с первого. Относительный путь из директивы include разрешается относительно (sic) папки из INCLUDE_PATH. Если файл не найден, переходим к следующему элементу INCLUDE_PATH. Если INCLUDE_PATH исчерпан, компилятор сообщает об ошибке.
Но Apple как всегда вносит свои коррективы. При сборке в XCode дополнительно используются т.н. header map. Это индекс всех заголовочных файлов в проекте. Если XCode «знает» про foobar.h, то данный файл будет доступен просто по имени (#include<foobar.h>), вне зависимости от фактического размещения на файловой системе.
Это прекрасное решение — до тех пор, пока оно работает как задумано. К сожалению, механизм header map плохо документирован, что не способствует быстрому разрешению проблем. Постараюсь восполнить этот пробел.
определение
Header Map представляет собой индексный файл, генерируемый XCode. Файл называется по имени текущей target и имеет расширение «.hmap». Индекс представляет собой множество строковых пар ключ—значение. Индекс используется для сопоставления полного пути к заголовочному файлу по аргументу директивыinclude. Поиск в индексе не чувствителен к регистру. Поиск в индексе имеет больший приоритет по сравнению с INCLUDE_PATH. Это сделано для ускорения сборки.По умолчанию header map активна. Для отключения нужно создать переменную
USE_HEADERMAP=NOв конфигурации проекта.
А что если в проекте используются несколько заголовочных файлов с одинаковыми именами? С настройками по умолчанию, в индекс попадет только один из этих файлов — какой именно, предсказать невозможно. Та же самая проблема возникает при совпадении имени файла в проекте с системным заголовочным файлом, без учета регистра (ex: Time.h).
Для диагностики бывает полезно заглянуть в сгенерированный header map. Это бинарный файл причем с замороченной оптимизацией общих подстрок. Хорошо, что добрые люди написали программу [1] для конвертации в текстовый формат.
python headermap.py build/hmap.build/Debug/primary.build/primary.hmap
Здесь primary — имя цели.
bar.h /Users/nickz/hmap/bar.h
foo.h /Users/nickz/hmap/foo.h
primary/foo.h /Users/nickz/hmap/foo.h
Если с foo.h и bar.h все более-менее понятно, то primary/foo.h вызывает вопросы. Как выяснилось, XCode создает такие записи для заголовочных файлов, являющихся членами текущей цели. (Для того, чтобы XCode позволил сделать заголовочным файлам членство в цели, нужно добавить в нее copy headers build phase.)
В качестве префикса используется PRODUCT_NAME, причем если его поменять, в header map по-прежнему будет попадать старый префикс (проявляется на 3.2.5, возможно исправлено в новых версиях). Лечится закрытием–открытием проекта.
USE_HEADERMAP = [YES]/NO
Вкл/выкл.
HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT = [YES]/NO
Включать в header map заголовочные файлы, которые являются членами активной цели. На 3.2.5 игнорируется.
HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = [YES]/NO
Включать в header map заголовочные файлы, которые являются членами активной цели. Файлы получают префикс $(PRODUCT_NAME)/. Если значение настройки —YES, такие записи создаются для любых типов целей; иначе только если тип цели — Framework.
HEADERMAP_INCLUDES_PROJECT_HEADERS = [YES]/NO
Включать в header map все заголовочные файлы из проекта без учета целей. На 3.2.5 игнорируется.
Автор: mejedi
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/8537
Ссылки в тексте:
[1] программу: http://opensource.apple.com/source/distcc/distcc-2503/distcc_dist/include_server/headermap.py
[2] Полный список настроек: http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html
Нажмите здесь для печати.