[résolu] Locating Frameworks in Non-Standard Directories ou framewok embarqué dans une application

mybofymybofy Membre
novembre 2013 modifié dans API AppKit #1

Bonjour


 


Sous ce titre, je lis dans la doc Xcode :


If your project links to frameworks that are not included in any of the standard locations, you must explicitly specify the location of that framework before Xcode can locate its header files. To specify the location of such a framework, add the directory containing the framework to the “Framework Search Paths” option of your Xcode project. Xcode passes this list of directories to the compiler and linker, which both use the list to search for the framework resources.


J'en déduis que je peux placer mon framework où je veux.


Dans Build Settings > Search Paths > Frameworks Search Paths je définis le chemin de recherche :


"/Users/rn/cocoa/10.7.5-4.6.1/projects/CVSophie/CVSophie"


J'y place MyFW.framework. Je l'ajoute au projet.


J'obtiens Build Succedeed, puis instantanément :


dyld: Library not loaded: /Library/Frameworks/MyFW.framework/Versions/A/MyFW


  Referenced from: /Users/rn/Library/Developer/Xcode/DerivedData/CVSophie-aitgnlaxmhaphvfnnkyvwppkjxgi/Build/Products/Debug/CVSophie.app/Contents/MacOS/CVSophie


  Reason: image not found


(lldb)


 


Xcode ignore le chemin de recherche que j'ai donné. Pourquoi ? Où est mon erreur ?


 


Merci.


