web-dev-qa-db-fra.com

Détection de plateforme dans CMake

J'ai ajouté des fonctionnalités de boost::asio, ce qui a précipité certains "avertissements" du compilateur:

Veuillez définir _WIN32_WINNT ou _WIN32_WINDOWS de manière appropriée.

Ce problème a été résolu ici . J'aimerais que CMake détecte quand je construis sur Windows et fasse les définitions ou les arguments de ligne de commande appropriés.

21
2NinerRomeo

Voici une solution simple.

macro(get_WIN32_WINNT version)
    if (WIN32 AND CMAKE_SYSTEM_VERSION)
        set(ver ${CMAKE_SYSTEM_VERSION})
        string(REPLACE "." "" ver ${ver})
        string(REGEX REPLACE "([0-9])" "0\\1" ver ${ver})

        set(${version} "0x${ver}")
    endif()
endmacro()

get_WIN32_WINNT(ver)
add_definitions(-D_WIN32_WINNT=${ver})
22
KneLL

Dans le fichier CMakeLists.txt, vous pouvez faire:

IF (WIN32)
  # set stuff for windows
ELSE()
  # set stuff for other systems
ENDIF()
35
karlphillip

Voici une version étendue de la réponse de KneLL, vérifiant également Windows 10.

if(WIN32)
    macro(get_WIN32_WINNT version)
        if(CMAKE_SYSTEM_VERSION)
            set(ver ${CMAKE_SYSTEM_VERSION})
            string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
            string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
            # Check for Windows 10, b/c we'll need to convert to hex 'A'.
            if("${verMajor}" MATCHES "10")
                set(verMajor "A")
                string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
            endif()
            # Remove all remaining '.' characters.
            string(REPLACE "." "" ver ${ver})
            # Prepend each digit with a zero.
            string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
            set(${version} "0x${ver}")
        endif()
    endmacro()

    get_WIN32_WINNT(ver)
    add_definitions(-D_WIN32_WINNT=${ver})
endif()
10
squareskittles

Comme l'a souligné karlphilip, vous pouvez utiliser if(WIN32) pour la détection de la plateforme.

Vous aurez un certain nombre de possibilités pour passer les définitions de préprocesseur à l'application:

  • Utilisez un en-tête configure qui est prétraité par configure_file de CMake. Cette approche a l'avantage que tous les #define Font en fait partie du code et non de l'environnement de génération. L'inconvénient est qu'il nécessite une étape de prétraitement (automatique) par CMake
  • Utilisez add_definitions . Cela ajoutera l'indicateur de préprocesseur pour tous les fichiers source du projet, il s'agit donc plutôt d'une approche rapide et sale.
  • Utilisez la propriété COMPILE_DEFINITIONS . Cela permet un contrôle fin sur les définitions par fichier (et même par configuration): set_property(SOURCE ${YOUR_SOURCE_FILES} APPEND PROPERTY COMPILE_DEFINITIONS YOUR_FLAG1 YOUR_FLAG2)

    Dans les versions modernes de CMake (2.8.12 et supérieures), vous pouvez également utiliser la commande target_compile_definitions plus pratique pour cela.

Je préfère généralement ce dernier, mais c'est surtout une question de goût personnel.

5
ComicSansMS

Une version améliorée de la réponse KneLLs:

macro(get_WIN32_WINNT version)
    if (WIN32 AND CMAKE_SYSTEM_VERSION)
        set(ver ${CMAKE_SYSTEM_VERSION})
        string(REGEX REPLACE "^([0-9])[.]([0-9]).*" "0\\10\\2" ver ${ver})
        set(${version} "0x${ver}")
    endif()
endmacro()

get_WIN32_WINNT(ver)
add_definitions(-D_WIN32_WINNT=${ver})

La version KneLLs n'a pas fonctionné dans mon cas, car CMAKE_SYSTEM_VERSION était 6.3.9600 ce qui a entraîné ${ver}=0x060306090000

Cette version échouera cependant pour Windows 10 et versions ultérieures. Il faut vérifier si le premier nombre est supérieur à 9 et le convertir en la valeur hexadécimale correcte.

1
Twonky