Recently I'm creating a base library for all my gamedev adventures. It contains both very low-level features (allocator, string, vector, hashmap, errors etc) and reasonably middle-level features (like HTTP requests). Grabbing system information is rather high-level but very important, especially for OpenGL developer. It's very helpful if you can inform user that he just needs to update drivers.
Typical output:
[23:12:26] CPU : 8 x 2806 (2806) MHz (Intel(R) Core(TM) i7 CPU 930 @ 2.80GHz, FPU MMX SSE SSE2 SSE3 SSSE3 EST SSE4.1 SSE4.2 POPCNT HTT) [23:12:26] RAM : 7956MB/12278MB [23:12:26] GPU : NVIDIA GeForce GTX 460 [8.17.12.6658, 1-7-2011] :: NVIDIA Corporation GeForce GTX 460/PCI/SSE2 using OpenGL 4.1.0 [23:12:26] OS : Windows 7 (6.1 Service Pack 1) 64 bit
Many folks complain on Windows API, it's backwards compatiblity and overall misery. But while working on sysinfo program, I've actually learned how powerful it is. Few examples:
Memory
On Windows there is GlobalMemoryStatusEx function that returns accurate results, in 64-bit format even for 32-bit applications.
On Linux there is /proc/meminfo but its results are very hard to interpret and are different than results of free command. In the end, I've used free -mo | head -n 2 | tail -n 1. Pure magic (and pure hope that free output format won't change).
Mac OSX amused me. As you may or may not know, I'm an iOS developer. I thought that Mac will be quite similar to its iOS counterpart, maybe with API like [[NSSystem sharedSystem] freeMemory]. Hell no! To obtain memory statistics, you need to access Mach (Mac OSX kernel) layer, like this:
mach_port_t host_port;
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t pagesize;
vm_statistics_data_t vm_stat;
host_port = mach_host_self();
host_page_size(host_port, &pagesize);
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) return;
natural_t mem_used = (vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pagesize;
mem_free = vm_stat.free_count * pagesize;
mem_total = mem_used + mem_free;
mem_free /= 1024 * 1024;
mem_total /= 1024 * 1024;
GPU
On all platforms I query OpenGL for vendor, renderer and both (OGL and GLSL) version strings. But this doesn't include driver information. And each vendor/platform has his own vision of those strings.
So, on Windows I use SetupAPI to obtain precise GPU information. With SetupDiEnumDeviceInfo I search for FILE_DEVICE_VIDEO devices. This is useful, because it allows to check multi-GPU configurations or to bypass additional layers of (OpenGL) emulation (like for example screen capturing applications). And with SetupAPI there is standarized driver information available.
But on Linux it's not so easy. I have no Linux-specific programming knowledge (not that I've used SetupAPI before). I didn't even search for kernel API for this. I've just used lspci command and searched for VGA compatible controller. For NVIDIA cards I've found that I can obtain driver info from /proc/driver/nvidia/version. For ATI or other vendors -- I have no idea. Fortunately, ATI seems to include driver information in OpenGL version string (like 3.3.10237 Compatibility Profile Context) so this should not be a problem. But if you know better solution, please let me know.
On Mac OSX I didn't even try. In fact you can't install or update GPU drivers on Mac, because those are not provided by NVIDIA or other IHV, but by Great Apple itself -- and that also means that OpenGL stopped at 2.1 version. Hate you, Apple. There is a magic number in OpenGL version string: 2.1 NVIDIA-1.6.26 but I have no idea how could I compare this to Windows/Linux driver version.
Conclusions
There is other data as well, but as complex as examples above. For example to obtain OS data there is GetVersionEx and GetNativeSystemInfo in WinAPI (Native flavour returns 64-bit information for 32-bit apps on 64-bit Windows). On Linux/OSX I just use uname -a (Mac OSX have no variations, and on Linux it would be hard because each distribution has its own vision of versioning). CPU was fortunately mostly cross-platform, because I focus on __cpuid data (BTW -- do you know how to obtain HTT and/or number of cores from __cpuid?).
So my verdict is: Windows rocks, other platforms are pure chaos. At least in grabbing system information. But really, WinAPI may be awkward or "too backward compatible" but at least is simple and powerful.
BTW, if you want to test sysinfo program on your PC, you can grab Windows, Linux or Mac OSX version and share results in comments. This is not the most recent version but results would be helpful.