Проблемы при компиляции Objective C с Clang (Ubuntu)
Я изучаю язык 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, но я не нашел для нее решения. Поэтому любая помощь будет оценена.
Спасибо!
Ответы
Ответ 1
Проблема заключалась в том, что библиотека gnustep-base не использовалась компоновщиком. Таким образом, для решения этой проблемы использовался параметр -Xlinker, который отправляет аргументы компоновщику, используемому clang:
clang -I /usr/include/GNUstep/ -Xlinker -lgnustep-base test.m -o test
Заявление "-X линкер -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 фрагментами кода и, похоже, работает.
Спасибо за помощь!
Ответ 2
Вы можете попробовать gcc-компилятор:
Прежде всего установите GNU Objective-C Время выполнения: sudo apt-get install gobjc
затем скомпилируйте: gcc -o hello hello.m -Wall -lobjc
Ответ 3
Вы не можете использовать функции 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 Структура Makefile
Вот пример make файла (названный GNUmakefile, чтобы подчеркнуть тот факт, что он опирается на специальные функции программы GNU make).
#
# 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 Запуск Make
Обычно для компиляции пакета, который использует пакет Makefile, достаточно просто набрать make
из каталога верхнего уровня пакета, и пакет компилируется без какого-либо дополнительного взаимодействия.