Преобразование qmake в cmake, как мне установить Debug vs Release и аналогичные параметры конфигурации?

#c #cmake #qmake

#c #cmake #qmake

Вопрос:

Я начну с того, что скажу, что я полный новичок в cmake, но это то, что использует большинство людей, и мне нужно, наконец, переключиться с qmake. Я пытаюсь преобразовать следующий файл проекта:

 # ----------------------------------------------------
# This file is generated by the Qt Visual Studio Tools.
# ------------------------------------------------------
# See: https://www.toptal.com/qt/vital-guide-qmake
# NOTE: Debug build should use /MDd runtime library, and release should use /MD (may be default for Qt)
# TODO: Convert to cmake: https://www.executionunit.com/blog/2014/01/22/moving-from-qmake-to-cmake/

message("Beginning qmake build of project_name.pro")

TEMPLATE = app
TARGET = project_name
QT  = core 
      opengl  
      gui 
      widgets 
      concurrent  # Mutexes/multithreading
      openglextensions 
      multimedia 
      gamepad  # Controller support
      network # TCP/IP

# Set compiler flags /////////////////////////////////////////////////////////////
QMAKE_CXXFLAGS  = /MP # Multiprocess compile, much faster

# MSVC versions after 15.3 are fickle with the flags required to use more modern c   variants
QMAKE_CXXFLAGS *= /std:c  17 # Add if not there, this may be the ticket
# QMAKE_CXXFLAGS  = -std=c  17 # For GCC/Clang
# QMAKE_CXXFLAGS  = -std=c  1z

# Set general configuration options /////////////////////////////////////////////////
CONFIG  = c  latest # Add support for c  17.
# CONFIG  = c  1z # another attempt at C  17 support
CONFIG  = qt # console # The target is a Qt application or library and requires the Qt library and header files
CONFIG  = thread # Thread support is enabled. This is enabled when CONFIG includes qt, which is the default.
CONFIG  = debug_and_release # Creates additional debug and release folders, but need it for debug

CONFIG(debug, debug|release){
    DESTDIR = ../app/debug
    DEFINES  = DEBUG_MODE
} 
else {
    DESTDIR = ../app/release
}

# Replace O2 flag with O3 flag
#CONFIG(release, debug|release) {
#    QMAKE_CXXFLAGS_RELEASE -= -O1
#   QMAKE_CXXFLAGS_RELEASE -= -O2
#   QMAKE_CXXFLAGS_RELEASE *= -O3
#}

# Do not display debug output in release mode
CONFIG(debug, debug|release) : CONFIG  = debug_info
CONFIG(release, debug|release) : DEFINES  = QT_NO_DEBUG_OUTPUT

CONFIG  = no_lflags_merge # Ensures that the list of libraries stored in the LIBS variable is not reduced to a list of unique values before it is used.
# CONFIG  = CONSOLE # makes this a console application
CONFIG -= flat # flattens file hierarchy, subtract if this is not desired

# Defines //////////////////////////////////////////////////////////////////////////
DEFINES  = _UNICODE _ENABLE_EXTENDED_ALIGNED_STORAGE WIN64 QT_DLL QT_OPENGL_LIB QT_OPENGLEXTENSIONS_LIB QT_WIDGETS_LIB
DEFINES  = DEVELOP_MODE
DEFINES  = LINALG_USE_EIGEN
INCLUDEPATH  = ./qt_generated 
    . 
    ./qt_generated/$(ConfigurationName) 
    
LIBS  = -lopengl32 
    -lglu32 
DEPENDPATH  = .


# Add Libraries ////////////////////////////////////////////////////////////////////
# Don't forget to add to unit tests project as well, or else Intellisense errors will carry over
# Include PythonQt and required libraries
# Maybe not needed here, since python.prf is included when PythonQt is built?
# Note that both windows and linux style library links work in windows
# LIBS  = -L$(PYTHON_LIB)/ -lpython$(PYTHON_VERSION) # L"PATH" adds PATH to library search directory list, and -lName loads library Name during linking

# Enable import <PythonQt.h>
# INCLUDEPATH  = $PWD/src/third_party/pythonqt

#include ( ../third_party/PythonQt/build/python.prf )   #Was pulled from  PythonQt build
include ( ../third_party/PythonQt/build/common.prf )  
include ( ../third_party/PythonQt/build/PythonQt.prf )  
#include ( ../third_party/PythonQt/build/PythonQt_QtAll.prf )  


# Compile against release version of python
CONFIG(debug, debug|release) : DEFINES  = PYTHONQT_USE_RELEASE_PYTHON_FALLBACK

# Eigen
INCLUDEPATH  = $PWD/src/third_party/eigen 
               $PWD/src/third_party/eigen/Eigen

