2017-10-09 12 views
-1

J'essaie de comprendre comment Objective-C fonctionne, et l'exemple le plus simple que j'ai trouvé jusqu'ici est de https://codeseekah.com/2012/09/12/compiling-objective-c-without-a-gui/; malheureusement, je ne peux pas tout à fait le compiler (en fait, le lien).Création simple d'un exemple Objective-C avec clang sur Ubuntu (la liaison échoue)?

Tout d'abord, j'utilise Ubuntu 14.04 (64 bits), et là, je l'ai installé:

sudo apt-get install clang-3.5 libobjc-4.8-dev 

Ensuite, je les fichiers (légèrement modifié) de la page référencée dans this gist, donc vous pouvez juste faire:

cd /tmp 
git clone https://gist.github.com/dc0b573ae8ef2424aaeb043a6014b7fd.git testobjc 
cd testobjc 
make 

le Makefile il est modifié pour utiliser le clang-3.5 actuellement installé.

Le premier problème que j'avais, était:

main.m:45:26: error: class method '+new' not found (return type defaults to 'id') [-Werror,-Wobjc-method-access] 
    Person *brad = [Person new]; 

Je trouve Unable to compile Objective-C code on Ubuntu:

+ (id) est une fonction nouvelle de la classe NSObject. Cependant, vous sous-classez un objet d'exécution. Pour utiliser la plupart des méthodes Apple que vous avez l'habitude d'utiliser sous OS X, vous devez sous-classer NSObject à la place.
Vous pouvez toujours utiliser le framework Foundation lors de l'utilisation de l'environnement d'exécution GNU. Cela devrait être disponible. Il y a une référence, vous pouvez utiliser ici: blog.lyxite.com/2008/01/...

Ce dernier est un lien mort, mais la copie sur http://www.cnblogs.com/jack204/archive/2012/03/21/2410095.html:

Pour compiler les programmes Objective-C sur Linux, GNUstep doit être installé

Je trouve How to instantiate a class in Objective-C that don't inherit from NSObject:

Vous ne pouvez absolument le faire. Votre classe doit simplement implémenter + alloc lui-même, comme le fait NSObject. À la base, cela signifie simplement utiliser malloc() pour récupérer un morceau de mémoire assez grand pour correspondre à la structure définissant une instance de votre classe.

donc ce que je ne comprends pas:

  • Si GNUstep offre Fondation cadre Objective-C sur GNU/Linux, quel est le rôle de libobjc!

Comme aucun de ces zoneAlloc fonctions (nécessaires pour init/alloc) etc sont disponibles avec l'installation des deux paquets ci-dessus, je l'ai grep -r " id" //usr/lib/gcc/x86_64-linux-gnu/4.8/include/objc et trouvé il y a une fonction class_createInstance qui retourne un id, et ainsi par En définissant une méthode new qui l'utilise, le compilateur ne génère plus de messages d'erreur lors de l'étape de compilation.

Mais alors, il échoue dans l'étape de liaison - le journal complet de construction est aussi l'essentiel (comme make.log) - avec:

/usr/bin/ld: cannot find -lobjc 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make: *** [all] Error 1 

Eh bien, tout d'abord, libobjc.so est dans le répertoire /usr/lib/x86_64-linux-gnu:

$ ls -la /usr/lib/x86_64-linux-gnu/libobjc* 
lrwxrwxrwx 1 root root  19 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc_gc.so.4 -> libobjc_gc.so.4.0.0 
-rw-r--r-- 1 root root 267552 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc_gc.so.4.0.0 
lrwxrwxrwx 1 root root  16 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc.so.4 -> libobjc.so.4.0.0 
-rw-r--r-- 1 root root 112536 May 7 2016 /usr/lib/x86_64-linux-gnu/libobjc.so.4.0.0 

... et dans le Makefile, j'ai essayé d'exécuter la commande clang en réglant les deux LD_LIBRARY_PATH et LIBRARY_PATH-/usr/lib/x86_64-linux-gnu - un nd Je l'ai également spécifié avec le commutateur "Additional Library paths" -L (dans LDFLAGS). Tous cela semble être ignoré par le temps la commande de liaison "/usr/bin/ld" se exécute, mais cela n'a pas d'importance, car la commande de liaison lui-même a cela dans ses arguments:

... -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu ... 

... et ce chemin fait En effet, étendre à /usr/lib/x86_64-linux-gnu (vérifié avec readlink -f), qui est où libobjc.so.* sont. Mais encore la commande de l'éditeur de liens échoue?!

Ma deuxième question est:

  • Pourquoi ne pas ld trouver libobjc.so.*, même si /usr/lib/x86_64-linux-gnu où il se trouve est spécifié sur ses arguments de ligne de commande via -L - et que dois-je faire, pour obtenir ce programme à lier?
+0

je pouvais attendre un closevote pour cette question pour de nombreuses raisons, mais certainement pas pour " hors sujet"? Quelqu'un peut-il expliquer pourquoi cela est hors sujet, et où puis-je le poster à la place (s'il existe un tel site sur Stack Exchange?) Merci! – sdaau

Répondre

0

Oh, eh bien, il s'avère que l'étape de liaison peut être résolue avec un lien symbolique; J'ai d'abord essayé de tester avec ld, et au début, je recevais:

$ ld -L/usr/lib/x86_64-linux-gnu -lobjc 
ld: cannot find -lobjc 

... Cependant, avec un chemin explicite, alors ld ne se plaint pas « ne peut pas trouver » plus:

$ ld -v /usr/lib/x86_64-linux-gnu/libobjc.so.4 
GNU ld (GNU Binutils for Ubuntu) 2.24 
ld: warning: cannot find entry symbol _start; not setting start address 

Alors, quand je regardais le répertoire de plus près:

$ (cd /usr/lib/x86_64-linux-gnu; ls libobjc*) 
libobjc_gc.so.4 libobjc_gc.so.4.0.0 libobjc.so.4 libobjc.so.4.0.0 

... il se trouve, il ne fichiers sont appelés simplement libobjc.so - ils ont tous des noms tels que libobjc.so.* ... Je pensais que, peut-être que je devrais peut-être un lien symbolique avec un nom de libobjc.so:

cd /usr/lib/x86_64-linux-gnu/ 
sudo ln -s libobjc.so.4.0.0 libobjc.so 

... et maintenant quand je lance make - il réussit en fait! Je reçois un fichier exécutable appelé main, et il fonctionne très bien:

$ ./main 
Hello, my name is Brad Cox! 
Hello, my name is Tom Love! 

Eh bien, agréable d'avoir cette ...

triés