Reputation: 45
What is the most elegant way to get hardware info, such us GPU name, CPU name, RAM in nim? I haven't found a library and not really sure how to implement it from pure nim
Upvotes: 1
Views: 727
Reputation: 382
When you want to search for Nim packages, you should look first at:
nimble search
functionality. Ex: nimble search hardware cpu
I have found the pkg/sysinfo package and pkg/psutil-nim which does probably what you want.Shell scripts are usually faster and more adapted for this kind of application. There are many CLI applications that you can adapt or leverage directly.
On Linux, you can get hostname and model information with hostnamectl
.
There are other utilities that aggregate hardware information, the most well-known is probably neofetch
. It has many variants, see: https://alternativeto.net/software/neofetch/
Based on neofetch, I have written a small script that works on Linux only:
import std/[strutils, strformat, osproc]
type
MyComputerInfo = object
os: string
host: string
kernel: string
cpu: string
gpu: string
proc cacheUnameInfo*(): tuple[os: string, host: string, kernel: string] =
## Only defined for posix systems
when defined(posix):
let (output, errorCode) = execCmdEx("uname -omnr")
if errorCode != 0:
echo fmt"`uname -omnr` command failed, with Error code: {errorCode}"
quit(2)
let outSeq: seq[string] = output.split(' ')
var arch: string = outSeq[3]
stripLineEnd(arch)
let
os = arch & ' ' & outSeq[2]
host = outSeq[0]
kernel = outSeq[1]
return (os, host, kernel)
proc getGpuInfo*(): string =
when defined(posix):
var (gpu_driver_name, exitCode) = execCmdEx("""lspci -nnk | awk -F ': ' \ '/Display|3D|VGA/{nr[NR+2]}; NR in nr {printf $2 ", "; exit}'""")
if exitCode == 0:
gpu_driver_name = gpu_driver_name.split(",")[0]
if gpu_driver_name == "nvidia":
var (gpu_name, exitCodeSmi) = execCmdEx("nvidia-smi --query-gpu=name --format=csv,noheader")
if exitCodeSmi != 0:
echo "nvidia-smi command failed with exit code: {exitCodeSmi}"
quit(2)
return gpu_name
return gpu_driver_name.toUpperAscii()
else:
echo fmt"GpuInfo error code: {exitCode}"
quit(2)
proc getCpuInfo*(): string =
when defined(posix):
var (cpu_name, _) = execCmdEx("""cat /proc/cpuinfo | awk -F '\\s*: | @' '/model name|Hardware|Processor|^cpu model|chip type|^cpu type/ { cpu=$2; if ($1 == "Hardware") exit } END { print cpu }' "$cpu_file" """)
return cpu_name
proc `$`(mci: MyComputerInfo): string =
## Nice Output of a `MyComputerInfo` object
for name, val in fieldPairs(mci):
if $val != "":
result.add name.capitalizeAscii()
result.add ": "
result.add ($val).strip(leading=false, chars = {'\n'})
result.add "\n"
result.strip(leading=false, chars = {'\n'})
when isMainModule:
var mci: MyComputerInfo
(mci.os, mci.host, mci.kernel) = cacheUnameInfo()
mci.gpu = getGpuInfo()
mci.cpu = getcpuInfo()
echo mci
On my computer, I get:
Os: GNU/Linux x86_64
Host: localhost
Kernel: 5.15.0-78-generic
Cpu: 11th Gen Intel(R) Core(TM) i5-1135G7
Gpu: HEWLETT-PACKARD COMPANY TIGERLAKE-LP GT2 [IRIS XE GRAPHICS] [103C:880D]
We could replace the awk's calls in execCmdEx
by Nim parsing procedures for more Nim purity. We could add a configurator (with a CLI parser, or a DSL) so that the user can select the options he wants to print out. I leave the rest to you.
Upvotes: 3