Как организовать исходный файл C, предварительно скомпилированный GCC Make, и собрать их в пакет Xcode? У меня есть повторяющийся символ _основная ошибка - PullRequest
3 голосов
/ 27 марта 2012

Как собрать .bundle из исходного кода?

Это может показаться простой проблемой, но это мешало мне неделю ...

Вот моя проблема:

У меня есть куча файлов .c и .h, которые организованы в папку и ее подпапки. Исходный код был написан и скомпилирован с помощью gcc make и протестирован многими другими инструментами make. В исходном коде есть некоторые утилиты и инструменты командной строки, и он содержит больше кода, который служит библиотекой для этих утилит и инструментов. Это файлы, которые служат библиотеками, которые я хочу использовать повторно. (Под библиотекой я не подразумеваю статическую библиотеку или что-то в этом роде, я просто имею в виду, что некоторые файлы .c и .h в определенных подпапках предоставляют функции, которые могут вызываться некоторыми другими файлами .c. Я хочу иметь возможность вызывать эти функции, тоже)

Тем не менее, моя проблема более сложна: мне нужно собрать эти .c и .h в связку, чтобы использовать их повторно. Я не пишу свое заявление на C; Я занимаюсь разработкой в ​​Unity, и Unity может принимать только файлы .bundle в Mac OS.

Вот моя цель:

Организовать папку с исходным кодом надлежащим образом, чтобы я мог встроить их в пакет в Xcode 4.

Вот где я застрял:

При сборке проекта я получил следующую ошибку:

Дубликат символа _main in /Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccndsmoketest.o а также /Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccnd_main.o для архитектуры i386

Я могу относиться к этой ошибке, потому что я могу найти много основных записей в исходном коде. Большинство из них являются тестовыми утилитами.

Вот что я попробовал:

  1. Я попытался удалить все эти служебные файлы .c, но безуспешно. Ошибка все еще там. Я удаляю и удаляю, пока некоторые файлы не могут найти определение функции, которую они вызывают. Поэтому мне пришлось остановиться там.

  2. Хотя я не смог собрать пакет, я смог создать статическую библиотеку C / C ++ (с расширением .a). После того, как я получил файл .a, я попытался поместить его в другой проект Xcode и попытался собрать его в пакет. Я мог создать пакет таким образом, но тогда у меня были проблемы с доступом к содержимому пакета. Как вызвать функции, определенные в статической библиотеке .a, если эта библиотека скрыта в комплекте? Я прочитал документацию Apple, в которой говорится:

Примечание: некоторые цели XCode (такие как инструменты оболочки и статические библиотеки) делают не приводит к созданию пакета или пакета. Это нормально и нет необходимости создавать пакеты специально для этих целей типы. Полученные двоичные файлы, сгенерированные для этих целей, предназначены использоваться как есть.

(цитата из: https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1)

Вот что я подумал:

  1. Я думал о замене всего основного чем-то вроде main_sth. Но исходный код был написан не мной, поэтому я не хотел его изменять. (Это просто не похоже на правильный способ сделать что-то со мной ...)
  2. Я узнал, что в Xcode встроен компилятор gcc. Так что я думаю, если gcc может это сделать, то может ли Xcode? Это просто дикая догадка - я не знаком с Xcode и gcc.

Вот краткое изложение моих вопросов:

  1. Есть ли способ правильно организовать кучу кода, предварительно скомпилированного и сделанного gcc make, чтобы его можно было встроить в пакет Xcode?
  2. Имеет ли смысл поместить библиотеку .a в проект Xcode и собрать ее в связку? Если это имеет смысл, как я могу вызывать функции, определенные в .a, после того, как он встроен в пакет?
  3. Правильно ли просто заменить все записи main () чем-то другим?

Ответы [ 2 ]

1 голос
/ 28 марта 2012

Хорошо, я думаю, что нашел по крайней мере одно решение проблемы.

