简体   繁体   中英

Converting qmake to cmake, how do I set Debug vs Release, and similar configuration options?

I'll start by saying that I'm a total noob to cmake, but it's what most people use and I need to finally make the switch from qmake. I'm trying to convert the following project file:

# ----------------------------------------------------
# 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")

Now, this file is big and scary, so I've been slowly working through it to find analogous functionality between cmake and qmake. However, I'm stuck. I can't seem to wrap my head around how I would convert the following bit over:

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

For starters, it's not super clear to me which of the CONFIG options are even still necessary. Can I do away with adding qt , thread , debug_and_release , etc.? If not, then what would the equivalent functionality in cmake be?

Even trickier is the CONFIG(debug, debug|release): logic. Is there a way to have Debug vs. Release settings in cmake like I currently do? My end goal is to have cmake putting out an MSVC studio project exactly like my qmake setup is doing, so I'd appreciate all the help I can get.

how do I set Debug vs Release, and similar configuration options?

There are two common options. A plain 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()

But note that CMAKE_BUILD_TYPE and STREQUAL is case sensitive , so if someone does cmake.... -DCMAKE_BUILD_TYPE=release it will just fail. Some programmers work around that by first uppercasing the CMAKE_BUILD_TYPE and then working with uppercased value (or lowercasing). Anyway, another method is to use generator expressions and it looks better and ignores case:

target_compile_definitions(the_target PUBLIC
    $<$<CONFIG:DEBUG>:DEBUG_MODE>
    $<$<CONFIG:RELEASE>:QT_NO_DEBUG_OUTPUT>
)

There are also many CMAKE_BLA_BLA_<configuration> options, like CMAKE_C_FLAGS_DEBUG , CMAME_C_FLAGS_RELEASE etc.

c++latest # Add support for c++17.

Use set_target_properties(the_target PROPERTIES CXX_STANDARD 17 CXx_STANDARD_REQUIRED YES) or use CMAKE_CXX_STANDARD and CMAKE_CXX_STANDARD_REQUIRED variables.

and I do away with adding qt, thread

Use find_library to find a library. There are many find_package to find various common libraries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM