Determine bitness for Linux/OSX lazarus / 23-Operating Systems ---------------------------------------------------------------------- BigChimp · 2011-09-06 18:23 Hi all, For my version of https://bitbucket.org/reiniero/lazupdater_baremetal/, I want to know whether an operating system is 32 bit or 64 bit, so I can let the user choose between 32 and 64 bit compilers/binutils - if possible. For Windows, I found a function that does it, thanks to the German Lazarus forum: http://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide#Det ecting_bitness_at_runtime How can I detect if you're running on 32 or 64 bit Linux and OSX? (Bonus question: if not on x86 architecture, how can I detect which processor it's running on - but I think that's less pressing) Something like uname -a might work, but I don't know if the output can be parsed for all Linux distros and OSX. Linux: Don't really know if all Linux Code: [Select]unames will give the same 64 bit indication... On Linux, perhaps something in the /proc filesystem? Found http://www.velocityreviews.com/forums/t147757-how-to-detect-cpu- architecture-bitmode-32-bit-vs-64-bit-for-linux.html; paraphrased: Code: [Select]cat /proc/cpuinfo You will see some parameters with their description Under "flags" parameter various parameters?/names?, one of them: 1. "rm(real mode)": 16 bit processor 2. "tm(transparent mode)": 32 bit processor 3. "lm(long mode)": 64 bit processorWould this also apply to non-X86 architectures? (And yes, the obvious next question is, how do I detect Linux on ARM etc) OSX: On OSX, I saw a post by Shebuka mentioning system_profiler: http://www .lazarus.freepascal.org/index.php/topic,13109.msg71741.html#msg71741, but the questions are: what setting to query & is there a more elegant way of doing that? Saw another site http://osxdaily.com/2009/09/07/how-to-tell-if-youre- running-the-32-bit-or-64-bit-kernel-in-mac-os-x-snow-leopard/ that says: Code: [Select]uname -athis returns a line ending with: Code: [Select] i386 or Code: [Select] x86_64Any more elegant way? Ok, for completeness' sake & my records: other unixes (FreeBSD, Solaris): any tips? Thanks! ---------------------------------------------------------------------- Blaazen · 2011-09-06 18:45 Here (64-bit Linux): Code: [Select]$ uname -m x86_64 $ ---------------------------------------------------------------------- BigChimp · 2011-09-06 19:08 Thanks, Blaazen. Looking at e.g. http://serverfault.com/questions/63484/linux-what-are-the-possible- values-returned-by-uname-m-and-uname-p I found: Quotelist of architectures supported by "alsa" package, which I believe has all popular archs includedCode: [Select]i386 i686 x86_64 ia64 alpha amd64 arm armeb armel hppa m32r m68k mips mipsel powerpc ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc... and yes, who knows, maybe FPC compiles on s390 (IBM mainframe), as well Seems I'd be safe to just look for 64 for 64 bit, and if not present, assume 32 bit... What do you think? ---------------------------------------------------------------------- BigChimp · 2011-09-07 06:22 On OSX (running OSX Lion), I seem to be able to get results: - using uname From man uname: Code: [Select]-a      Behave as though all of the options -mnrsv were specified. -m      print the machine hardware name. -p      print the machine processor architecture name. Results: Code: [Select]Laptop:~ theuser$ uname -a Darwin Laptop.local 11.1.0 Darwin Kernel Version 11.1.0: Tue Jul 26 16:07:11 PDT 2011; root:xnu-1699.22.81~1/RELEASE_X86_64 x86_64 Laptop:~ theuser$ uname -m x86_64 Laptop:~ theuser$ uname -p i386 - using system_profiler Code: [Select]system_profiler SPSoftwareDataType | grep "64-bit Kernel and Extensions"gives Code: [Select]64-bit Kernel and Extensions: Yes So, which one would be most stable and easiest? To align with Linux, I think I'll go with Code: [Select]uname -m ---------------------------------------------------------------------- BigChimp · 2011-09-07 07:10 I'm started talking to myself here, but I think I'm having a good conversation  I think I found a solution, but haven't tested it for Linux/OSX/Unix yet, so comments welcome: Code: [Select]{$IFDEF Windows} function Is64bitOS: boolean; { Detect if we are running on a 64 bit or 32 bit operating system/kernel independently of bitness of this program, or actual hardware. Original source: http://www.delphipraxis.net/118485-ermitteln-ob-32-bit-oder-64-bit- betriebssystem.html modified for FreePascal in German Lazarus forum: http://www.lazarusforum.de/viewtopic.php?f=55&t=5287 } type   TIsWow64Process = function( // Type of IsWow64Process API fn       Handle: Windows.THandle; var Res: Windows.BOOL): Windows.BOOL; stdcall; var   IsWow64Result: Windows.BOOL; // Result from IsWow64Process   IsWow64Process: TIsWow64Process; // IsWow64Process fn reference begin   // Try to load required function from kernel32   IsWow64Process := TIsWow64Process(Windows.GetProcAddress(     Windows.GetModuleHandle('kernel32'), 'IsWow64Process'));   if Assigned(IsWow64Process) then   begin     // Function is implemented: call it     if not IsWow64Process(Windows.GetCurrentProcess, IsWow64Result) then       raise SysUtils.Exception.Create('IsWindows64: bad process handle');     // Return result of function     Result := IsWow64Result;   end   else     // Function not implemented: can't be running on Wow64     Result := False; end; {$ENDIF Windows} {$IF DEFINED(DARWIN) or DEFINED(Linux) or DEFINED(Unix)} function Is64bitOS: boolean; { Detect if we are running on a 64 bit or 32 bit operating system/kernel independently of bitness of this program, or actual hardware. Adapted from Lazarus forum post by Shebuka: http://www.lazarus.freepascal.org/index.php/topic,13109.msg71741.html# msg71741 } var   InfoProcess: TProcess;   path: string;   InfoResult: TStringList;   ResultLine: string;   NumRows, i: integer; begin   result := false; //fail by default   path := 'sh -c "uname -m"';   InfoProcess := Tprocess.Create(nil);   try     InfoProcess.CommandLine := path;     InfoProcess.Options := InfoProcess.Options + [poUsePipes, poWaitOnExit];     InfoProcess.Execute;   except     InfoProcess.Free;     exit; //result already was false...   end;   InfoResult := TStringList.Create;   try     InfoResult.LoadFromStream(InfoProcess.Output);   except     InfoResult.Free;     exit; //result already was false...   end;   InfoProcess.Terminate(0);   InfoProcess.Free;   NumRows := InfoResult.Count;   // Should be just one result; we'll take the first non-empty line   for i := 0 to NumRows - 1 do   begin     ResultLine:=trim(Inforesult[i]);     if ResultLine<>'' then     begin       //Note: we're no only testing x86 architecture!       //Don't know if s390 s390x are 64 bit, but not a big chance to encounter mainframes for now       if (       (ResultLine='x86_64') or       (ResultLine='amd64') or       (ResultLine='ia64') or       (ResultLine='ppc64')       ) then       begin         result:=true;       end       else       begin         //'Fail' if another, even unknown, architecture is used         result:=false;       end;       Break; //we're done.     end;   InfoResult.Free;   end; end; {$ENDIF} //Darwin, Linux, Unix ---------------------------------------------------------------------- Shebuka · 2011-09-07 09:05 I think that for your uses uname is just perfect, system_profile can give many info (like your IP, OS version/architecture ecc.), but it's much slower. ---------------------------------------------------------------------- marcov · 2011-09-07 10:55 Note that there is a baseunix.fpuname call, you don't need to call the runtime module. But maybe a fpuname from a 32-bit binary on a 64-bit system returns a 32-bit architecture description. How to detect that you are not in an emulation mode is harder (Linux binaries can run in a Linux emulation mode on most BSDs) ---------------------------------------------------------------------- franciscoluiz · 2013-01-01 13:31 mr Banana  ,  isn't simpler something like: Code: [Select]function TForm1.IsWindows: boolean; begin     {$IFDEF Windows}          Result  := true;     {$ENDIF}     {$IF DEFINED(DARWIN) or DEFINED(Linux) or DEFINED(Unix)}          Result  := false;     {$ENDIF} end; function TForm1.Is32b: boolean; begin     {$ifdef CPU32}          Result  := true;     {$ENDIF}     {$ifdef CPU64}          Result  := false;     {$ENDIF} end; ??? ---------------------------------------------------------------------- marcov · 2013-01-02 14:45 FreeBSD: [Toad] uname -m amd64 [Toad] uname -p amd64 [Toad]