Компиляция кода в OS X
Теперь, когда Вы имеете в распоряжении основные части, пора создать Ваше приложение. Этот раздел охватывает некоторые из большего количества общих проблем, с которыми можно встретиться в подаче приложения UNIX к OS X. Эти проблемы применяются в основном вне зависимости от того, какую разработку Вы делаете.
Используя GNU Autoconf, автосделайте, и автозаголовок
Если Вы приносите существующую ранее утилиту командной строки к OS X, использующему GNU autoconf
, automake
, или autoheader
, Вы, вероятно, найдете, что это конфигурирует себя без модификации (хотя получающаяся конфигурация может быть недостаточной). Просто выполненный configure
и make
поскольку Вы были бы в любой другой основанной на UNIX системе.
При выполнении configure
сценарий перестал работать, потому что он не понимает архитектуру, попытайтесь заменить проект config.sub
и config.guess
файлы с доступными в /usr/share/automake-1.6
. Если Вы распределяете приложения, использующие autoconf, необходимо включать актуальную версию config.sub
и config.guess
так, чтобы пользователи OS X не делали ничего дополнительного для разрабатывания проекта.
Если это все еще перестало работать, Вы, возможно, должны работать /usr/bin/autoconf
на Вашем проекте восстановить configure
сценарий, прежде чем это будет работать. OS X включает autoconf в пакет инструментов BSD. Вне этих основ, если проект не создает, Вы, возможно, должны изменить свой make-файл с помощью некоторых подсказок, предоставленных в следующих разделах. После того, как Вы сделаете это, более обширный рефакторинг может требоваться.
Некоторые программы могут использовать autoconf макросы, которые не поддерживаются версией autoconf, поставившего с OS X. Поскольку autoconf периодически изменяется, Вы, возможно, фактически должны получить новую версию autoconf, если необходимо создать очень последние источники для некоторых проектов. В целом большинство проектов включает предварительно созданный configure
сценарий с выпусками, таким образом, это обычно не необходимо, если Вы не разрабатываете проект с открытым исходным кодом с помощью источников, полученных из CVS или из ежедневного исходного снимка.
Однако при нахождении необходимым обновить autoconf можно получить текущую версию от http://www .gnu.org/software/autoconf/. Обратите внимание на то, что autoconf, по умолчанию, устанавливает в /usr/local/
, таким образом, Вы, возможно, должны изменить Ваш PATH
переменная окружения для использования недавно обновленной версии. Не пытайтесь заменить версию, установленную в /usr/
.
Для получения дополнительной информации об использовании автокомплекта инструментальных средств GNU посмотрите http://autotoolset .sourceforge.net/tutorial.html и страницы руководства autoconf
, automake
, и autoheader
.
Компиляция для многократных архитектур ЦП
Поскольку платформа Macintosh включает больше чем одно семейство процессоров, часто важно скомпилировать программное обеспечение для многократных архитектур процессора. Например, библиотеки должны обычно компилироваться как универсальные двоичные файлы даже при монопольном предназначении для основанного на Intel компьютера Macintosh поскольку библиотекой может пользоваться двоичный файл PowerPC, работающий при Розетте. Для исполнимых программ, если Вы планируете распределить скомпилированные версии, необходимо обычно создавать универсальные двоичные файлы для удобства.
При компиляции программ для архитектуры кроме архитектуры узла по умолчанию, такой как компиляция для ppc64 или основанной на Intel цели Macintosh на основанном на PowerPC узле сборки, существует несколько типичных проблем, с которыми можно столкнуться. Большинство этих проблем следует из одной из следующих ошибок:
Предположение, что узел сборки архитектурно подобен целевой архитектуре и таким образом будет способен к выполнению промежуточных продуктов сборки
Попытка определить целевой процессор определенная информация во время конфигурации (путем компиляции и выполнения маленьких фрагментов кода), а не во время компиляции (использующий макро-тесты) или время выполнения (например, при помощи условного байта подкачивают функции),
Каждый раз, когда кросс-компиляция происходит, дополнительную заботу нужно соблюдать, чтобы гарантировать, что целевая архитектура обнаруживается правильно. Это - особенно проблема при генерации двоичного, содержащего объектный код больше чем для одной архитектуры.
Во многих случаях двоичные файлы, содержащие объектный код больше чем для одной архитектуры, могут быть сгенерированы просто путем выполнения нормального сценария конфигурации, затем переопределения флагов архитектуры во время компиляции.
Например, Вы могли бы работать
./configure |
сопровождаемый
make CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc \ |
-arch i386" LDFLAGS="-syslibroot /Developer/SDKs/MacOSX10.4u.sdk \ |
-arch ppc -arch i386" |
генерировать универсальный двоичный файл (для основанных на Intel и основанных на PowerPC компьютеров Macintosh). Для генерации универсального двоичного файла с 4 путями, включающего 64-разрядные версии Вы добавили бы -arch ppc64
и -arch x86_64
к CFLAGS
и LDFLAGS
.
Однако приложения, принимающие разовые конфигурацией решения относительно размера структур данных, обычно не создадут правильно в такой среде (так как те размеры, возможно, должны отличаться в зависимости от того, выполняет ли компилятор a ppc
передача, a ppc64
передача, или i386
передача). Когда это происходит, инструмент должен быть сконфигурирован и скомпилирован для каждой архитектуры как отдельные исполнимые программы, затем склеил вручную использование lipo
.
В редких случаях программное обеспечение, не записанное с кросс-компиляцией в памяти, сделает, конфигурируют разовые решения путем выполнения кода узла сборки. В этих случаях необходимо будет вручную изменить или сценарии конфигурации или получающиеся заголовки, чтобы быть подходящими для фактической целевой архитектуры (а не архитектура сборки). В некоторых случаях это может быть решено путем сообщения сконфигурировать сценарию, что Вы кросс-компилируете использование --host
, --build
, и --target
флаги. Однако это может просто привести к значениям по умолчанию для вставляемой целевой платформы, который действительно не решает проблему.
Лучшая фиксация должна заменить, конфигурируют разовое обнаружение порядка байтов, размеров типа данных, и т.д. со временем компиляции или обнаружением во время выполнения. Например, вместо того, чтобы тестировать архитектуру на порядок байтов для получения непротиворечивого порядка байтов в файле необходимо выполнить одно из следующих действий:
Используйте макросы препроцессора C как
__BIG_ENDIAN__
и__LITTLE_ENDIAN__
протестировать порядок байтов во время компиляции.Используйте функции как
htonl
,htons
,ntohl
, иntohs
гарантировать представление с обратным порядком байтов на любой архитектуре.Извлеките отдельные байты поразрядным маскированием и смещением (например,
lowbyte=word & 0xff; nextbyte = (word >> 8) & 0xff;
и т.д.).
Точно так же вместо того, чтобы выполнить тщательно продуманные тесты, чтобы определить, использовать ли int
или long
для 4-байтовой части данных необходимо просто использовать тип стандартного размера такой как uint32_t
.
Существует несколько других протестов при работе с универсальными двоичными файлами:
Утилита архива библиотеки,
ar
, не может работать с библиотеками, содержащими код больше чем для одной архитектуры (или библиотеки единой архитектуры, сгенерированные сlipo
) после того, как ranlib добавил оглавление к ним. Таким образом, если необходимо добавить дополнительные объектные файлы к библиотеке, необходимо сохранить отдельную копию без TOC.-M
переключитесь на gcc (для вывода информации о зависимостях), не поддерживается, когда многократная архитектура указана на командной строке. В зависимости от Вашего make-файла это может потребовать существенных изменений к Вашим правилам make-файла. Поскольку находящиеся в autoconf конфигурируют сценарии, флаг--disable-dependency-tracking
должен решить эту проблему.Для проектов использование автоделает, может быть необходимо работать, автоделают с
-i
флаг, чтобы отключить проверки зависимости или поместитьno-dependencies
вAUTOMAKE_OPTIONS
переменная в каждом файле Makefile.am.При столкновении с проблемами, создающими универсальный двоичный файл для инструмента с открытым исходным кодом первая вещь, которую необходимо сделать, состоит в том, чтобы получить последнюю версию исходного кода. Это делает две вещи:
Гарантирует, чтобы версия autoconf и автосделала используемыми для генерации сценариев конфигурации, является довольно текущим, сокращая вероятность отказов сборки, отказов выполнения, назад или проблем прямой совместимости и другого особенного или прямого поврежденного поведения.
Сокращает вероятность создания версии инструмента с открытым исходным кодом, содержащего известные дыры в системе безопасности или другие серьезные ошибки.
Более старые версии autoconf не обрабатывают случай где
--target
,--host
, и--build
не обрабатываются корректно. Различные версии также ведут себя по-другому при указании только одного или двух из этих флагов. Таким образом необходимо всегда указывать все три из этих опций, если Вы работаете, autoconf-сгенерированный конфигурируют сценарий с намерением кросс-скомпилировать.Некоторые более ранние версии дескриптора autoconf, кросс-компилирующего плохо. Если Ваш инструмент содержит сконфигурировать сценарий, сгенерированный ранним autoconf, можно быть в состоянии значительно улучшить вещи путем замены части из
config.*
файлы (иconfig.guess
в частности) с обновленными копиями от версии autoconf, идущего с OS X.Это будет не всегда работать, однако, когда может быть необходимо фактически регенерировать сконфигурировать сценарий рабочей автоконференцией, Чтобы сделать это, просто измениться в корневой каталог проекта и работать
/usr/bin/autoconf
. Это будет автоматически обнаруживать и использоватьconfigure.in
файл и использование это для генерации нового конфигурирует сценарий. Если Вы получаете предупреждения, необходимо сначала попробовать веб-поиск сообщения об ошибке, поскольку кто-то еще, возможно, уже столкнулся с проблемой (возможно на различном инструменте) и нашел решение.Если Вы получаете ошибки о без вести пропавших
AC_
макросы, Вы, возможно, должны загрузить копию библиотек, от которых Ваш инструмент зависит и копия их.m4
конфигурационные файлы autoconf в/usr/share/autoconf
. Поочередно, можно добавить макросы к файлуacinclude.m4
в основном каталоге и autoconf Вашего проекта должен автоматически забрать тех макросы.Вы, возможно, в некоторых случаях, должны повторно выполниться
automake
и/илиautoheader
если Ваш инструмент использует их. Будьте подготовлены столкнуться с без вести пропавшимиAM_
иAH_
макросы, если Вы делаете, как бы то ни было. Если выполнение autoconf отдельно не исправляет проблему сборки, из-за добавленного риска недостающих макросов это должно обычно только быть сделано.Различные make-файлы и конфигурируют переопределения командной строки дескриптора сценариев по-разному. Самый непротиворечивый способ вызвать эти переопределения состоит в том, чтобы указать их до команды. Например:
make CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
должен обычно приводить к вышеупомянутому, добавляемому к
CFLAGS
во время компиляции. Однако это поведение не является абсолютно непротиворечивым через make-файлы из различных проектов.
Для получения дополнительной информации о autoconf автосделайте, и автозаголовок, можно просмотреть autoconf документацию в http://www .gnu.org/software/autoconf/manual/index.html.
Поскольку дополнительная информация о компиляторе отмечает для основанных на Intel компьютеров Macintosh, изменяя код для поддержки CPUs с прямым порядком байтов и других проблем портирования, необходимо считать Универсальные Двоичные Инструкции по Программированию, Второй Выпуск, доступный от Ссылочной Библиотеки ADC.
Кросс-компиляция инструмента самоначальной загрузки
Вероятно, самая трудная ситуация, которую можно испытать, является ситуацией инструмента самоначальной загрузки — инструмент, использующий (возможно упрощенный) копия себя, чтобы или скомпилировать окончательную версию себя или создать файлы поддержки или библиотеки. Некоторые примеры включают TeX, Perl и gcc.
Идеально, необходимо быть в состоянии создать исполнимую программу как универсальный двоичный файл в единственной передаче сборки. Если это возможно, все “просто работает”, так как универсальный двоичный файл может выполниться на узле. Однако это не всегда возможно. Если необходимо кросс-скомпилировать и склеить части с lipo
, это, очевидно, не будет работать.
Если система сборки будет записана хорошо, то инструмент загрузит себя путем создания версии, скомпилированной для узла, затем использовать это, чтобы создать части для цели, и наконец скомпилировать версию двоичного файла для цели. В этом случае Вам не придется сделать ничего специального для сборки для следования.
В некоторых случаях, однако, не возможно одновременно скомпилировать для многократной архитектуры, и система сборки не была разработана для кросс-компиляции. В тех случаях рекомендуемое решение должно предварительно установить версию инструмента для архитектуры узла, затем изменить сценарии сборки, чтобы переименовать промежуточную копию цели инструмента и скопировать копию узла вместо того промежуточного продукта сборки (например, mv miniperl miniperl-target; cp /usr/bin/perl miniperl
).
Путем выполнения этого более поздние части сценария сборки выполнят версию инструмента, созданного для архитектуры узла. Принятие там не является никакими зависимостями от архитектуры в зависимых инструментах или файлах поддержки, они должны создать правильно использование копии узла инструмента. Как только зависимая сборка завершена, необходимо подкачать назад в исходной целевой копии в заключительной фазе сборки. Прием находится в выяснении, когда иметь в распоряжении каждую копию.
Условная компиляция на OS X
Вы будете иногда считать необходимым использовать условную компиляцию, чтобы заставить Ваш код вести себя по-другому в зависимости от того, доступна ли определенная функциональность.
Более старый код иногда использовал условные операторы как #ifdef __MACH__
или #ifdef __APPLE__
попытаться определить, компилировалось ли это на OS X или нет. В то время как это кажется обращением как быстрым способом быть портированным, оно в конечном счете вызывает больше работы в конечном счете. Например, при создании предположения, что определенная функция не существует в OS X и условно заменяет его собственной версией, реализующей ту же функциональность как обертка вокруг различного API, приложение больше может не компилировать или может быть менее эффективным, если Apple добавляет что функция в более поздней версии.
Кроме отображения или использования имени OS по некоторым причинам (который можно более переносимо получить из uname
API), код никогда не должен вести себя по-другому на OS X просто, потому что это работает на OS X. Код должен вести себя по-другому, потому что OS X ведет себя по-другому в некотором роде — предложение дополнительной функции, не предложение функциональности, определенной для другой операционной системы, и т.д. Таким образом, для максимальной мобильности и пригодности для обслуживания, необходимо фокусироваться на том различии и сделать условную компиляцию зависящей от обнаружения различия, а не зависящий от OS самого. Это не только упрощает поддерживать Ваш код, как OS X развивается, но также и упрощает портировать Ваш код на другие платформы, которые могут поддерживать различные но перекрывающиеся наборы функций.
Наиболее распространенными причинами Вы могли бы хотеть использовать такие условные операторы, являются попытки обнаружить различия в:
архитектура процессора
порядок байтов
чувствительность к регистру файловой системы
другие свойства файловой системы
компилятор, компоновщик или различия в наборе инструментальных средств
доступность сред разработки приложения
доступность заголовочных файлов
поддержка функции или функции
Вместо этого лучше выяснить, почему Ваш код должен вести себя по-другому в OS X, затем используйте методы условной компиляции, которые являются подходящими для фактической первопричины.
Неправильное использование этих условных выражений часто вызывает проблемы. Например, если Вы предполагаете, что определенные платформы присутствуют, если те, которые определяются макросы, Вы могли бы получить отказы компиляции при создании 64-разрядной исполнимой программы. Если Вы вместо этого тестируете на доступность платформы, Вы могли бы быть в состоянии возвратиться к альтернативному механизму, такому как X11, или Вы могли бы пропустить создание графических частей приложения полностью.
Например, OS X обеспечивает макросы препроцессора для определения архитектуры ЦП и порядка байтов. Они включают:
__i386__
— (32-разрядный) Intel__x86_64__
— (64-разрядный) Intel__ppc__
— (32-разрядный) PowerPC__ppc64__
— (64-разрядный) PowerPC__BIG_ENDIAN__
— CPU с обратным порядком байтов__LITTLE_ENDIAN__
— CPU с прямым порядком байтов__LP64__
— LP64 (64-разрядная) модель данных
Кроме того, использование инструментов как autoconf
, можно создать произвольную условную компиляцию на почти любой практической функции установки от тестирования, чтобы видеть, существует ли файл к наблюдению, если можно успешно скомпилировать часть кода.
Например, если часть Вашего проекта требует определенной среды разработки приложения, можно скомпилировать маленькую тестовую программу чей main
вызовы функции функция в той платформе. Если тестовая программа компилирует и соединяется успешно, среда разработки приложения присутствует для указанной архитектуры ЦП.
Можно даже использовать этот метод, чтобы определить, включать ли обходные решения для известных ошибок в Apple или сторонних библиотеках и платформах, или путем тестирования версий тех платформ или путем обеспечения тестового сценария, воспроизводящего ошибку и проверку результатов.
Например, в OS X, poll
не поддерживает файлы устройств такой как /dev/tty
. Если Вы просто избегаете poll
если Ваш код работает на OS X, Вы делаете два предположения, что Вы не должны делать:
Вы предполагаете, что то, что Вы делаете, будет всегда не поддерживаться. OS X является развивающейся операционной системой, добавляющей новые опции регулярно, таким образом, это - не обязательно допустимое предположение.
Вы предполагаете, что OS X является единственной платформой, не поддерживающей использование
poll
на файлах устройств. В то время как это - вероятно, истина для большинства файлов устройств, не вся поддержка файлов устройствpoll
во всех операционных системах, таким образом, это - также не обязательно допустимое предположение.
Лучшее решение состоит в том, чтобы использовать разовый конфигурацией тест, пытающийся использовать poll
на файле устройств, и если вызов сбои, отключает использование poll
. При использовании poll
обеспечивает некоторое значительное преимущество, может быть лучше выполнить тест во время выполнения рано в Вашем выполнении приложений, затем использовать poll
только если успешно выполняется тот тест. Путем тестирования на поддержку во время выполнения приложение может использовать poll
API, если поддерживается определенной версией какой-либо операционной системы, отступая корректно, если она не поддерживается.
Хорошее правило состоит в том, чтобы всегда тестировать на самую определенную вещь, которая, как гарантируют, удовлетворит Ваши требования. Если Вы нуждаетесь в платформе, тестируете на платформу. Если Вы нуждаетесь в библиотеке, тестируете на библиотеку. Если Вы нуждаетесь в определенной версии компилятора, тестируете версию компилятора. И т.д. Путем выполнения этого Вы увеличиваете свои возможности, что Ваше приложение будет продолжать работать правильно без модификации в будущем.
Выбор компилятора
OS X поставляет два компилятора и их соответствующие наборы инструментальных средств. Компилятор по умолчанию основывается на GCC 4.2. Кроме того, компилятор на основе GCC 4.0 предоставлен. Более старые версии XCode также обеспечивают предыдущие версии. Компиляция для 64-разрядного PowerPC и основанных на Intel компьютеров Macintosh только поддерживается в версии 4.0 и позже. Компиляция 64-разрядных расширений ядра только поддерживается в версии 4.2 и позже.
Всегда пытайтесь скомпилировать свое программное обеспечение с помощью GCC 4, потому что будущие наборы инструментальных средств будут основываться на версии 4 GCC или позже. Однако, потому что GCC 4 является относительно новым набором инструментальных средств, можно найти ошибки, предотвращающие определенные программы компиляции.
Использование устаревшего GCC, набору инструментальных средств на основе 2.95.2 строго обескураживают, если Вы не должны поддерживать совместимость с версией 10.1 OS X.
Если Вы сталкиваетесь с проблемой, которая похожа на ошибку компилятора, попытайтесь использовать различную версию GCC. Можно выполнить различную версию путем установки CC
переменная окружения в Вашем Make-файле. Например, CC=gcc-4.0
выбирает GCC 4.0. В XCode можно изменить параметр компилятора на основе на проект или основании на файл путем выбора различной версии компилятора в соответствующем инспекторе настроек сборки.
Установка флагов компилятора
Когда разрабатывание Ваших проектов в OS X, просто предоставление или изменение флагов компилятора нескольких ключевых опций являются всем, что необходимо сделать для портирования большинства программ. Они обычно указываются любым CFLAGS
или LDFLAGS
переменная в Вашем make-файле, в зависимости от которого часть цепочки компилятора интерпретирует флаги. Если не указано иное необходимо добавить эти флаги к CFLAGS
в случае необходимости.
Некоторые общие флаги включают:
-flat_namespace
(вLDFLAGS
)Изменения от двухуровневого до одноуровневого (плоского) пространства имен. По умолчанию OS X создает библиотеки и приложения с двухуровневым пространством имен, где ссылки на динамические библиотеки разрешены к определению в определенной динамической библиотеке, когда создается изображение. Использованию этого флага обычно обескураживают, но в некоторых случаях, неизбежно. Для получения дополнительной информации посмотрите Понимающие Двухуровневые Пространства имен.
-bundle
(вLDFLAGS
)Производит Мужественный файл формата пакета, использующийся для создания загружаемых плагинов. Посмотрите
ld
страница справочника для большего количества обсуждения этого флага.-bundle_loader
исполнимая программа (вLDFLAGS
)Указывает, какая исполнимая программа загрузит плагин. Неопределенные символы в том пакете проверяются по указанной исполнимой программе, как будто это была другая динамическая библиотека, таким образом гарантируя, что пакет фактически будет загружаемым без отсутствующих символов.
-framework
платформа (вLDFLAGS
)Соединяет исполнимую программу, создаваемую против перечисленной платформы. Например, Вы могли бы добавить - платформа vecLib для включения поддержки векторной математики.
-mmacosx-version-min
версияУказывает версию OS X, для которого Вы предназначаетесь. Необходимо предназначаться компиляции для самой старой версии OS X, на котором Вы хотите выполнить исполнимую программу. Кроме того, необходимо установить и использовать кросс-разработку SDK для той версии OS X. Для получения дополнительной информации посмотрите Руководство по совместимости SDK.
Примечание: OS X также использует это значение для определения поведения соответствия UNIX некоторого APIs. Для получения дополнительной информации читайте информацию о версии Unix 03 Соответствия.
Более обширное обсуждение для компилятора в целом может быть найдено в http://developer.apple.com/releasenotes/DeveloperTools/.
Понимание двухуровневых пространств имен
По умолчанию OS X создает библиотеки и приложения с двухуровневым пространством имен. В двухуровневой среде пространства имен при компиляции новой динамической библиотеки любые ссылки, которые библиотека могла бы сделать на другие динамические библиотеки, разрешены к определению в тех определенных динамических библиотеках.
Двухуровневый проект пространства имен имеет много преимуществ для приложений Углерода. Однако это может вызвать проблемы для многих традиционных приложений UNIX, если они были разработаны для работы в плоской среде пространства имен.
Например, предположите одну библиотеку, вызовите ее libfoo
, пользуется другой библиотекой, libbar
, для его реализации функции barIt
. Теперь предположите, что приложение хочет переопределить использование libbar
со сжатой версией, вызванной libzbar
. С тех пор libfoo
был соединен против libbar
во время компиляции это не возможно без перекомпиляции libfoo
.
Позволить приложению переопределять ссылки, сделанные libfoo
к libbar
, Вы использовали бы флаг -flat_namespace
. ld
страница справочника имеет более детальное обсуждение этого флага.
Если Вы пишете библиотеки с нуля, это может быть достойно рассмотрения двухуровневая проблема пространства имен в Вашем проекте. Если Вы ожидаете, что кто-то может хотеть переопределить использование Вашей библиотекой другой библиотеки, у Вас могла бы быть подпрограмма инициализатора, берущая указатели на вторую библиотеку как ее параметры, и затем используйте те указатели для вызовов вместо того, чтобы вызвать вторую библиотеку непосредственно.
Поочередно, Вы могли бы использовать сменную архитектуру, в которой вызовы к внешней библиотеке выполняются от плагина, который мог быть легко заменен различным плагином для различной внешней библиотеки. Посмотрите Динамические Библиотеки и Плагины для получения дополнительной информации.
По большей части, однако, если Вы не разрабатываете библиотеку с нуля, это не практично для избегания использования -flat_namespace
если необходимо переопределить ссылки библиотеки на другую библиотеку.
При компиляции исполнимой программы (в противоположность библиотеке), можно также использовать -force_flat_namespace
сказать dyld
использовать плоское пространство имен при загрузке любых динамических библиотек и пакетов, загруженных двоичным файлом. Это обычно не необходимо, как бы то ни было.
Формат исполняемых файлов
Единственный формат исполняемых файлов, который понимает ядро OS X, является Мужественным форматом. Некоторые инструменты образования моста предоставлены для классических форматов исполняемых файлов Macintosh, но Мужественный собственный формат. Это очень отличается от обычно используемой Исполнимой программы и Соединения Формата (ELF). Для получения дополнительной информации о Мужественном посмотрите OS X ABI Мужественная Ссылка Формата файла.
Динамические библиотеки и плагины
Динамические библиотеки и плагины ведут себя по-другому в OS X, чем в других операционных системах. Этот раздел объясняет некоторые из тех различий.
Пользование динамическими библиотеками во время ссылки
При соединении исполнимой программы OS X обрабатывает динамические библиотеки точно так же, как библиотеки в любой другой основанной на UNIX или подобной UNIX операционной системе. Если Вам вызвали библиотеку libmytool.a
, libmytool.dylib
, или libmytool.so
, например, все, что необходимо сделать, является этим:
ld a.o b.o c.o ... -L/path/to/lib -lmytool |
Как правило необходимо избежать создавать статические библиотеки (.a
) за исключением временного продукта стороны создавания приложения. Необходимо работать ranlib
на любом архивном файле, прежде чем Вы попытаетесь соединиться против него.
Пользование динамическими библиотеками программно
OS X делает интенсивное использование динамично соединенного кода. В отличие от других двоичных форматов, таких как ELF и xcoff, Мужественные плагины обработок по-другому, чем он обрабатывают совместно использованные библиотеки.
Предпочтительный механизм для динамической загрузки совместно используемого кода, начинающегося в OS X v10.4 и позже, dlopen
семья функций. Они описаны в странице справочника для dlopen
. ld
и dyld
страницы справочника предоставляют больше определенную подробную информацию реализации динамического компоновщика.
Библиотеки, что Вы знакомы с от других основанных на UNIX систем, не могли бы быть в том же расположении в OS X. Это вызвано тем, что OS X имеет единственную динамично загружаемую платформу, libSystem
, это содержит большую часть базовой функциональности системы. Этот единственный модуль обеспечивает стандарт C среда выполнения, подпрограммы ввода/вывода, математические библиотеки и большая часть нормальной функциональности, требуемой приложениями командной строки и сетевыми службами.
libSystem
библиотека также включает функции, которые Вы обычно ожидали бы находить в libc и libm, службах RPC и определителе имен. Поскольку libSystem
автоматически соединяется в Ваше приложение, Вы не должны явно добавлять его к строке ссылки компилятора. Для Вашего удобства многие из этих библиотек существуют как символьные ссылки на libSystem
, таким образом, при явном соединении против -lm
(например), не необходим, это не вызовет ошибку.
Чтобы узнать больше, как пользоваться динамическими библиотеками, посмотрите, что Динамическая Библиотека Программирует Темы.
Компиляция динамических библиотек и плагинов
По большей части можно обработать динамические библиотеки и плагины тот же путь как на любой другой платформе при использовании GNU libtool. Этот инструмент установлен в OS X как glibtool
избегать конфликта имен с NeXT libtool. Для получения дополнительной информации см. страницу руководства для glibtool
.
Можно также создать динамические библиотеки и плагины вручную при желании. Как упомянуто в пользовании Динамическими Библиотеками Программно, динамические библиотеки и плагины не являются той же вещью в OS X. Таким образом необходимо передать различные флаги при создании их.
Для создания динамических библиотек в OS X передайте -dynamiclib
флаг.
Для создания плагинов передайте -bundle
флаг.
Поскольку плагины могут быть адаптированы в соответствии с определенным приложением, компилятор OS X предоставляет возможность для проверки этих плагинов на loadability во время компиляции. Для использования в своих интересах этой функции используйте -bundle_loader
флаг. Например:
gcc -bundle a.o b.o c.o -o mybundle.bundle \ |
-bundle_loader /Applications/MyApp.app/Contents/MacOS/MyApp |
Если компилятор найдет запросы символа в плагине, который не может быть разрешен в приложении, то Вы получите ошибку ссылки. Это означает что Вы must
используйте -l
отметьте для соединения против любых библиотек, которых требует плагин, как будто Вы создавали полную исполнимую программу.
Чтобы узнать больше, как создать и пользоваться динамическими библиотеками, посмотрите, что Динамическая Библиотека Программирует Темы.
Пакеты
В файловой системе OS X некоторые каталоги хранят исполняемый код и программные ресурсы, связанные с тем кодом в одном дискретном пакете. Эти пакеты, известные как пакеты, прибывают в два варианта: комплекты приложений и платформы.
Существует два основных типа пакетов, что необходимо быть знакомы с во время основного процесса портирования: комплекты приложений и платформы. В частности необходимо знать, как использовать платформы, так как Вы, возможно, должны соединиться против содержания платформы при портировании приложения.
Комплекты приложений
Комплекты приложений являются специальными каталогами, появляющимися в Средстве поиска как единственный объект. Наличие только одного элемента позволяет пользователю дважды щелкать по нему для получения приложения со всеми его ресурсами поддержки. При создании приложений Mac необходимо сделать комплекты приложений. XCode создает их по умолчанию при выборе одних из типов проектов приложения. Больше информации о комплектах приложений доступно в Пакетах по сравнению с Установщиками и в Технологическом Обзоре Mac.
Платформы
Платформа является типом пакета, упаковывающего совместно используемую библиотеку с ресурсами, которых требует библиотека. В зависимости от библиотеки этот пакет мог включать заголовочные файлы, изображения и справочную документацию. При попытке поддержать межплатформенную совместимость, Вы не можете хотеть создавать свои собственные платформы, но необходимо знать о них, потому что Вы, возможно, должны были бы соединиться против них. Например, Вы могли бы хотеть соединиться против Базовой платформы Основы. Так как платформа является всего одной формой пакета, можно сделать это путем соединения против /System/Library/Frameworks/CoreFoundation.framework
с -framework
флаг. Более полное обсуждение платформ находится в Технологическом Обзоре Mac.
Для получения дополнительной информации
Можно найти дополнительную информацию о пакетах в Технологическом Обзоре Mac.
Обработка умножает определенные символы
Умножение определенной ошибки символа происходит, если существуют повторные определения для какого-либо символа в объектных файлах, которые Вы соединяете. Можно указать, что следующие флаги для изменения обработки умножают определенные символы при определенных обстоятельствах:
-multiply_defined treatment
Указывает, как умножаются, определенные символы в динамических библиотеках должны быть обработаны когда
-twolevel_namespace
имеет силу. Значения для обработки должны быть одним из:error
— Обработка умножает определенные символы как ошибку.warning
— Обработка умножает определенные символы как предупреждение.suppress
— Проигнорируйте умножают определенные символы.
Поведение по умолчанию состоит в том, чтобы обработать, умножают определенные символы в динамических библиотеках как предупреждения когда
-twolevel_namespace
имеет силу.-multiply_defined_unused treatment
Указывает, как неиспользованный умножаются, определенные символы в динамических библиотеках должны быть обработаны когда
-twolevel_namespace
имеет силу. Неиспользованное умножается, определенный символ является символом, определенным в выводе, также определяющемся в одной из динамических библиотек, но в который, но символ в динамической библиотеке не используется никакой ссылкой в выводе. Значения для обработки должны бытьerror
,warning
, илиsuppress
. Значение по умолчанию для неиспользованного умножается, определенные символы должен подавить эти сообщения.
Предопределенные макросы
Следующие макросы предопределены в OS X:
__OBJC__
Когда Ваш код компилируется компилятором Objective C, этот макрос определяется. По умолчанию это происходит при компиляции a
.m
файл или любой заголовок включены a.m
файл. Можно вынудить компилятор Objective C использоваться для a.c
или.h
файл путем передачи-ObjC
или-ObjC++
флаги.__cplusplus
Этот макрос определяется, когда Ваш код компилируется компилятором C++ (или явно или путем передачи
-ObjC++
флаг).__ASSEMBLER__
Этот макрос определяется при компиляции
.s
файлы.__NATURAL_ALIGNMENT__
Этот макрос определяется в системах, использующих естественное выравнивание. При использовании естественного выравнивания,
int
выровненный наsizeof(int)
граница, короткое целое выровненное наsizeof(short)
граница, и т.д. Это определяется по умолчанию при компиляции кода для PowerPC architecutres. Когда Вы используете, это не определяется-malign-mac68k
переключатель компилятора, и при этом это не определяется на архитектурах Intel.__MACH__
Если системные вызовы Маха поддерживаются, этот макрос определяется.
__APPLE__
Этот макрос определяется в любом Компьютере Apple.
__APPLE_CC__
Этот макрос установлен в целое число, представляющее номер версии компилятора. Это позволяет Вам различить, например, между компиляторами на основе той же версии GCC, но с различными исправлениями ошибок или функциями. Большие значения обозначают более поздние компиляторы.
__BIG_ENDIAN__
и__LITTLE_ENDIAN__
Они, которые говорят макросы, использует ли текущая архитектура порядок байтов с обратным порядком байтов или с прямым порядком байтов. Для получения дополнительной информации посмотрите Компиляцию для Многократных архитектур ЦП.
Другие подсказки по портированию
В этом разделе описываются альтернативы определенному обычно используемому APIs.
Заголовки
Следующие заголовки, обычно находимые в UNIX, BSD или Операционных системах Linux, или недоступны или не поддерживаются в OS X:
alloc.h
Этот файл не существует в OS X, но функциональность действительно существует. Необходимо включать
stdlib.h
вместо этого. Также можно определить прототипы сами следующим образом:#ifndef _ALLOCA_H
#undef __alloca
/* Now define the internal interfaces. */
extern void *__alloca (size_t __size);
#ifdef __GNUC__
# define __alloca(size) __builtin_alloca (size)
#endif /* GCC. */
#endif
ftw.h
ftw
функционируйте пересечения через иерархию каталогов, и вызывает функцию для получения информации о каждом файле. Однако нет функции, подобнойftw
вfts.h
.Одна альтернатива должна использовать
fts_open
,fts_children
, иfts_close
реализовать такой обход файла. Чтобы сделать это, используйтеfts_open
функция для получения дескриптора к файловой иерархии использоватьfts_read
получить информацию о каждом файле и использованиеfts_children
получить ссылку к списку структур, содержащих информацию о файлах в каталоге.Также можно использовать
opendir
,readdir
иclosedir
с рекурсией для достижения того же результата.Например, для получения, описание каждого файла расположилось в
/usr/include
использованиеfts.h
, тогда код был бы следующие:/* assume that the path "/usr/include" has been passed through argv[3]*/
fileStruct = fts_open(&argv[3], FTS_COMFOLLOW, 0);
dirList = fts_children(fileStruct, FTS_NAMEONLY);
do
{
fileInfo = fts_read(dirList->fts_pointer);
/* at this point, you would be able to extract information from the
FTSENT returned by fts_read */
fileStruct = fts_open(dirList->fts_link->fts_name,
FTS_PHYSICAL, (void *)result);
}while (dirList->fts_link != NULL);
ftsResult = fts_close(fileStruct);
См. страницу руководства для
fts
понять структуры и макросы, используемые в коде. Пример кода выше шоу очень упрощенный обход файла. Например, это не считает возможные подкаталоги существующими в каталоге искавший.getopt.h
Не поддерживаемый, использовать
unistd.h
вместо этого.lcrypt.h
Не поддерживаемый, использовать
unistd.h
вместо этого.malloc.h
Не поддерживаемый, использовать
stdlib.h
вместо этого.mm.h
Этот заголовок поддерживается в Linux для отображения памяти, но не поддерживается в Макс. OS X. В OS X можно использовать
mmap
отобразить файлы в память. Если Вы хотите отобразить устройства, используйте платформу Набора I/O вместо этого.module.h
Модули ядра должны быть загружены с помощью KextManager API в платформе Набора I/O. Для получения дополнительной информации посмотрите
KextManagerLoadKextWithURL
и связанные функции. Сами модули должны быть скомпилированы против платформы Ядра. Для получения дополнительной информации см. Основные принципы IOKit.nl_types.h
Используйте
CFBundleCopyLocalizedString
API в Базовой Основе для подобной функциональности локализации.ptms.h
Несмотря на то, что pseudo-TTYs поддерживаются в OS X, этот заголовок не. Реализация pseudo-TTYs очень отличается от Linux. Для получения дополнительной информации посмотрите
pty
страница руководства.stream.h
Этот заголовочный файл не присутствует в OS X. Для потоковой передачи файла использовать
iostream.h
.stropts.h
Не поддерживаемый.
swapctl.h
OS X не поддерживает этот заголовочный файл. Можно использовать заголовочный файл
swap.h
реализовать функциональность подкачки.swap.h
заголовочный файл содержит много функций, которые могут использоваться для настройки подкачки.termio.h
Этот заголовочный файл является устаревшим, и был заменен
termios.h
, который является частью стандарта POSIX. Эти два заголовочных файла очень подобны. Однакоtermios.h
не включает те же заголовочные файлы какtermio.h
. Таким образом, несомненно, необходимо будет посмотреть непосредственно наtermios.h
заголовок для проверки это включает все потребности приложения.utmp.h
Осуждаемый, использовать
utmpx.h
вместо этого.values.h
Не поддерживаемый, использовать
limits.h
вместо этого.wchar.h
Несмотря на то, что эта функциональность доступна, необходимо обычно использовать
CFStringRef
API в Базовой Основе вместо этого.
Функции
Следующие функции, обычно замечаемые в другом Unix, Linux или операционных системах BSD, не поддерживают или обескураживают в OS X.
btowc, wctob
Несмотря на то, что OS X поддерживает
wchar
API, предпочтительный способ работать с международными строкамиCFStringRef
API, который является частью Базовой платформы Основы. Часть APIs, доступного в Базовой Основе,CFStringGetSystemEncoding
,CFStringCreateCopy
,CFStringCreateMutable
, и т.д. См. Базовую документацию Основы для полного списка поддерживаемого APIs.catopen, catgets, catclose
nl_types.h
не поддерживается, таким образом, эти функции не поддерживаются. Эти функции предоставляют доступ к локализованным строкам. В OS X нет никакого прямого эквивалента. В целом необходимо использовать Базовую Основу для доступа к локализованным ресурсам (CFBundleCopyLocalizedString
, например).crypt
crypt
функция выполняет шифрование пароля, на основе Стандарта шифрования данных (DES) NBS. Дополнительный код был добавлен для удерживания ключевых поисковых попыток.crypt
. Версия OS X функцииcrypt
ведет себя очень так же к версии Linux, за исключением того, что она шифрует 64-разрядную константу, а не 128-разрядную константу. Эта функция расположена вunistd.h
заголовочный файл, а неlcrypt.h
.dysize
Эта функция не поддерживается в OS X. Его вычисление в течение високосного года основывается:
(year) %4 == 0 && ((year) %100 != 0 || (year) % 400 == 0)
Можно или использовать этот код для реализации этой функциональности, или можно использовать любой существующий APIs в time.h, чтобы сделать что-то подобное.
ecvt
,fcvt
Обескураженный в OS X. Использовать
sprintf
,snprintf
, и подобные функции вместо этого.fcloseall
Эта функция является расширением
fclose
. Несмотря на то, что OS X поддерживаетfclose
,fcloseall
не поддерживается. Можно использоватьfclose
реализоватьfcloseall
путем хранения указателей файла в массиве и итерации через массив.getmntent
,setmntent
,addmntent
,endmntent
,hasmntopt
В целом объемы в OS X не находятся в
/etc/fstab
. Однако до такой степени, что они, можно получить схожую функциональность отgetfsent
и связанные функции.poll
Этот API частично поддерживается в OS X. Это не поддерживает устройства опроса.
sbrk
,brk
brk
иsbrk
функции являются историческим любопытством, перенесенным с более ранних дней перед появлением управления виртуальной памятью. Несмотря на то, что они присутствуют в системе, им не рекомендуют.shmget
Этот API поддерживается, но не рекомендуется.
shmget
имеет блочное выделение ограниченной памяти. Когда несколько приложений используютshmget
, этот предел может изменить и вызвать проблемы для других приложений. В целом необходимо или использоватьmmap
для отображения файлов в память или использование POSIXshm_open
функционируйте и связанные функции для создания не, файл поддержал общую память.swapon
,swapoff
Эти функции не поддерживаются в OS X.
Утилиты
Глава, Разрабатывая Сценарии для Межплатформенного Развертывания в Shell, Пишущем сценарий Учебника для начинающих, описывает много межплатформенных проблем совместимости, с которыми можно столкнуться с обычно задающимися сценарием утилитами командной строки.
Этот раздел перечисляет несколько команд, которые имеют прежде всего интерес для людей, портирующих скомпилированные приложения и драйверы, а не сценарии общего назначения.
ldd
ldd
команда не доступна в OS X. Однако можно использовать командуotool -L
получить ту же функциональность этоldd
обеспечивает.otool
команда выводит на экран указанные части объектных файлов или библиотек. Опция-L
выводит на экран имя и номера версий совместно используемых библиотек, которыми пользуется объектный файл. Для наблюдения всех существующих опций см. страницу руководства дляotool
.lsmod
lsmod
не доступно на OS X, но другие команды существуют та схожая функциональность предложения.kextutil
Загрузки, проблемы диагнозов с, и генерируют символы для расширений ядра.
kextstat
Статистика печати о в настоящее время загруженных драйверах и других расширениях ядра.
kextload
Загружает модуль ядра для драйвера устройства или других расширений ядра. Эта команда является основной командой, предназначенной для использования в сценариях. В целях разработчика использовать
kextutil
вместо этого.kmodunload
Разгружает модуль ядра для драйвера устройства или других расширений ядра. Эта команда является основной командой, предназначенной для использования в сценариях. В целях разработчика использовать
kextutil
вместо этого.
Для получения дополнительной информации о загружающихся модулях ядра, посмотрите, что Расширение ядра Программирует Темы.