PPC ou Intel comment savoir sur quoi tourne mon appli ?

MathMath Membre
09:36 modifié dans API AppKit #1
Bonjour à  tous  <3 <br />
J'ai créé une application (Objective-c/Cocoa) utilisant un petit prog open source. J'ai compilé cet outil sur mon mac PPC sans aucun problème et je l'utilise dans mon programme.

Sauf que maintenant avec les Mac Intel pour être universal binary je dois avoir deux versions de cet outil. Une version compilée sur PPC et une compilée sur Intel.

Alors la question est, comment savoir si mon application est lancée sur un mac Intel ou sur un mac PPC ? (afin de lancer la bonne version de l'outil).

Merci d'avance.

Réponses

  • aranaudaranaud Membre
    février 2006 modifié #2
    Dans les informations finder. Si tu n'as pas ceci (voir image si join), ton application n'est pas compilé en universel. Mais elle fonctionnera grasse à  l'émulateur Roseta.

    Un seul exécutable est présent, mais il contient les deux codes.

    Va voir ce sujet Compilation i386

    [Fichier joint supprimé par l'administrateur]
  • MathMath Membre
    09:36 modifié #3
    Ouais ça je le sais bien  :P

    En fait je voulais dire :

    comment savoir avec des lignes de codes si mon application est lancée sur un mac Intel ou sur un mac PPC ?

    De telle façon que je fasse un truc du style :

    Si je suis sur un mac ppc je lance totoPPC
    Sinon je lance totoIntel

  • aranaudaranaud Membre
    09:36 modifié #4
    Ok, j'avais mal compris.
    Essaye ceci :

    <br />#ifdef __ppc__<br />&nbsp;  //code pour G3, G4, G5<br />#else<br />&nbsp;  // code pour Intel<br />#endif<br />
    

    Il me semble que c'est ça.
  • MathMath Membre
    09:36 modifié #5
    Je vais tester ça ! Merci beaucoup.
  • 09:36 modifié #6
    les directives #xxxx concernent la compilation, pas l'exécution. Autrement dit, la portion de code qui sera compilée dépend non pas de la platteforme sur laquelle le programme tourne, mais bien des réglages de compilations.
  • aranaudaranaud Membre
    09:36 modifié #7
    Mais sa doit répondre à  ce qui veut faire. A savoir faire la différence entre les deux types de processeurs.
  • maconnectmaconnect Membre
    09:36 modifié #8
    pendant l'exécution, y'a un moyen simple:
    int isBigEndian(void)<br />{<br />&nbsp; short int word = 0x0100;<br />&nbsp; char *byte = (char *)&amp;word;<br />&nbsp; return(byte[0]);<br />}
    

    si isBigEndian retourne vrai, alors t'es sur PPC. Sinon t'es sur Intel
    @+
  • MathMath Membre
    09:36 modifié #9
    Ok, je vais tester ça aussi parce qu'effectivement c'est à  l'execution que je dois le savoir.
  • elfelf Membre
    09:36 modifié #10
    Juste pour la culture générale: tu peux m'expliquer comment ton code fonctionne, macconect?
  • AliGatorAliGator Membre, Modérateur
    09:36 modifié #11
    Je ne vois pas ce que le code de Maconnect a de compliqué : il vérifie l'endianness utilisée par le processeur en regardant sur un short.
    Il stocke le short 0x0100 sous forme de short, puis dit ensuite qu'il faut le considérer comme tableau de char plutôt que short, et ainsi en regardant le byte[0] il regarde l'octet de poids fort.
    Si le short est stocké en bigEndian (MSB first) byte[0] vaudra 0x01, sinon c'est byte[1] qui vaudra 0X01 et byte[0] 0x00.

    Comme les PPC et les proc Intel n'utilisent pas le même endianness, il se base sur cette particularité pour faire la différence.

    Enfin bon je trouve ça moyen, pourquoi se compliquer la vie alors qu'une directive de compilation ferait l'affaire ??
    Si vraiment tu le veux sous forme de fonction :
    - (BOOL)isOnPPC {<br />#if __ppc__<br />return YES;<br />#else<br />return NO;<br />#endif<br />}
    
    Lorsque tu vas compiler ce code, si tu le compiles pour PPC il va se compiler comme :
    - (BOOL)isOnPPC {<br />&nbsp; return YES;<br />}
    
    et si tu compiles pour Intel il va se compiler ainsi :
    - (BOOL)isOnPPC {<br />&nbsp; return NO;<br />}
    
    Cette compilation conditionnelle est automatique grace aux directives #if/#else/#endif qui agissent sur le compilateur. Et si tu compiles en UB, pas de problème, la partie compilée pour PPC dans le UB aura une implémentation de la fonction isOnPPC, et la partie Intel de l'UniversalBinary aura une autre implémentation.

    Ca ne dérange pas que les #xxx soient des flags influant sur la compilation et non pas le runtime dans le sens où on peut comme ici les utiliser pour modifier l'implémentation d'une fonction selon qu'elle sera compilée pour intel et PPC, vu qu'après on peut faire appel à  cette fonction pendant le Runtime, fonction qui sera implémentée différament si le logiciel tourne sous Intel (et donc que c'est la version compilée pour Intel qui est executée dans le package UB) ou tourne sous PPC

    Je ne vois en aucun cas en quoi ça pose problème d'utiliser les #xxx même si tu veux savoir sur quel processeur est exécuté ton code, puisque sur un processeur Intel c'est le code compilé Intel qi s'executera et sur un proc PPC le code PPC.
  • MathMath Membre
    09:36 modifié #12
    Merci Ali  <3 <br />
    je comprend les choses beaucoup mieux maintenant  :p
  • BruBru Membre
    09:36 modifié #13
    dans 1140975441:

    Ca ne dérange pas que les #xxx soient des flags influant sur la compilation et non pas le runtime dans le sens où on peut comme ici les utiliser pour modifier l'implémentation d'une fonction selon qu'elle sera compilée pour intel et PPC, vu qu'après on peut faire appel à  cette fonction pendant le Runtime, fonction qui sera implémentée différament si le logiciel tourne sous Intel (et donc que c'est la version compilée pour Intel qui est executée dans le package UB) ou tourne sous PPC

    Je ne vois en aucun cas en quoi ça pose problème d'utiliser les #xxx même si tu veux savoir sur quel processeur est exécuté ton code, puisque sur un processeur Intel c'est le code compilé Intel qi s'executera et sur un proc PPC le code PPC.


    Sauf que...

    Que se passe t'il si un développeur utilise ta méthode, compile en ppc (donc fabrique une appli non UB) et fait tourner tout ça sur MacIntel dans Rosetta ?

    .
  • AliGatorAliGator Membre, Modérateur
    février 2006 modifié #14
    Gasp.
    You got me, Bru.
    :o

    En fait l'idée des flags de compilation est de savoir si on est en train d'executer une version compilée PPC ou une version compilée Intel. Pas de savoir l'architecture courante de la machine.

    Dans ce cas tester l'endianness peut être une possibilité, mais je trouve pas ça très pro perso (je sais pas pourquoi, enfin je trouve que ça fait plutôt "hack" que véritable test en fait)

    Sinon j'ai trouvé ça dans NSProcessInfo, mais ça donne l'OS et pas le processeur (tiens, d'ailleurs, c'est étonnant ça... Cocoa serait prêt à  supporter Windows ou quoi ? bizarre ce truc...)

    Sinon j'utiliserais plutôt sysctl ou des trucs du genre pour récupérer les infos sur l'architecture courante.

    En creusant je suis sûr qu'on peut récupérer les informations de "Informations Système" avec une API Cocoa plus sympatique, non ?
    Que ce soit pour récupérer la version de OSX ou l'architecture de la machine où est executé le programme ? Y'a bien un truc, non ?
  • BruBru Membre
    09:36 modifié #15
    dans 1140986498:

    Dans ce cas tester l'endianness peut être une possibilité, mais je trouve pas ça très pro perso (je sais pas pourquoi, enfin je trouve que ça fait plutôt "hack" que véritable test en fait)


    En effet, pas propre du tout.
    En plus, puisque tu as évoqué sysctl, il existe une clé "hw.byteorder" qui retourne l'information du byte-ordering de manière officielle : 4321 pour big-endian et (sans doute) 1234 pour little-endian.


    dans 1140986498:

    Sinon j'utiliserais plutôt sysctl ou des trucs du genre pour récupérer les infos sur l'architecture courante.


    Effectivement, le truc est d'utiliser ou sysctl ou le gestalt manager.

    Pour sysctl, il n'y a pas (par l'instant et d'après la doc) de clé permettant de récupérer l'info sur le type d'architecture. Pourtant, Apple a diffusé une astuce permettant de savoir si le code PPC tourne en natif (donc sur un PowerPc) ou sous Rosetta (donc sous Intel). Cela passe par une clé ajoutée au dictionnaire de sysctl n'existant que sous MacIntel ("sysctl.proc_native").

    Pour gestalt, il y a  le sélecteur 'sysa' qui retourne l'architecture de la machine. Actuellement cela retourne 1 (gestalt68k) pour 68XXX, 2 (gestaltPowerPC) pour PowerPC, et 10 (gestaltIntel) pour Intel. Par contre, j'ai cru comprendre que si le code tourne dans Rosetta, 'sysa' retourne alors 2 au lieu de 10.

    Bref, c'est pas simple pour le moment, et cela montre que chez Apple, c'est encore le flou (du moins dans les docs).

    Ma préférence va tout de même pour l'utilisation du gestalt.

    .
  • BruBru Membre
    09:36 modifié #16
    dans 1140991144:

    Ma préférence va tout de même pour l'utilisation du gestalt.


    <br />{<br />&nbsp; &nbsp; OSErr erreur;<br />&nbsp; &nbsp; long architecture;<br /><br />&nbsp; &nbsp; erreur=Gestalt(&#39;sysa&#39;, &amp;architecture);<br /><br />&nbsp; &nbsp; if (architecture==gestalt68k)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;je tourne sur 68xxx, et c&#39;est carrémant pas normal&quot;);<br />&nbsp; &nbsp; }<br />	<br />&nbsp; &nbsp; else if (architecture==gestaltPowerPC)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;je tourne sur PPC, IBM for ever&quot;);<br />&nbsp; &nbsp; }<br /><br />&nbsp; &nbsp; else if (architecture==gestaltIntel)<br />	{<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;je tourne sur Intel, et Apple baisse sa culotte&quot;);<br />&nbsp; &nbsp; }<br />}<br />
    

    (il faudra sans doute ajouter le framework Carbon au projet)

    .
  • aranaudaranaud Membre
    09:36 modifié #17
    Et parmi toutes c'est méthodes, c'est là  quel la plus rapide.
  • 09:36 modifié #18
    Il y a aussi man arch et man 3 arch ;D

    Salut
  • AliGatorAliGator Membre, Modérateur
    février 2006 modifié #19
    En effet, [tt]extern const NXArchInfo * NXGetLocalArchInfo(void);[/tt] semble répondre au problème...
    man arch
  • maconnectmaconnect Membre
    09:36 modifié #20
    dans 1141024167:

    Et parmi toutes c'est méthodes, c'est là  quel la plus rapide.
    la seule qui soit vraiment bonne à  mon avis est celle des instructions préprocesseur.
    -(void)mafonction<br />{<br /> NSString *s=nil;<br />#ifdef _BIG_ENDIAN<br /> s=@&quot;action ppc&quot;;<br />#else<br /> s=@&quot;action intel&quot;;<br />#endif<br />}
    
  • AliGatorAliGator Membre, Modérateur
    09:36 modifié #21
    Oui je dirais que c'est la solution la plus simple que de tester l'endianness, mais pas la plus propre (on ne teste pas vraiment le processeur, mais on teste une de ses spécificités, ce qui à  mon sens est "risqué")

    Donc à  la limite tu peux tester l'endianness.
    Mais du coup pas avec les instructions du préprocesseur, qui sont évaluées lors de la compilation ce qui fait que comme me l'a justement fait remarquer Bru, si on est sous Rosetta, en train de faire tourner la version PPC, c'est le code PPC qui s'executera alors qu'on sera sous Intel.
    Et puis de toute façon si jamais on utilise les instructions préprocesseur, autant utilise __ppc__ comme macro plutôt que _BIG_ENDIAN

    Par contre, je pensais à  un truc : si on fait un UniversalBinary, on ne se trouvera jamais dans le cas où Rosetta fonctionnera, car la version Intel existera donc se lancera, non ?

    Ca reste je trouve vraiment une solution un peu bidon, car ça ne répond pas à  la question d'origine, mais bon pour le cas qui nous intéresse ça peut dépanner.
    Mais je persiste à  dire que c'est pas une bonne habitude :p
  • BruBru Membre
    09:36 modifié #22
    dans 1141024167:

    Et parmi toutes c'est méthodes, c'est là  quel la plus rapide.


    Pourquoi savoir ça ?

    Tu as peur que pendant l'exécution de ton appli, l'architecture change 1000 fois de PPC à  Intel et vice-versa ?

    Un appel une seule fois au lancement/initialisation de l'une des méthodes ci-dessus (gestalt ayant ma préférence car c'est la méthode officielle) avec mémorisation du résultat est largement suffisant.

    .
  • aranaudaranaud Membre
    09:36 modifié #23
    dans 1141076668:

    Pourquoi savoir ça ?

    La curiosité.
    Je suis étonné par le nombre de méthode différentes pour savoir si on fonctionne sur tell ou tell processeur.
  • MathMath Membre
    09:36 modifié #24
    dans 1141110578:

    dans 1141076668:

    Pourquoi savoir ça ?

    La curiosité.
    Je suis étonné par le nombre de méthode différentes pour savoir si on fonctionne sur tell ou tell processeur.


    Je suis aussi étonné par toutes ces méthodes :) mais ça laisse le choix .

    Merci à  tous.
  • molgowmolgow Membre
    09:36 modifié #25
    dans 1140869627:
    J'ai créé une application (Objective-c/Cocoa) utilisant un petit prog open source. J'ai compilé cet outil sur mon mac PPC sans aucun problème et je l'utilise dans mon programme.

    Sauf que maintenant avec les Mac Intel pour être universal binary je dois avoir deux versions de cet outil. Une version compilée sur PPC et une compilée sur Intel.


    Hello,

    Je ne comprends pas pourquoi ne pas simplement faire un petit exécutable universal binaries ?!
    J'ai développé un petit programme qui utilise aussi un petit exécutable binaire (de type standard tool), et je l'ai compilé pour que ça fonctionne sur PPC et Intel.

    La solution de compiler 2 binaires et de sélectionner à  l'exécution me semble compliquée.
  • MathMath Membre
    09:36 modifié #26
    J'aimerai bien savoir alors comment faire pour le compiler en universal binaries sachant qu'il n'a pas été créé avec xcode.

    Il s'agit de ce programme : http://www.mt-daapd.org/

    Si tu peux me dire comment faire ça serait sympa :)
  • molgowmolgow Membre
    09:36 modifié #27
    dans 1141465042:

    J'aimerai bien savoir alors comment faire pour le compiler en universal binaries sachant qu'il n'a pas été créé avec xcode.

    Il s'agit de ce programme : http://www.mt-daapd.org/

    Si tu peux me dire comment faire ça serait sympa :)


    Ah oui, en effet, c'est loin d'être aisé  ???
    Mais ça doit être possible malgré tout  :P
Connectez-vous ou Inscrivez-vous pour répondre.