【问题标题】:cmake_configuration_types and 3rd party librariescmake_configuration_types 和 3rd 方库
【发布时间】:2020-02-05 18:41:58
【问题描述】:

我正在尝试使用here 描述的方法创建自定义cmake_configuration_type 我面临的问题是第 3 方库的正确链接。例如,当我创建自定义配置时,可执行文件未正确链接到最终配置的第三方库。链接到的一些库处于发布模式,而其他库处于调试模式。有人会指出我 CMake 是否提供了解决此问题的方法吗?

这是所要求的代码: CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)

project(DisplayImage)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake)

# Add configurations
include(SetupConfiguration)

# if (WIN32)
#   # Restrict the generated configuration to be what we configured above.
#   # No point creating project files for build types that will not compile.
#   # Note: it's set to FORCE so that both CMAKE_BUILD_TYPE and CMAKE_CONFIGURATION_TYPES match up.
#   set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE STRING "Build configurations to generate." FORCE)
#   mark_as_advanced(CMAKE_CONFIGURATION_TYPES)
# endif()
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")

######################################################################
# Choose C++ standard. Currently 11, as we try to support VS2013.
######################################################################
set(mp_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS 0)
set(CMAKE_CXX_STANDARD ${mp_CXX_STANDARD})
set(CMAKE_CXX_STANDARD_REQUIRED ON)

######################################################################
# Add Optional Requirements
######################################################################
if(WIN32)
  set(_library_sub_dir "bin")
else()
  set(_library_sub_dir "lib")
endif()

find_package( OpenCV REQUIRED )

add_executable(DisplayImage main.cpp)
target_link_libraries(DisplayImage ${OpenCV_LIBS})
if (CMAKE_CONFIGURATION_TYPES MATCHES Release)
  set_property(TARGET DisplayImage PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")
  set_target_properties(DisplayImage PROPERTIES RELEASE_POSTFIX "R")
elseif(CMAKE_CONFIGURATION_TYPES MATCHES Final)
  set_property(TARGET DisplayImage PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")
  set_target_properties(DisplayImage PROPERTIES RELEASE_POSTFIX "F")
  target_compile_definitions(DisplayImage PUBLIC -DFINAL)
elseif(CMAKE_CONFIGURATION_TYPES MATCHES Debug)
  set_property(TARGET DisplayImage PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug")
  set_target_properties(DisplayImage PROPERTIES DEBUG_POSTFIX "D")
endif()

main.cpp

#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char** argv )
{
    if ( argc != 2 )
    {
        printf("usage: DisplayImage.out <Image_Path>\n");
        return -1;
    }

    Mat image;
    image = imread( argv[1], 1 );

    if ( !image.data )
    {
        printf("No image data \n");
        return -1;
    }
    namedWindow("Display Image", WINDOW_AUTOSIZE );
    imshow("Display Image", image);

    waitKey(0);

    return 0;
}

在项目的CMake文件夹下有以下两个文件mpSetupMSVCRuntime.cmake

if(MSVC)
    set(variables
        CMAKE_C_FLAGS_DEBUG
        CMAKE_C_FLAGS_MINSIZEREL
        CMAKE_C_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_DEBUG
        CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_RELWITHDEBINFO
        )
  add_definitions(/bigobj)
  add_definitions(/MP)
endif()

和 SetupConfiguration.cmake

if(NOT SET_UP_CONFIGURATIONS_DONE)
    set(SET_UP_CONFIGURATIONS_DONE TRUE)

    get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
    if(isMultiConfig)
        set(CMAKE_CONFIGURATION_TYPES "Debug;Release;Final" CACHE STRING "" FORCE)
    else()
        if(NOT CMAKE_BUILD_TYPE)
            message("Defaulting to release build.")
            set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
        endif()
        set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPTSTRING "Choose the type of build")
        #set the valid options for cmake-gui drop-down list
        set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;Final")
    endif()
    # now set up the Final configuration
    set(CMAKE_C_FLAGS_FINAL "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "" FORCE)
    set(CMAKE_CXX_FLAGS_FINAL "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "" FORCE)
    set(CMAKE_EXE_LINKER_FLAGS_FINAL "${CMAKE_EXE_LINKER_FLAGS_RELEASE}" CACHE STRING "" FORCE)
    set(CMAKE_SHARED_LINKER_FLAGS_FINAL "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}" CACHE STRING "" FORCE)
    set(CMAKE_MODULE_LINKER_FLAGS_FINAL "${CMAKE_MODULE_LINKER_FLAGS_RELEASE}" CACHE STRING "" FORCE)

endif()

感谢您的帮助

【问题讨论】:

  • 您能否提供一个示例 CMake 文件,显示如何链接您的第三方库?一般来说,这就是 CMake generator expressions 的用途。
  • 如果没有您使用的库的示例,很难说出了什么问题。
  • 我还要补充一点,这只是一个例子,在实际项目中有几个第三方库。

标签: cmake visual-studio-2019


【解决方案1】:

所以最后我能够通过对 CMakeLists.txt 进行一些更改来解决这个问题

cmake_minimum_required(VERSION 3.5)

project(DisplayImage)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake)

# Add configurations
include(SetupConfiguration)

# if (WIN32)
#   # Restrict the generated configuration to be what we configured above.
#   # No point creating project files for build types that will not compile.
#   # Note: it's set to FORCE so that both CMAKE_BUILD_TYPE and CMAKE_CONFIGURATION_TYPES match up.
#   set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE STRING "Build configurations to generate." FORCE)
#   mark_as_advanced(CMAKE_CONFIGURATION_TYPES)
# endif()
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")

######################################################################
# Choose C++ standard. Currently 11, as we try to support VS2013.
######################################################################
set(mp_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS 0)
set(CMAKE_CXX_STANDARD ${mp_CXX_STANDARD})
set(CMAKE_CXX_STANDARD_REQUIRED ON)

######################################################################
# Add Optional Requirements
######################################################################
if(WIN32)
  set(_library_sub_dir "bin")
else()
  set(_library_sub_dir "lib")
endif()

find_package( OpenCV REQUIRED )
foreach(_cvlib ${OpenCV_LIBS})
  set_target_properties(${_cvlib} PROPERTIES MAP_IMPORTED_CONFIG_FINAL "RELEASE")
endforeach()
add_executable(DisplayImage main.cpp)
if (CMAKE_CONFIGURATION_TYPES MATCHES Release)
  target_link_libraries(DisplayImage ${OpenCV_LIBS})
  set_property(TARGET DisplayImage PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")
  set_target_properties(DisplayImage PROPERTIES RELEASE_POSTFIX "R")
elseif(CMAKE_CONFIGURATION_TYPES MATCHES Final)
  target_link_libraries(DisplayImage ${OpenCV_LIBS})
  set_property(TARGET DisplayImage PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Final>:Final>")
  set_target_properties(DisplayImage PROPERTIES RELEASE_POSTFIX "F")
  add_definitions(-DFINAL)
elseif(CMAKE_CONFIGURATION_TYPES MATCHES Debug)
  target_link_libraries(DisplayImage ${OpenCV_LIBS})
  set_property(TARGET DisplayImage PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug")
  set_target_properties(DisplayImage PROPERTIES DEBUG_POSTFIX "D")
endif()

关键是使用 CMake 的MAP_IMPORTED_CONFIG_&lt;CONFIG&gt; 功能。

【讨论】:

    猜你喜欢
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 2017-12-14
    • 2016-01-02
    • 2014-08-23
    • 2017-01-10
    相关资源
    最近更新 更多