# ASSIMP
# To be able to write <module.h>
INCLUDEPATH  = ../third_party/assimp/assimp-5.0.0/include
INCLUDEPATH  = ../third_party/assimp/assimp-5.0.0/build/include
CONFIG(debug, debug|release) : LIBS  = -L$PWD/lib/assimp -lassimp_d
CONFIG(release, debug|release) : LIBS  = -L$PWD/lib/assimp -lassimp

# PhysX
DEFINES  = PX_PHYSX_STATIC_LIB
INCLUDEPATH  = ../../PhysX/physx/include 
               ../../PhysX/pxshared/include
CONFIG(debug, debug|release) { 
    LIBS  = -L$PWD/lib/physx/debug -lPhysX_static_32
    LIBS  = -L$PWD/lib/physx/debug -lPhysXCharacterKinematic_static_32
    LIBS  = -L$PWD/lib/physx/debug -lPhysXCommon_static_32
    LIBS  = -L$PWD/lib/physx/debug -lPhysXCooking_static_32
    LIBS  = -L$PWD/lib/physx/debug -lPhysXExtensions_static_32
    LIBS  = -L$PWD/lib/physx/debug -lPhysXFoundation_static_32
    LIBS  = -L$PWD/lib/physx/debug -lPhysXPvdSDK_static_32
    LIBS  = -L$PWD/lib/physx/debug -lPhysXVehicle_static_32
}
CONFIG(release, debug|release) { 
    # Always needed
    LIBS  = -L$PWD/lib/physx/release -lPhysXCommon_static_32
    
    # Always needed
    LIBS  = -L$PWD/lib/physx/release -lPhysX_static_32
    
    # Always needed
    LIBS  = -L$PWD/lib/physx/release -lPhysXFoundation_static_32
    
    # To cook geometry data on the fly
    LIBS  = -L$PWD/lib/physx/release -lPhysXCooking_static_32
    
    # Other
    LIBS  = -L$PWD/lib/physx/release -lPhysXCharacterKinematic_static_32
    LIBS  = -L$PWD/lib/physx/release -lPhysXExtensions_static_32
    LIBS  = -L$PWD/lib/physx/release -lPhysXPvdSDK_static_32
    LIBS  = -L$PWD/lib/physx/release -lPhysXVehicle_static_32
}

# FreeType
INCLUDEPATH  =  ../third_party/freetype-2.10.1/include
CONFIG(debug, debug|release) : LIBS  = -L$PWD/lib/freetype/debug -lfreetype
CONFIG(release, debug|release) : LIBS  = -L$PWD/lib/freetype/release -lfreetype

# SoLoud
INCLUDEPATH  = ../third_party/soloud/include
CONFIG(debug, debug|release) { 
    LIBS  = -L$PWD/lib/soloud/debug -lsoloud_x86_d
    LIBS  = -L$PWD/lib/soloud/debug -lsoloud_static_x86_d
}
CONFIG(release, debug|release) { 
    LIBS  = -L$PWD/lib/soloud/release -lsoloud_x86
    LIBS  = -L$PWD/lib/soloud/release -lsoloud_static_x86
}


# Include Visual Leak Detector //////////////////////////////////////////////////////////////////
INCLUDEPATH  = "../third_party/Visual Leak Detector/include/"
LIBS         = -L"../third_party/Visual Leak Detector/lib/Win32"    
    
               
# Set directories //////////////////////////////////////////////////////////////////
MOC_DIR  = ./qt_generated/moc
OBJECTS_DIR  = ./qt_generated/obj
UI_DIR  = ./qt_generated/ui
RCC_DIR  = ./qt_generated

message("Loaded .pro files, now loading .pri")

# Load in library files for project
include(project_name.pri)

message("Loaded .pri files")

 

Теперь этот файл большой и страшный, поэтому я медленно работал над ним, чтобы найти аналогичную функциональность между cmake и qmake. Однако я застрял. Кажется, я не могу понять, как я мог бы преобразовать следующий бит:

 CONFIG  = c  latest # Add support for c  17.
CONFIG  = qt # console # The target is a Qt application or library and requires the Qt library and header files
CONFIG  = thread # Thread support is enabled. This is enabled when CONFIG includes qt, which is the default.
CONFIG  = debug_and_release # Creates additional debug and release folders, but need it for debug

CONFIG(debug, debug|release){
    DESTDIR = ../app/debug
    DEFINES  = DEBUG_MODE
} 
else {
    DESTDIR = ../app/release
}

# Do not display debug output in release mode
CONFIG(debug, debug|release) : CONFIG  = debug_info
CONFIG(release, debug|release) : DEFINES  = QT_NO_DEBUG_OUTPUT

