Distinguer les processeurs Intel des processeurs Apple Silicon depuis nos programmes

Suite à un problème dont je ne parlerai pas ici, j'ai eu besoin de savoir si un programme Delphi exécuté sur macOS était en émulation Intel sur une puce Apple Silicon ou nativement dans un environnement Intel. Quelques recherches et tests plus tard j'en suis arrivé à cette fonction :

function isAppleSiliconProcessor: boolean;
begin
{$IFDEF MACOS}
  result := (_system(PAnsiChar('sysctl hw.optional.arm64 >null 2>&1')) = 0);
  // no error on exit = ARM64, error on exit = no ARM64
{$ELSE}
  result := false;
{$ENDIF}
end;

Pour l'utiliser dans vos programmes vous devez ajouter l'unité Posix.Stdlib, par exemple conditionnée comme ici :

uses
{$IFDEF MACOS}
  Posix.Stdlib,
{$ENDIF}
  System.SysUtils;

Normalement l'exécution des programmes FireMonkey compilés pour macOS fonctionnent en émulation Intel sans problème sur les Mac à base de processeur Apple Silicon, mais il peut arriver que l'on ait besoin de lancer d'autres programmes du système et pour ce faire il est utile de savoir si on les lance en direct (dans le mode émulation si notre programme l'est) ou nativement en forçant comme avec cet exemple :

procedure execCommand(cmd: ansistring);
begin
  if isAppleSiliconProcessor then
    cmd := '"/usr/bin/arch" -arm64e ' + cmd;
  writeln(cmd);
{$IFDEF MACOS}
  _system(PAnsiChar(cmd));
{$ELSE}
  // ...
{$ENDIF}
end;

execCommand('uname -m');

 


Mug Chinese New Year 2023 : year of the rabbitMug Pascal case in Alexandrie