Forum > Operating Systems

Determine bitness for Linux/OSX

(1/2) > >>

BigChimp:
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#Detecting_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: ---uname
--- End code ---
s 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: ---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 processor
--- End code ---
Would 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: ---uname -a
--- End code ---
this returns a line ending with:
--- Code: --- i386
--- End code ---
or
--- Code: --- x86_64
--- End code ---
Any more elegant way?

Ok, for completeness' sake & my records: other unixes (FreeBSD, Solaris): any tips?

Thanks!

Blaazen:
Here (64-bit Linux):

--- Code: ---$ uname -m
x86_64
$

--- End code ---

BigChimp:
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:

--- Quote ---list of architectures supported by "alsa" package, which I believe has all popular archs included
--- End quote ---

--- Code: ---i386 i686 x86_64 ia64 alpha amd64 arm armeb armel hppa m32r m68k mips mipsel powerpc ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc
--- End code ---
... and yes, who knows, maybe FPC compiles on s390 (IBM mainframe), as well ;)
Seems I'd be safe to just look for <some letters>64 for 64 bit, and if not present, assume 32 bit...

What do you think?

BigChimp:
On OSX (running OSX Lion), I seem to be able to get results:
- using uname
From man uname:

--- Code: ----a      Behave as though all of the options -mnrsv were specified.
-m      print the machine hardware name.
-p      print the machine processor architecture name.

--- End code ---

Results:

--- Code: ---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
--- End code ---


- using system_profiler

--- Code: ---system_profiler SPSoftwareDataType | grep "64-bit Kernel and Extensions"
--- End code ---
gives

--- Code: ---64-bit Kernel and Extensions: Yes
--- End code ---

So, which one would be most stable and easiest? To align with Linux, I think I'll go with
--- Code: ---uname -m
--- End code ---

BigChimp:
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: ---{$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

--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version