Проблемы при компиляции Objective C с Clang (Ubuntu) - PullRequest
10 голосов
/ 18 февраля 2012

Я изучаю язык Objective-C. Поскольку у меня нет Mac, я компилирую и запускаю свой код на платформе Ubuntu 11.04.

До сих пор я использовал gcc для компиляции. Я установил GNUStep и все работало. Но затем я начал пробовать некоторые функции Objective-C 2.0, такие как @property и @synthesize, которые gcc не разрешает.

Поэтому я попытался скомпилировать код с помощью Clang, но, похоже, он неправильно связывает мой код с библиотеками GNUStep, даже с простой программой Hello world.

Например, если я скомпилирую следующий код:

#import <Foundation/Foundation.h>

int main(void) {
  NSLog(@"Hello world!");
  return 0;
}

Выходные данные компилятора:

/tmp/cc-dHZIp1.o: In function `main':
test.m:(.text+0x1f): undefined reference to `NSLog'
/tmp/cc-dHZIp1.o: In function `.objc_load_function':
test.m:(.text+0x3c): undefined reference to `__objc_exec_class'
collect2: ld returned 1 exit status
clang: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)

Команда, которую я использую для компиляции:

clang -I /usr/include/GNUstep/ test.m -o test

с директивой -I для включения библиотек GNUStep (в противном случае Clang не сможет найти Foundation.h).

Я погуглил свою проблему и посетил веб-страницы GNUStep и Clang, но я не нашел решения. Так что любая помощь будет оценена.

Спасибо!

Ответы [ 3 ]

6 голосов
/ 19 февраля 2012

Проблема заключалась в том, что библиотека gnustep-base не использовалась компоновщиком.Таким образом, для решения этой проблемы использовалась опция -Xlinker, которая отправляет аргументы компоновщику, используемому clang:

clang -I /usr/include/GNUstep/ -Xlinker -lgnustep-base test.m -o test

Утверждение "-X linker -lgnustep-base" сотворило магию.Однако у меня были проблемы с этой командой, связанной с классом, который представляет строку в Objective-C:

./test: Uncaught exception NSInvalidArgumentException, reason: GSFFIInvocation:
Class 'NXConstantString'(instance) does not respond to forwardInvocation: for
'hasSuffix:'

. Я мог бы решить ее, добавив аргумент "-fconstant-string-class = NSConstantString":

clang -I /usr/include/GNUstep/ -fconstant-string-class=NSConstantString \
-Xlinker -lgnustep-base test.m -o test

Кроме того, я попробовал несколько кусков кода Objective-C 2.0, и, похоже, он работает.

Спасибо за помощь!

1 голос
/ 18 февраля 2012

Вы можете попробовать компилятор gcc:
Прежде всего, установите GNU Objective-C Runtime: sudo apt-get install gobjc
затем скомпилируйте: gcc -o hello hello.m -Wall -lobjc

0 голосов
/ 06 июля 2016

Вы не можете использовать функции ObjC 2.0, потому что вам не хватает ObjC-среды выполнения, поддерживающей их. Среда выполнения GCC старая и устаревшая, она не поддерживает ObjC 2.0. Clang / LLVM не имеет сопутствующей среды выполнения, вам нужно установить ObjC2-среду выполнения из GNUstep (которую можно найти здесь: https://github.com/gnustep/libobjc2) и переустановить GNUstep, используя эту среду выполнения.

Вот несколько скриптов bash для разных версий Ubuntu, которые сделают все за вас:

http://wiki.gnustep.org/index.php/GNUstep_under_Ubuntu_Linux

И, пожалуйста, не пытайтесь заново изобретать GNUstep make, вместо этого используйте его:

http://www.gnustep.org/resources/documentation/Developer/Make/Manual/gnustep-make_1.html

Если вы действительно так не думаете, вот отрывок из этого:

1.2 Структура Make-файла

Вот пример make-файла (названного GNUmakefile, чтобы подчеркнуть тот факт, что он опирается на специальные функции программы make GNU).

#
# An example GNUmakefile
#

# Include the common variables defined by the Makefile Package
include $(GNUSTEP_MAKEFILES)/common.make

# Build a simple Objective-C program
TOOL_NAME = simple

# The Objective-C files to compile
simple_OBJC_FILES = simple.m

-include GNUmakefile.preamble

# Include in the rules for making GNUstep command-line programs
include $(GNUSTEP_MAKEFILES)/tool.make

-include GNUmakefile.postamble

Это все, что необходимо для определения проекта.

В вашем случае замените все вхождения simple на test и все готово

1.3 Беговая марка

Обычно для компиляции пакета, использующего пакет Makefile, достаточно просто набрать make из каталога верхнего уровня пакета, и пакет компилируется без какого-либо дополнительного взаимодействия.

...