mans
mans

Reputation: 18198

How to set CMAKE_TOOLCHAIN_FILE for when the project is created on windows only

I am trying to use vcpkg for Windows build when the CMake is also used for Linux build. The Linux build doesn't use vcpkg.

This is part of CMake that works on windows:

cmake_minimum_required(VERSION 3.5)
file(TO_CMAKE_PATH $ENV{LOCAL_ROOT} LOCAL_ROOT)
set(VCPKG_ROOT "${LOCAL_ROOT}/vcpkg-master")
set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
OPTION(USE_BOOST "use BOOST library" ON)
OPTION(CREATE_DLL "Create DLL or .so library" OFF)
OPTION(READ_GIT_HASH "read git sha1 hash for versioning" OFF)
project(ExtractOnctData)
if(MSVC)
   add_definitions (-D_USE_MATH_DEFINES)
   add_definitions (-DNOMINMAX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP ")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}  /MTd" )
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ot /openmp /MT" )
else(MSVC)
    #Use C++11
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    #Find and use standard libraries
    find_package(Threads REQUIRED)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif(MSVC)

but it breaks Linux build as the three vcpkg settings which not used in Linux build added to CMake.

If I do this:

cmake_minimum_required(VERSION 3.5)
if(MSVC)
    file(TO_CMAKE_PATH $ENV{LOCAL_ROOT} LOCAL_ROOT)
    set(VCPKG_ROOT "${LOCAL_ROOT}/vcpkg-master")
    set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
    set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
endif(MSVC)
OPTION(USE_BOOST "use BOOST library" ON)
OPTION(CREATE_DLL "Create DLL or .so library" OFF)
OPTION(READ_GIT_HASH "read git sha1 hash for versioning" OFF)
project(ExtractOnctData)
if(MSVC)
   add_definitions (-D_USE_MATH_DEFINES)
   add_definitions (-DNOMINMAX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP ")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}  /MTd" )
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ot /openmp /MT" )
else(MSVC)
    #Use C++11
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    #Find and use standard libraries
    find_package(Threads REQUIRED)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif(MSVC)

Then it doesn't work in Windows.

If I do this:

cmake_minimum_required(VERSION 3.5)
OPTION(USE_BOOST "use BOOST library" ON)
OPTION(CREATE_DLL "Create DLL or .so library" OFF)
OPTION(READ_GIT_HASH "read git sha1 hash for versioning" OFF)
project(ExtractOnctData)
if(MSVC)
    file(TO_CMAKE_PATH $ENV{LOCAL_ROOT} LOCAL_ROOT)
    set(VCPKG_ROOT "${LOCAL_ROOT}/vcpkg-master")
    set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
    set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
endif(MSVC)
if(MSVC)
   add_definitions (-D_USE_MATH_DEFINES)
   add_definitions (-DNOMINMAX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP ")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}  /MTd" )
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ot /openmp /MT" )
else(MSVC)
    #Use C++11
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    #Find and use standard libraries
    find_package(Threads REQUIRED)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif(MSVC)

It doesn't work in windows.

How Can I fix this problem?

Upvotes: 3

Views: 14306

Answers (1)

Alexander Neumann
Alexander Neumann

Reputation: 2028

A few things:

  1. you want to define CMAKE_TOOLCHAIN_FILE and VCPKG_TARGET_TRIPLET before your project(ExtractOnctData)call (so the third example will never work)
  2. You want to use if(WIN32) (target system) or if(CMAKE_HOST_WIN32) instead of if(MSVC). if(MSVC) is a compiler check and not a host/target system check.
  3. Remove OPTION(CREATE_DLL "Create DLL or .so library" OFF). This should be controlled by BUILD_SHARED_LIBS (https://cmake.org/cmake/help/v3.17/variable/BUILD_SHARED_LIBS.html). Make sure you export your functions correctly on Windows if you allow a DLL build
  4. find_package(Threads REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread"). Link target Threads::Threads instead and you can move it out of the if.
  5. Please don't add /MT(d) to CMAKE_CXX_FLAGS_(DEBUG|RELEASE) on Windows.
  6. Don't add -std=c++11 use target_compile_features instead (https://cmake.org/cmake/help/v3.17/manual/cmake-compile-features.7.html#compile-feature-requirements). Maybe add a compiler_(flag|requirements) interface target which you use to setup all those flags

Upvotes: 6

Related Questions