Detect underlying platform/flavour in Cmake
Asked Answered
N

7

28

Does anybody know any cmake variable or hook or something which can give me underlying platform name/flavour name on which it is getting executed ? e.g. Linux-CentOs Linux-Ubuntu Linux-SLES

I know cmake has "CMAKE_SYSTEM" variable but that doesn't help differentiating flavours of linux for e.g. Any help is appreciated.

edit : I just read that it can be done using lsb_release command ?

Notornis answered 13/11, 2014 at 22:5 Comment(0)
S
27

The following snippet populates the LSB_RELEASE_ID_SHORT cmake variable with information about the underlying Linux system:

find_program(LSB_RELEASE_EXEC lsb_release)
execute_process(COMMAND ${LSB_RELEASE_EXEC} -is
    OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

On Ubuntu, for example, it yields Ubuntu.

Sallysallyann answered 11/1, 2017 at 13:37 Comment(5)
Different distros put the same things in different places. This was the perfect way to include libraries using those distro-specific locations.Cambridge
Might want to wrap this with a succinct check for linux somehow. Just learning cmake myself.Underlinen
Tested on Ubuntu for ARM64 and it says No LSB modules are available.Marni
Do you have the lsb_release binary installed in your system? On Arch, for example, its package is called lsb-release.Sallysallyann
rocky linux 9 does not have lsb_releaseDebility
M
12

Slightly less convoluted than checking files on the filesystem is to deduce the best you can from the available CMAKE_SYSTEM vars. For instance a CMakeLists.txt file containing lines like this:

message("-- CMAKE_SYSTEM_INFO_FILE: ${CMAKE_SYSTEM_INFO_FILE}")
message("-- CMAKE_SYSTEM_NAME:      ${CMAKE_SYSTEM_NAME}")
message("-- CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
message("-- CMAKE_SYSTEM:           ${CMAKE_SYSTEM}")

string (REGEX MATCH "\\.el[1-9]" os_version_suffix ${CMAKE_SYSTEM})
message("-- os_version_suffix:      ${os_version_suffix}")

outputs this when I ran cmake . :

-- CMAKE_SYSTEM_INFO_FILE: Platform/Linux
-- CMAKE_SYSTEM_NAME:      Linux
-- CMAKE_SYSTEM_PROCESSOR: x86_64
-- CMAKE_SYSTEM:           Linux-2.6.32-573.7.1.el6.x86_64
-- os_version_suffix:      .el6

And for my situation, the .el6 was enough to differentiate.

Minnieminnnie answered 17/5, 2016 at 21:1 Comment(1)
You capture only one digit, "\\.el[1-9]+" would be better idea IMHO ;-)Eon
E
7

Likely, you have to write such a test yourself. Here's one of the possible examples, just googled: https://htcondor-wiki.cs.wisc.edu/index.cgi/fileview?f=build/cmake/FindLinuxPlatform.cmake&v=4592599fecc08e5588c4244e2b0ceb7d32363a56

However depending on your actual needs the test may be quite complex. For example Ubuntu as a Debian-based OS always has /etc/debian_version and many RPM-based OSes traditionally have /etc/redhat-release. There's a file /etc/os-release in the Linux Standard Base (LSB) specification, but for example on the localhost this file is empty for an unknown reason :)

Epifocal answered 13/11, 2014 at 22:59 Comment(3)
yeah the problem is quite complex and I am thinking of manually setting up the variable but just wanted to see if theree are any solutions out there.Notornis
Well, one of the possible implementation I've given above. For SuSE-based you may also look at /etc/SuSE-release Another possible solution is to detect "main flavours" (e.g. whether its RPM-, DEB- or <YOU-NAME-THE-PACKAGE-MANAGER>-based and then call a detected package manager and look for a specific package as described hereEpifocal
Note that /etc/os-release will work on all systemd-based distributions, at minimum.Rarefaction
P
6

I know this is an old question, but as of now, there is still no cmake built-in function to find this information in good detail. I've implemented a small utility function that uses lsb_release on Linux to find a number of relevant system details:

function(get_linux_lsb_release_information)
    find_program(LSB_RELEASE_EXEC lsb_release)
    if(NOT LSB_RELEASE_EXEC)
        message(FATAL_ERROR "Could not detect lsb_release executable, can not gather required information")
    endif()

    execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
    execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
    execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --codename OUTPUT_VARIABLE LSB_RELEASE_CODENAME_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)

    set(LSB_RELEASE_ID_SHORT "${LSB_RELEASE_ID_SHORT}" PARENT_SCOPE)
    set(LSB_RELEASE_VERSION_SHORT "${LSB_RELEASE_VERSION_SHORT}" PARENT_SCOPE)
    set(LSB_RELEASE_CODENAME_SHORT "${LSB_RELEASE_CODENAME_SHORT}" PARENT_SCOPE)
endfunction()

Add it to your CMakeLists.txt and use it like this:

if(CMAKE_SYSTEM_NAME MATCHES "Linux")
    get_linux_lsb_release_information()
    message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}")
endif()

If you need further details, check what else lsb_release can provide with lsb_release -a.

Note that not every Linux has lsb_release installed. Most systems provide it, but its not mandatory. On newer Ubuntu, for example, its the default on desktop installs, and required by ubuntu-minimal. If it should be missing on your machine, you can install it with sudo apt install lsb-release.

Precognition answered 3/9, 2020 at 12:12 Comment(0)
G
1

on my machine

CMAKE_SYSTEM_INFO_FILE == "Platform/Linux"
CMAKE_SYSTEM_NAME == "Linux"
CMAKE_SYSTEM == "Linux-<kernel version>"

obtained with cmake --system-information, I know of people that use said macros in their own CMakeLists.txt files so they work as expected, probably CMAKE_SYSTEM_NAME is what you really want but here you go, you get this 3 and the command to inspect the properties of your machine as far as cmake is concerned .

Goeselt answered 13/11, 2014 at 23:14 Comment(3)
Unfortunately a version of the Linux kernel is usually the least significant characteristic of a given Linux installation. Technically I could setup a really ancient kernel on my workstation. Well, likely then I would also need to downgrade or specifically compile LIBC... Well, with some "core software".Epifocal
@Epifocal that's why I added the command, that command gives you anything you need to know to compile your softwareGoeselt
Nope, I have a Ubuntu-based distro and it doesn't tell anything about that, it doesn't even tell me my actual distro (KDE Neon). Gotta use uname.Leal
K
1

Based on thiagowfx answer, If you want to get the codename of the distro (if it is available):

execute_process(COMMAND lsb_release -cs
    OUTPUT_VARIABLE RELEASE_CODENAME
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

E.g. in Ubuntu 14.04 the variable RELEASE_CODENAME will hold trusty.

Kolyma answered 3/1, 2018 at 15:6 Comment(0)
S
1
### find our os (wins, centos, ubuntu, etc)
set(VAR_OS "")
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
        MESSAGE(DEBUG "Linux")
        execute_process (
                COMMAND bash -c "awk -F= '/^ID=/{print $2}' /etc/os-release |tr -d '\n' | tr -d '\"'"
                OUTPUT_VARIABLE outOS
        )
        MESSAGE(DEBUG "Linux os: ${outOS}")
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
        MESSAGE(DEBUG "Windows")
        set(VAR_OS "wins")
ELSE()
        MESSAGE(FATAL "No OS detected!")
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
Solicit answered 17/7, 2020 at 19:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.