0

I want to try and build a source file only if I'm on a POSIX system (let's ignore cross-building for the sake of this question). I know how to check that I'm on a UNIX system; I know how to check for the presence of header files; but - how do I check for full POSIX conformance?

Notes:

  • For the sake of specificity, I want to check for POSIX.1-2008 and POSIX.1c.
  • I care about conformance in practice, not official certification.
  • You may assume CMake 3.25 or later (but if you can avoid that assumption, that's also nice).
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 3
    "I care about conformance in practice" - What do you mean by that? Do you mean that you want to check whether the platform you are running on has **all interfaces** which are defined in POSIX.1-2008 and they **behave** exactly like described in that standard? Only thorough verification can confirm that, which is definitely far more than common CMake can. – Tsyvarev Mar 27 '23 at 22:58
  • @Tsyvarev: Let's say that I trust superficial presumption of conformance. Like - all the relevant headers are present, perhaps some relevant binaries or libraries etc. – einpoklum Mar 28 '23 at 07:20
  • "all the relevant headers are present, perhaps some relevant binaries or libraries etc." - The only way to be sure about that is to check that all headers, binaries and libraries, described in the POSIX, are available on the build machine. CMake definitely does not store that list of all standard "interfaces". But you could easily take this list from the needed standard, and store it in your project. Then in `CMakeLists.txt` you could iterate over given list and use `CHECK_INCLUDE_FILE` or other CMake functions for check existence of corresponding interface. – Tsyvarev Mar 28 '23 at 21:02

1 Answers1

0

One way basic way to do this is just check CMAKE_HOST_SYSTEM_NAME (assuming you really want the host system name and not the target system name (CMAKE_HOST_NAME)):

Name of the OS CMake is running on.

On systems that have the uname command, this variable is set to the output of uname -s. Linux, Windows, and Darwin for macOS are the values found on the big three operating systems.

You can look at the doc comment in Modules/CMakeDetermineSystem.cmake to see the list of possible values.

The list of well-known operating systems that are POSIX certified is pretty short (https://en.wikipedia.org/wiki/POSIX#POSIX-certified). Of those that are listed in the Wikipedia page and the CMakeDetermineSystem.cmake, I see AIX, HP-UX, Darwin (macOS), SCO_SV (OpenServer 5), UnixWare,

I don't see INTEGRITY, VxWorks, or z/OS in the list of documented possible values, but that might just be a lapse in documentation and not necessarily that they aren't supported. From https://en.wikipedia.org/wiki/Uname#Examples, I see that uname -s for "z/OS USS" gives OS/390. That table doesn't have info for INTEGRITY or VxWare though.

Related on the point of there not being a lot of POSIX-certified OSes: Why are most Linux distributions not POSIX-compliant?

Something like this:

set(POSIX_SYSTEM_NAMES "AIX;HP-UX;Darwin;SCO_SV;UnixWare;OS/360")
if(NOT ("${CMAKE_HOST_SYSTEM_NAME}" IN_LIST POSIX_SYSTEM_NAMES))
  message(FATAL_ERROR "This system is not a fully POSIX compliant system")
endif()
starball
  • 20,030
  • 7
  • 43
  • 238