Дублированная основная ошибка была вызвана кучей основных записей в моем исходном коде.Когда код был скомпилирован gcc make, я предполагаю, что автор определил своего рода порядок компиляции, чтобы дублирование сети не было проблемой.(Если вы знаете, как это сделать, пожалуйста, дайте мне знать. Я почти не знаю, как создавать инструменты.) Но когда я просто добавляю всю папку с исходным кодом в свой проект Xcode, конечно, Xcode будет жаловаться во время компоновки ...

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

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

Хорошо, здесьвот что я сделал:

  1. Я установил пустое рабочее пространство.

  2. Я создал проект статической библиотеки C / C ++.

  3. Импортировать всю мою папку с исходным кодом в проект статической библиотеки.

  4. Установить некоторый путь поиска заголовка для проекта статической библиотеки.

  5. Сборка проекта статической библиотеки.(Теперь у меня есть библиотека .a, с которой я могу связать)

  6. Я настроил другой проект с целью комплектации.

  7. Впроект пакета -> этапы сборки -> связать двоичные файлы с библиотеками, добавьте только что созданную библиотеку .a

  8. В проекте пакета -> изменить схему -> построить, добавьтеСтатический проект библиотеки в схему и переместите его вверх по списку, чтобы он был построен до моего проекта пакета.

  9. Затем добавьте .h файлы моего проекта библиотеки в мой проект пакета как ссылки.

  10. После этого добавьте .c файл в мой пакетный проект, который в основном функционирует как оболочка.Я выбрал функцию, которую хочу вызвать в Unity, написал функцию-обертку в новом файле .c и смог собрать пакет.

  11. После нескольких проб и ошибок ябыл в состоянии импортировать пакет в Unity и был в состоянии вызвать функцию тестирования из Unity.

Я был очень рад этому!Хотя он еще не завершен, я думаю, что это вселяет надежду, и я уверен, что теперь могу использовать исходный код!И самое лучшее в этом решении - мне не нужно изменять код библиотеки, разработанный другими.Всякий раз, когда они обновляют свой код, я просто обновляю свою библиотеку .a и все!

Хотя я перечислил 11 шагов, я все еще чувствую, что есть много деталей, которые я пропустил.Итак, вот мои ссылки:

  1. Я следовал этому руководству, чтобы встроить свой исходный код в статическую библиотеку: http://www.ccnx.org/?post_type=incsub_wiki&p=1315

  2. Я следовал по этому блогу, чтобы связатьстатическая библиотека для моего кода пакета и фаз сборки твист и поисковых заголовков: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/

  3. Я следовал этому документу, чтобы импортировать свой пакет в Unity3D Pro в качестве плагина: http://unity3d.com/support/documentation/Manual/Plugins.html

Я настоятельно рекомендую второй справочник, потому что именно это решило мою проблему!

Хотя проблема почти решена, есть еще несколько вещей, которых у меня нет 't выяснил:

  1. Я не знаю, нужна ли вообще функция обертки.Я попробую это завтра и вернусь к обновлению.

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

  1. Я не использовал класс NSBundle, хотя я прочиталнесколько документов об этом.Раньше я думал об использовании этого класса для доступа к моей библиотеке .a, инкапсулированной в моем комплекте, но когда я нашел решение, которое написал выше, я не попробовал этот класс.

Наконец, если у вас есть лучшее решение, пожалуйста, не стесняйтесь, дайте мне знать!

0 голосов
/ 26 июня 2014

Я пытался выполнить шаги в принятом ответе, но безуспешно. В конце я понял, что шаг 10 нужно немного изменить:

  • Создайте проект dummy.c under (.bundle), и dummy.c может быть просто пустым.
  • Удалите настройку библиотеки, с которой вы хотите связать Link Binary With Libraries
  • Вместо этого используйте -Wl,-force_load,$(CONFIGURATION_BUILD_DIR)/libYourLib.a или -all_load до Other Linker Flags

PS: А также может использовать подпроект вместо рабочего пространства. и используйте Target Dependencies вместо Edit Scheme для достижения того же эффекта.

...