仅在 windows 上创建项目时如何设置 CMAKE_TOOLCHAIN_FILE
How to set CMAKE_TOOLCHAIN_FILE for when the project is created on windows only
我正在尝试将 vcpkg 用于 Windows 构建,而 CMake 也用于 Linux 构建。 Linux 构建不使用 vcpkg。
这是 CMake 的一部分,适用于 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)
但它破坏了 Linux 构建,因为 Linux 构建中未使用的三个 vcpkg 设置已添加到 CMake。
如果我这样做:
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)
那么它在Windows.
中不起作用
如果我这样做:
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)
它在 windows 中不起作用。
我该如何解决这个问题?
几件事:
- 您想在
project(ExtractOnctData)
调用之前定义 CMAKE_TOOLCHAIN_FILE
和 VCPKG_TARGET_TRIPLET
(因此第三个示例将永远不起作用)
- 您想使用
if(WIN32)
(目标系统)或 if(CMAKE_HOST_WIN32)
而不是 if(MSVC)
。 if(MSVC)
是编译器检查而不是 host/target 系统检查。
- 删除
OPTION(CREATE_DLL "Create DLL or .so library" OFF)
。这应该由 BUILD_SHARED_LIBS
(https://cmake.org/cmake/help/v3.17/variable/BUILD_SHARED_LIBS.html) 控制。如果允许 DLL 构建 ,请确保在 Windows 上正确导出函数
find_package(Threads REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
。 Link 改为目标 Threads::Threads,您可以将其移出 if。
- 请不要在 Windows 上将
/MT(d)
添加到 CMAKE_CXX_FLAGS_(DEBUG|RELEASE)
。
- 不要添加
-std=c++11
,而是使用 target_compile_features
(https://cmake.org/cmake/help/v3.17/manual/cmake-compile-features.7.html#compile-feature-requirements)。也许添加一个 compiler_(flag|requirements) 接口目标,你用它来设置所有这些标志
我正在尝试将 vcpkg 用于 Windows 构建,而 CMake 也用于 Linux 构建。 Linux 构建不使用 vcpkg。
这是 CMake 的一部分,适用于 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)
但它破坏了 Linux 构建,因为 Linux 构建中未使用的三个 vcpkg 设置已添加到 CMake。
如果我这样做:
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)
那么它在Windows.
中不起作用如果我这样做:
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)
它在 windows 中不起作用。
我该如何解决这个问题?
几件事:
- 您想在
project(ExtractOnctData)
调用之前定义CMAKE_TOOLCHAIN_FILE
和VCPKG_TARGET_TRIPLET
(因此第三个示例将永远不起作用) - 您想使用
if(WIN32)
(目标系统)或if(CMAKE_HOST_WIN32)
而不是if(MSVC)
。if(MSVC)
是编译器检查而不是 host/target 系统检查。 - 删除
OPTION(CREATE_DLL "Create DLL or .so library" OFF)
。这应该由BUILD_SHARED_LIBS
(https://cmake.org/cmake/help/v3.17/variable/BUILD_SHARED_LIBS.html) 控制。如果允许 DLL 构建 ,请确保在 Windows 上正确导出函数
find_package(Threads REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
。 Link 改为目标 Threads::Threads,您可以将其移出 if。- 请不要在 Windows 上将
/MT(d)
添加到CMAKE_CXX_FLAGS_(DEBUG|RELEASE)
。 - 不要添加
-std=c++11
,而是使用target_compile_features
(https://cmake.org/cmake/help/v3.17/manual/cmake-compile-features.7.html#compile-feature-requirements)。也许添加一个 compiler_(flag|requirements) 接口目标,你用它来设置所有这些标志