CONFIG  = no_lflags_merge # Ensures that the list of libraries stored in the LIBS variable is not reduced to a list of unique values before it is used.
# CONFIG  = CONSOLE # makes this a console application
CONFIG -= flat # flattens file hierarchy, subtract if this is not desired

 

Для начала мне не совсем ясно, какие из параметров конфигурации все еще необходимы. Могу ли я отказаться от добавления qt , thread debug_and_release , и т.д.? Если нет, то какой будет эквивалентная функциональность в cmake?

CONFIG(debug, debug|release) : Логика еще сложнее. Есть ли способ иметь Debug против Настройки выпуска в cmake, как я делаю в настоящее время? Моя конечная цель — заставить cmake выпустить проект MSVC studio точно так же, как это делает моя настройка qmake, поэтому я был бы признателен за любую помощь, которую я могу получить.

Комментарии:

1. Is there a way Да. how do I set Debug vs Release, and similar configuration options? Должно быть объяснено в каком-нибудь приличном руководстве по cmake. Какое исследование вы провели?

2. Есть выражения генератора. Я не думаю, что перевод — это правильный путь. Вероятно, вы захотите начать с более простых примеров.

3. @KamilCuk Я искал в Интернете информацию о том, как настроить различные встроенные режимы в cmake, но это сложно, не зная, что именно я ищу. Если бы вы могли предоставить некоторую фактическую информацию вместо того, чтобы критиковать мой google-fu, это было бы замечательно.

4. Вы не настраиваете модули таким же образом вообще.

5. Вы, вероятно, хотите начать здесь: https://doc.qt.io/qt-5/cmake-get-started.html

Ответ №1:

как мне установить Debug vs Release и аналогичные параметры конфигурации?

Есть два распространенных варианта. Простой if :

 if(CMAKE_BUILD_TYPE STREQUAL "Debug")
   target_compile_definitions(the_target PUBLIC DEBUG_MODE)
elif(CMAKE_BUILD_TYPE STREQUAL "Release")
   target_compile_definitions(the_target PUBLIC QT_NO_DEBUG_OUTPUT)
endif()
 

Но обратите внимание, что CMAKE_BUILD_TYPE и STREQUAL чувствителен к регистру, поэтому, если кто-то это сделает cmake .... -DCMAKE_BUILD_TYPE=release , это просто завершится неудачей. Некоторые программисты обходят это, сначала вводя верхний регистр CMAKE_BUILD_TYPE, а затем работая со значением в верхнем регистре (или в нижнем регистре). В любом случае, другой метод заключается в использовании выражений генератора, и он выглядит лучше и игнорирует регистр:

 target_compile_definitions(the_target PUBLIC


lt;


lt;CONFIG:DEBUG>:DEBUG_MODE>


lt;


lt;CONFIG:RELEASE>:QT_NO_DEBUG_OUTPUT>
)

Есть также много CMAKE_BLA_BLA_<configuration> вариантов, например CMAKE_C_FLAGS_DEBUG , и т.д. CMAME_C_FLAGS_RELEASE

последняя версия c # Добавить поддержку c 17.

Используйте set_target_properties(the_target PROPERTIES CXX_STANDARD 17 CXx_STANDARD_REQUIRED YES) или используйте CMAKE_CXX_STANDARD CMAKE_CXX_STANDARD_REQUIRED переменные и .

и я отказываюсь от добавления qt, thread

Используется find_library для поиска библиотеки. Существует множество find_package различных распространенных библиотек.

Комментарии:

1. Большое спасибо, это очень полезно! Я немного почитаю выражения генератора, чтобы лучше понять синтаксис, но я понимаю суть того, что вы говорите. Я отмечу это как ответ.

2. Итак, если посмотреть на это подробнее, если бы я хотел добавить несколько определений для каждой конфигурации, я бы просто сделал что-то вроде этого?: target_compile_definitions(the_target PUBLIC $<$<CONFIG:DEBUG>:DEBUG_MODE OTHER_OPTION> $<$<CONFIG:RELEASE>:QT_NO_DEBUG_OUTPUT ANOTHER_OPTION> )

3. Или мне нравится сохранять по одному параметру на строку и делать отдельные $<$<CONFIG:RELEASE:QT_NO_DEBUG_OUTPUT> $<$<CONFIG:RELEASE>:ANOTHER_OPTION> . Со строками работать проще. (Я думаю, что у меня были проблемы с пробелами в выражениях генератора, но я не уверен, я стараюсь избегать пробелов)

4. Понял, я могу сделать это, чтобы быть в безопасности. Еще раз спасибо!