cmake_configuration_types и сторонние библиотеки - PullRequest
2 голосов
/ 31 января 2020

Я пытаюсь создать пользовательский cmake_configuration_type, используя метод, описанный здесь Проблема, с которой я сталкиваюсь, заключается в правильном подключении сторонних библиотек. Например, когда я создаю пользовательскую конфигурацию, исполняемый файл неправильно связывается со сторонними библиотеками для финальной конфигурации. Некоторые связанные библиотеки находятся в режиме выпуска, а другие - в режиме отладки. Кто-нибудь подскажет мне, дает ли 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()

Основной. 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()

Спасибо за вашу помощь

1 Ответ

0 голосов
/ 05 февраля 2020

Итак, наконец я смог решить эту проблему с некоторыми изменениями в 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()

Ключом было использование функции MAP_IMPORTED_CONFIG_<CONFIG> в CMake.

...