Обнаружение платформы в CMake - PullRequest
17 голосов
/ 16 марта 2012

Я добавил некоторые функции из boost::asio, что вызвало некоторые "предупреждения" компилятора:

Пожалуйста, определите _WIN32_WINNT или _WIN32_WINDOWS соответственно.

Эта проблемаздесь разобрались с здесь .Я хотел бы, чтобы CMake обнаруживал, когда я собираюсь на Windows, и делал соответствующие определения или аргументы командной строки.

Ответы [ 6 ]

27 голосов
/ 16 марта 2012

Внутри файла CMakeLists.txt вы можете сделать:

IF (WIN32)
  # set stuff for windows
ELSE()
  # set stuff for other systems
ENDIF()
22 голосов
/ 25 июля 2013

Вот простое решение.

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})
10 голосов
/ 24 октября 2016

Вот расширенная версия ответа KneLL, также проверяющая для 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 ("${verMajor}" MATCHES "10")
            # 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(CMAKE_SYSTEM_VERSION)
    endmacro(get_WIN32_WINNT)

    get_WIN32_WINNT(ver)
    add_definitions(-D_WIN32_WINNT=${ver})
endif(WIN32)
5 голосов
/ 16 марта 2012

Как указал karlphilip, вы можете использовать if(WIN32) для определения платформы.

У вас будет несколько возможностей для передачи определений препроцессора в приложение:

  • Используйте заголовок configure, который предварительно обрабатывается CMake configure_file . Преимущество этого подхода состоит в том, что все #define являются частью кода, а не среды сборки. Недостатком является то, что он требует (автоматической) предварительной обработки CMake
  • Использовать add_definitions . Это добавит флаг препроцессора для всех исходных файлов в проекте, так что это скорее быстрый и грязный подход.
  • Используйте свойство COMPILE_DEFINITIONS . Это позволяет детально контролировать определения для каждого файла (и даже для каждого конфига): set_property(SOURCE ${YOUR_SOURCE_FILES} APPEND PROPERTY COMPILE_DEFINITIONS YOUR_FLAG1 YOUR_FLAG2)

    В современных версиях CMake (2.8.12 и выше) вы также можете использовать для этого более удобную команду target_compile_definitions.

Я обычно предпочитаю последнее, но это в основном вопрос личного вкуса.

1 голос
/ 28 января 2016

Улучшенная версия ответа 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})

Версия KneLLs не работала в моем случае, потому что CMAKE_SYSTEM_VERSION был 6.3.9600, что привело к ${ver}=0x060306090000

Эта версия не будет работать для Windows 10 и более поздних версий. Нужно проверить, больше ли первое число, чем 9, и преобразовать его в правильное шестнадцатеричное значение.

0 голосов
/ 16 марта 2012

Вот что я придумала:

if(${WIN32})
#this method adds the necessary compiler flag
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=0x0501")
#this adds a preprocessor definition to the project
add_definitions(-D_WIN32_WINNT=0x0501)
endif()

Для работы с «предупреждением» boost :: asio либо определение препроцессора, либо флаг командной строки выполняют работу.

...