将 qmake 转换为 cmake,如何设置 Debug 与 Release 以及类似的配置选项?
Converting qmake to cmake, how do I set Debug vs Release, and similar configuration options?
首先我会说我是 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
对于初学者来说,我不是很清楚哪些 CONFIG 选项仍然是必要的。我可以取消添加 qt
、thread
、debug_and_release
等吗?如果不是,那么 cmake 中的等效功能是什么?
更棘手的是 CONFIG(debug, debug|release) :
逻辑。有没有办法像我目前那样在 cmake 中进行调试与发布设置?我的最终目标是让 cmake 推出一个 MSVC studio 项目,就像我的 qmake 设置所做的那样,所以我很感激我能得到的所有帮助。
how do I set Debug vs Release, and similar configuration options?
有两个常用选项。一个普通的 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
$<$<CONFIG:DEBUG>:DEBUG_MODE>
$<$<CONFIG:RELEASE>:QT_NO_DEBUG_OUTPUT>
)
还有很多CMAKE_BLA_BLA_<configuration>
选项,比如CMAKE_C_FLAGS_DEBUG
、CMAME_C_FLAGS_RELEASE
等
c++latest # Add support for c++17.
使用 set_target_properties(the_target PROPERTIES CXX_STANDARD 17 CXx_STANDARD_REQUIRED YES)
或使用 CMAKE_CXX_STANDARD
和 CMAKE_CXX_STANDARD_REQUIRED
变量。
and I do away with adding qt, thread
使用find_library
查找图书馆。有很多find_package
找各种常用库
首先我会说我是 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
对于初学者来说,我不是很清楚哪些 CONFIG 选项仍然是必要的。我可以取消添加 qt
、thread
、debug_and_release
等吗?如果不是,那么 cmake 中的等效功能是什么?
更棘手的是 CONFIG(debug, debug|release) :
逻辑。有没有办法像我目前那样在 cmake 中进行调试与发布设置?我的最终目标是让 cmake 推出一个 MSVC studio 项目,就像我的 qmake 设置所做的那样,所以我很感激我能得到的所有帮助。
how do I set Debug vs Release, and similar configuration options?
有两个常用选项。一个普通的 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
$<$<CONFIG:DEBUG>:DEBUG_MODE>
$<$<CONFIG:RELEASE>:QT_NO_DEBUG_OUTPUT>
)
还有很多CMAKE_BLA_BLA_<configuration>
选项,比如CMAKE_C_FLAGS_DEBUG
、CMAME_C_FLAGS_RELEASE
等
c++latest # Add support for c++17.
使用 set_target_properties(the_target PROPERTIES CXX_STANDARD 17 CXx_STANDARD_REQUIRED YES)
或使用 CMAKE_CXX_STANDARD
和 CMAKE_CXX_STANDARD_REQUIRED
变量。
and I do away with adding qt, thread
使用find_library
查找图书馆。有很多find_package
找各种常用库