Réponses

  • Il faut que l'install path du framework quand tu l'a compilé soit cohérent également. Par défaut ils sont réglé à  /Library/Frameworks, ça se change dans les réglages du projet du framework en lui même.


    Cependant c'est une assez mauvaise idée si tu compte distribuer ton logiciel. Les .framework sont des libraries dynamique, ça veut donc dire qu'elles doivent être à  l'endroit indiqué sur toutes les machines où sera lancé l'application.


  • Merci.


    J'ai bien compris et j'ai changé l'install path. Mais ça ne change rien.


     


    Je ne comprends rien aux frameworks.


     


    Je reprends à  zéro.


     


    Je crée un framework MyFW, sans rien changer aux paramètres de build par défaut. OK.


     


    Le seul endroit où je vois MyFW.framework est dans ~/Library/Developer/Xcode/...


     


    J'imaginais que le Install Directory plaçait MyFW.framework dans le répertoire défini, ici le répertoire proposé par défaut : /Library/Frameworks


    Or rien dans ce répertoire alors que je n'ai rien changé aux paramètres par défaut.


     


    Comment récupérer MyFW.framework autrement qu'en allant le chercher dans ~/Library/Developer/Xcode/... ?


    Ce qui me paraà®t un bidouillage merdique.


  • CéroceCéroce Membre, Modérateur

    Je ne comprends rien aux frameworks.



    Le système est particulièrement difficile à  comprendre, mais crois-moi, ça s'est beaucoup amélioré depuis 10.5 !

     



    Le seul endroit où je vois MyFW.framework est dans 



    ~/Library/Developer/Xcode/...

    Si elle y est, c'est que c'est toi qui l'a mise ici.

     




    J'imaginais que le Install Directory plaçait MyFW.framework dans le répertoire défini, ici le répertoire proposé par défaut : /Library/Frameworks



    Non, pas du tout, l'install path dit d'où le code de la framework va s'exécuter. Je n'ai jamais bien compris pourquoi c'était nécessaire de le donner.

     



    Or rien dans ce répertoire alors que je n'ai rien changé aux paramètres par défaut.



    ça c'est normal, Xcode ne copie pas automatiquement la framework à  l'install path.


     


    En fait, il fallait que je prenne un peu de temps pour retrouver un message qui explique tout:
    Merci à” Chacha vénéré.


     


    Les frameworks, c'est très compliqué, mais une fois qu'on utilise otool pour connaitre l'install path et qu'on sait quoi y écrire (avec @loader_path), on y arrive.


  • Je pense que si le framework que tu utilises est normalement installé sous OSx, tu te compliques vachement la vie. 


    Par contre si c'est un framework spécifique que tu ajoutes, le plus simple serait de l'embarquer dans l'application en ajoutant une "build phase" et en indiquant dans "Run search path" quelque chose comme "@loader_path/../Frameworks".


    Il faut également savoir que les chemins de recherches peuvent être différents en "debug" et en "realize" et qu'il faut également régler cela pour le "Project" et pour la "target". Si, si, c'est Siiiiiiiiimmple!


  • Donc, je crée un framework MyFW (vide) Cocoa Framework.


    Dans Build Settings > Installation Directory > Debug :


    ~/cocoa/10.7.5-4.6.1/projects/EssaiFW/EssaiFW



    Le seul endroit où je vois MyFW.framework est


    ~/Library/Developer/Xcode/DerivedData/MyFW-dtmbytzkkvshajecbngjjyxchaqa/Build/Products/Debug/MyFW.framework


     


    Je crée une application EssaiFW (vide) Cocoa Application.

    Dans Build Settings > Frameworks Search Paths > Debug :

    ~/cocoa/10.7.5-4.6.1/projects/EssaiFW/EssaiFW

     

    Je copie MyFW.framework dans


     ~/cocoa/10.7.5-4.6.1/projects/EssaiFW/EssaiFW


     


    J'ajoute MyFW.framework dans EssaiFW.


     


    Dans Build Phases > Link Binary With Libraries j'ai bien MyFW.framework.


     


    Run. Succeeded. Erreur :


    dyld: Library not loaded: ~/cocoa/10.7.5-4.6.1/projects/EssaiFW/EssaiFW


    /MyFW.framework/Versions/A/MyFW


      Referenced from: /Users/rn/Library/Developer/Xcode/DerivedData/EssaiFW-bxbwcantvkjxmudnbhurupswlwhw/Build/Products/Debug/EssaiFW.app/Contents/MacOS/EssaiFW


      Reason: image not found


    (lldb)


     


    Il manque sûrement quelque chose quelque part, mais quoi ?


     


     


     


    J'ai essayé ce que les uns et les autres m'ont dit, mal sans doute. Sans résultat.


     


    Quand à  la doc Framework Programming Guide > Embedding a Private Framework in Your Application bundle elle est aussi complète qu'inutile.


    Pour moi, ce que je lis est de l'ordre du YAKA :


     


    To embed a framework in an application, there are several steps you must take:


    • You must configure the build phases of your application target to put the framework in the correct location. 

    • You must configure the framework target's installation directory, which tells the framework where it will live.



    • You must configure the application target so that it references the framework in its installation directory.


    It is possible to build and embed a framework in an application using a single Xcode project or multiple projects. Using a single Xcode project is somewhat easier because it requires less configuration to get both the framework and application to build.


    Un exemple basique serait le bienvenu.


     


  • CéroceCéroce Membre, Modérateur

    Commence par regarder avec otool l'install path de ta framework. La solution est là .


  • mybofymybofy Membre
    novembre 2013 modifié #8

    Bon, ça y est ! Un chemin incorrect...


     


    Je récapitule la procédure qui marche pour moi.


     


    Je crée une Cocoa Application EssaiFW.


    Les fichiers se trouvent dans ~/cocoa/10.7.5-4.6.1/projects/EssaiFW/EssaiFW


    Run OK.


     


    Je crée un Cocoa Framework MyFW.


    Les fichiers se trouvent dans ~/cocoa/10.7.5-4.6.1/projects/MyFW/MyFW


    Dans Build Settings > Installation Directory : /Users/rn/cocoa/10.7.5-4.6.1/projects/EssaiFW/EssaiFW


    Dans File Inspector, je sélectionne MyFW public pour MyFW.h.


    J'ajoute la méthode myFW :



    #import <Foundation/Foundation.h>
    @interface MyFW : NSObject
    - (void)myFW;
    @end
    #import "MyFW.h"
    @implementation MyFW
    - (void)myFW {
    NSLog(@myFW);
    }
    @end

    Run OK.


     


    Dans EssaiFW.


    Dans Buid Settings


        > Runpath Search Paths j'ajoute : @loader_path/../Frameworks/MyFW.framework


        > Framework Search Paths j'ajoute : /Users/rn/cocoa/10.7.5-4.6.1/projects/EssaiFW/EssaiFW


    Dans /Users/rn/Library/Developer/Xcode/DerivedData/MyFW-dtmbytzkkvshajecbngjjyxchaqa/Build/Products/Debug


        je copie MyFW.framework que je colle dans ~/cocoa/10.7.5-4.6.1/projects/MyFW/MyFW


    J'ajoute MyFW.framework à  EssaiFW.


    J'ajoute l'appel à  MyFW :



    #import <Cocoa/Cocoa.h>
    #import <MyFW/MyFW.h>
    @interface AppDelegate : NSObject <NSApplicationDelegate>
    @property (assign) IBOutlet NSWindow *window;
    @end
    #import "AppDelegate.h"
    @implementation AppDelegate
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    MyFW *myFW = [MyFW new];
    [myFW myFW];
    }
    @end

    Run OK.


    Et j'ai dans la console :



    2013-11-05 17:46:37.140 EssaiFW[3775:303] myFW

    Il y a des tas de choses que je ne comprends pas vraiment, des tas d'imprécisions, des tas de choses qui pourraient être améliorées pour faire quelque chose de vraiment propre.


    Désolé s'il y a des erreurs d'écriture, mais le squelette est correct. 


    Sur github : http://github.com/mybofy/EssaiFW (attention : il faudra changer les chemins ! : cf. ci-dessus)


    J'ai appris plein de choses et je constate que tout ce que vous m'avez dit a servi.


     


    Grand merci à  tous.


Connectez-vous ou Inscrivez-vous pour répondre.