我的 qmake 构建在调试构建中的速度是 cmake 的两倍多,为什么?
My qmake build is more than twice as fast in debug build as cmake, why?
所以,我正在将我的项目从 qmake 转换为 cmake,我即将完成!但是,至少在调试模式下,我的 qmake 构建运行速度提高了一倍以上。我想在两个构建配置中设置相同的编译标志,以便我比较苹果与苹果。
不幸的是,我并没有多少运气来弄清楚到底是什么导致了性能差异!我的 qmake 标志解决了这个问题:
/MP
/GS
/analyze-
/W3
/wd"4577"
/wd"4467"
/Zc:wchar_t
/I"."
/I"qt_generated"
/I"./qt_generated/Debug"
/I"..\third_party\Python38-32\include"
/I"..\third_party\PythonQt\src"
/I"..\third_party\pybind11\include"
/I"src\third_party\eigen"
/I"src\third_party\eigen\Eigen"
/I"..\third_party\assimp\assimp-5.0.0\include"
/I"..\third_party\assimp\assimp-5.0.0\build\include"
/I"..\..\PhysX\physx\include"
/I"..\..\PhysX\pxshared\include"
/I"..\third_party\freetype-2.10.1\include"
/I"..\third_party\soloud\include"
/I"..\third_party\Visual Leak Detector\include"
/I"C:\Qt.12.2\msvc2017\include"
/I"C:\Qt.12.2\msvc2017\include\QtOpenGL"
/I"C:\Qt.12.2\msvc2017\include\QtWidgets"
/I"C:\Qt.12.2\msvc2017\include\QtOpenGLExtensions"
/I"C:\Qt.12.2\msvc2017\include\QtMultimedia"
/I"C:\Qt.12.2\msvc2017\include\QtGamepad"
/I"C:\Qt.12.2\msvc2017\include\QtGui"
/I"C:\Qt.12.2\msvc2017\include\QtANGLE"
/I"C:\Qt.12.2\msvc2017\include\QtConcurrent"
/I"C:\Qt.12.2\msvc2017\include\QtNetwork"
/I"C:\Qt.12.2\msvc2017\include\QtCore"
/I"qt_generated\moc"
/I"qt_generated\ui"
/I"C:\VulkanSDK.0.51.0\include"
/I"C:\Qt.12.2\msvc2017\mkspecs\win32-msvc"
/I"C:\Program Files (x86)\Visual Leak Detector\include"
/Zi
/Gm-
/Od
/Fd"qt_generated\obj\vc141.pdb"
/Zc:inline
/fp:precise
/D "_WINDOWS"
/D "UNICODE"
/D "_UNICODE"
/D "WIN32"
/D "_ENABLE_EXTENDED_ALIGNED_STORAGE"
/D "DEBUG_MODE"
/D "WIN64"
/D "QT_DLL"
/D "QT_OPENGL_LIB"
/D "QT_OPENGLEXTENSIONS_LIB"
/D "QT_WIDGETS_LIB"
/D "DEVELOP_MODE"
/D "LINALG_USE_EIGEN"
/D "PYTHONQT_USE_RELEASE_PYTHON_FALLBACK"
/D "PX_PHYSX_STATIC_LIB"
/D "QT_MULTIMEDIA_LIB"
/D "QT_GAMEPAD_LIB"
/D "QT_GUI_LIB"
/D "QT_CONCURRENT_LIB"
/D "QT_NETWORK_LIB"
/D "QT_CORE_LIB"
/errorReport:prompt
/WX-
/Zc:forScope
/Gd
/Oy-
/MDd
/FC
/Fa"qt_generated\obj\"
/EHsc
/nologo
/Fo"qt_generated\obj\"
/Fp"qt_generated\obj\grand_blue_d.pch"
/diagnostics:classic
在尝试尽可能接近匹配后,我的 cmake 标志解决了这个问题:
/MP
/GS
/analyze-
/W3
/wd"4577"
/wd"4467"
/Zc:wchar_t
/I"C:\Users\me\Documents\Projects\my-engine\app"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine"
/I"C:\Users\me\Documents\Projects\my-engine\app\reverie_autogen\include_Debug"
/I"C:\Users\me\Documents\Projects\my-engine\third_party\Python38-32\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\pybind11\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\src\third_party\eigen"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\assimp\assimp-5.0.0\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\assimp\assimp-5.0.0\build\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\physx\physx\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\physx\pxshared\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\freetype-2.10.1\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\soloud\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\Visual Leak Detector\include"
/I"C:\Qt.12.2\msvc2017\include"
/I"C:\Qt.12.2\msvc2017\include\QtCore"
/I"C:\Qt.12.2\msvc2017\.\mkspecs\win32-msvc"
/I"C:\Qt.12.2\msvc2017\include\QtConcurrent"
/I"C:\Qt.12.2\msvc2017\include\QtGamepad"
/I"C:\Qt.12.2\msvc2017\include\QtGui"
/I"C:\Qt.12.2\msvc2017\include\QtANGLE"
/I"C:\Qt.12.2\msvc2017\include\QtOpenGLExtensions"
/I"C:\Qt.12.2\msvc2017\include\QtMultimedia"
/I"C:\Qt.12.2\msvc2017\include\QtNetwork"
/I"C:\Qt.12.2\msvc2017\include\QtMultimediaWidgets"
/I"C:\Qt.12.2\msvc2017\include\QtWidgets"
/I"C:\Program Files (x86)\Visual Leak Detector\include"
/Zi
/Gm-
/Od
/Fd"reverie.dir\Debug\vc141.pdb"
/Zc:inline
/fp:precise
/D "WIN32"
/D "_WINDOWS"
/D "DEBUG_MODE"
/D "_UNICODE"
/D "_ENABLE_EXTENDED_ALIGNED_STORAGE"
/D "WIN64"
/D "QT_DLL"
/D "QT_OPENGL_LIB"
/D "DEVELOP_MODE"
/D "LINALG_USE_EIGEN"
/D "_CRT_SECURE_NO_WARNINGS"
/D "PX_PHYSX_STATIC_LIB"
/D "QT_CORE_LIB"
/D "QT_CONCURRENT_LIB"
/D "QT_GAMEPAD_LIB"
/D "QT_GUI_LIB"
/D "QT_OPENGLEXTENSIONS_LIB"
/D "QT_MULTIMEDIA_LIB"
/D "QT_NETWORK_LIB"
/D "QT_MULTIMEDIAWIDGETS_LIB"
/D "QT_WIDGETS_LIB"
/D "CMAKE_INTDIR=\"Debug\""
/D "UNICODE"
/errorReport:prompt
/WX-
/Zc:forScope
/Gd
/Oy-
/MDd
/std:c++latest
/Fa"reverie.dir\Debug\"
/EHsc
/nologo
/Fo"reverie.dir\Debug\"
/Fp"reverie.dir\Debug\reverie.pch"
/diagnostics:classic
据我所知,这些应该具有相同的性能!关于我的 qmake 构建如何变得如此快,有什么想法吗?
编辑:为了更有趣,这是我的 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 my_project.pro")
TEMPLATE = app
TARGET = my_project
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 ////////////////////////////////////////////////////////////////////
INCLUDEPATH += ../third_party/pybind11/include
# 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(my_project.pri)
message("Loaded .pri files")
和我的 cmake 项目文件:
# CMake build for the Reverie Engine
# To run cmake, add cmake/bin directory to system path
## TODO:
## Implement source_group, for organizing in IDE, see:
## TODO: Remove DLLs from this folder, as they are not needed
message( STATUS "---------Beginning cmake build of Reverie Engine---------")
# MACROS =================================================================
macro(remove_flag_from_target _target _flag)
get_target_property(_target_cxx_flags ${_target} COMPILE_OPTIONS)
if(_target_cxx_flags)
list(REMOVE_ITEM _target_cxx_flags ${_flag})
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${_target_cxx_flags}")
endif()
endmacro()
# Project-level setup ====================================================
project( Reverie ) # TODO: Set version
cmake_minimum_required( VERSION 3.16 )
set(TARGET_NAME "reverie") # See:
message (STATUS "--------- Set target ${TARGET_NAME}---------")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON) # Saves having to use QT5_WRAP_CPP
set(CMAKE_AUTORCC ON) # Saves having to use QT5_ADD_RESOURCES
set(CMAKE_AUTOUIC ON) # Saves having to use QT5_WRAP_UI
# Set compiler flags =====================================================
# Use C++20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Multiprocess compiler, disable specific warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /wd4577 /wd4467")
# Remove unwanted flags
STRING (REGEX REPLACE "[/|-]RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
STRING (REGEX REPLACE "[/|-]Ob0" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
STRING (REGEX REPLACE "[/|-]GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# Set paths to find Qt ===================================================
# Find Qt itself
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(CMAKE_PREFIX_PATH "C:\Qt\5.12.2\msvc2017")
else()
message (WARNING "-------- System not supported ---------")
endif()
# Find UI files
# See:
set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ui")
# Find Required Qt Libraries =============================================
find_package(Qt5 COMPONENTS Core REQUIRED)# Core stuff
find_package(Qt5 COMPONENTS Concurrent REQUIRED) # For threading
find_package(Qt5 COMPONENTS Gamepad REQUIRED) # Controller support
find_package(Qt5 COMPONENTS Gui REQUIRED) # For OpenGL integration
find_package(Qt5 COMPONENTS OpenGLExtensions REQUIRED)
# find_package(Qt5OpenGL) # OpenGL should come from GUI
find_package(Qt5 COMPONENTS Multimedia REQUIRED) # Multimedia capabilities
find_package(Qt5 COMPONENTS MultimediaWidgets REQUIRED)
find_package(Qt5 COMPONENTS Widgets REQUIRED) # For widgets
# OpenGL libraries
# See:
find_package(OpenGL REQUIRED) # enforces as a requirement
# find_library(OPENGL_LIB names opengl32) # Also valid
# find_library(GLU_LIB names glu32) # Also valid
# Set build mode directory options ========================================
# add_definitions(-DAPPLETTUTORIAL1_LIBRARY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/release)
# Set directories to find libraries, need to do this before add_executable for desired target
# link_directories(${CMAKE_SOURCE_DIR} "${CMAKE_SOURCE_DIR}/lib")
file(TO_CMAKE_PATH "$ENV{PYTHON_LIB}" ENV_PYTHON_LIB)
message(STATUS "Setting link directory ${ENV_PYTHON_LIB}")
link_directories(${ENV_PYTHON_LIB})
# Works as alternative, but does not solve any of my runtime problems
# set(PYTHON_QT_PATH "${CMAKE_SOURCE_DIR}/../third_party/PythonQt")
# set(PYTHON_QT_LIB_PATH "${PYTHON_QT_PATH}/lib")
# link_directories(${PYTHON_QT_LIB_PATH})
# Build EXE ===============================================================
# Get all source files, headers, resources, and UI (forms) from src subdirectory
# See:
## TODO: Maybe don't include headers as source?, see
message (STATUS "-------- Finding source, header, resource, UI files relative to ${CMAKE_SOURCE_DIR} ---------")
file(GLOB_RECURSE MY_SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.cpp" "src/*.h"
"resources/*.qrc" "ui/*.ui")
message (STATUS "=========== FOUND FILES =============")
message (STATUS "${MY_SOURCES}")
message (STATUS "=========== END FILES ===============")
# Generate release PDB
#
add_compile_options("$<$<NOT:$<CONFIG:Debug>>:/Zi>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/DEBUG>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/OPT:REF>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/OPT:ICF>")
# Add an executable to be built from sources variable
add_executable(${TARGET_NAME} ${MY_SOURCES})
# Add compile definitions to the target ===================================
# Set options based on debug or release mode
# Generator expression, see:
#
# https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html
set(DEBUG_DEFINITIONS "DEBUG_MODE")
set(RELEASE_DEFINITIONS "QT_NO_DEBUG_OUTPUT")
target_compile_definitions(${TARGET_NAME} PUBLIC
$<$<CONFIG:DEBUG>:${DEBUG_DEFINITIONS}>
$<$<CONFIG:RELEASE>:${RELEASE_DEFINITIONS}>
)
# Remove unwanted flags ===================================================
# Doesn't work
# remove_flag_from_target(${TARGET_NAME} -RTC1)
# Pre-processor Defines ===================================================
add_definitions(-D_UNICODE -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DLL -DQT_OPENGL_LIB)
add_definitions(-DDEVELOP_MODE)
add_definitions(-DLINALG_USE_EIGEN)
# Disable warnings about deprecated things, like using strcpy (sorry, not sorry)
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
# Add compile options to the target =======================================
# target_compile_options(${TARGET_NAME} PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
# target_compile_options(${TARGET_NAME} PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
# Link Required Qt modules to main target =================================
# This MUST come after add_executable and find_package for each module
# Essentially, target_link_libraries links the two specified libraries
#
target_link_libraries(${TARGET_NAME} OpenGL::GL OpenGL::GLU)
target_link_libraries(${TARGET_NAME} Qt5::Core)
target_link_libraries(${TARGET_NAME} Qt5::Concurrent)
target_link_libraries(${TARGET_NAME} Qt5::Gamepad)
target_link_libraries(${TARGET_NAME} Qt5::Gui)
target_link_libraries(${TARGET_NAME} Qt5::OpenGLExtensions) # TODO: Probably unnecessary, remove
target_link_libraries(${TARGET_NAME} Qt5::Multimedia)
target_link_libraries(${TARGET_NAME} Qt5::MultimediaWidgets)
target_link_libraries(${TARGET_NAME} Qt5::Widgets)
# Add additional libraries ================================================
# Add a default search locations
# TODO: link_directories takes generators, so maybe split into debug and release that way
message(STATUS "Default library search directories: ${CMAKE_SOURCE_DIR}/lib ${CMAKE_SOURCE_DIR}/lib/assimp")
# Include directories:
#
# Linking libraries:
# ****
#
# Python
message (STATUS "=========== Including Python =============")
# To eliminate conflict with "slots" keyword: PyType_Slot *slots; /* terminated by slot==0. */
# Equivalent to CONFIG += no_keywords in qmake
# add_definitions(-DQT_NO_KEYWORDS)
# For system versions, see:
#
if(DEFINED ENV{PYTHON_VERSION})
set(PYTHON_VERSION $ENV{PYTHON_VERSION})
else()
if(WIN32)
# for Windows operating system in general
# if(MSVC OR MSYS OR MINGW) # for detecting Windows compilers
set(PYTHON_VERSION 38)
elseif(APPLE)
# for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
elseif(UNIX AND NOT APPLE)
# For Linux, BSD, Solaris, Minix
message(STATUS "Setting UNIX python version")
set(PYTHON_VERSION 3.8)
else()
message( WARNING "Unrecognized operating system")
endif()
endif()
message (STATUS "PYTHON VERSION $ENV{PYTHON_VERSION}")
# Set up include paths and libraries for Python itself
if(WIN32)
# for Windows operating system in general
# if(MSVC OR MSYS OR MINGW) # for detecting Windows compilers
# Convert paths to CMAKE-friendly versions
file(TO_CMAKE_PATH "$ENV{PYTHON_PATH}" ENV_PYTHON_PATH)
# Link Python
# Debug DLL fails to import third party modules, so always use release
target_include_directories(${TARGET_NAME} PRIVATE "${ENV_PYTHON_PATH}/include")
message(STATUS "Python include path for windows is ${ENV_PYTHON_PATH}/include")
message(STATUS "Python path is ${ENV_PYTHON_PATH}")
# find_library(PYTHON_DEBUG_LIB NAMES "python${PYTHON_VERSION}_d" HINTS ${ENV_PYTHON_LIB})
find_library(PYTHON_RELEASE_LIB NAMES "python${PYTHON_VERSION}" HINTS ${ENV_PYTHON_LIB})
# message(STATUS "Linking Python with debug path ${PYTHON_DEBUG_LIB} and release path ${PYTHON_RELEASE_LIB}")
target_link_libraries(${TARGET_NAME}
debug ${PYTHON_RELEASE_LIB} optimized ${PYTHON_RELEASE_LIB}
)
elseif(APPLE)
# for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
message (STATUS "BUILDING FOR APPLE")
# Include library directory
target_include_directories(${TARGET_NAME} PRIVATE "/System/Library/Frameworks/Python.framework/Headers")
# Find library with name Python, and link
find_library(PYTHON_LIBRARY_PATH NAMES "Python")
target_link_libraries(${TARGET_NAME}
${PYTHON_LIBRARY_PATH}
)
elseif(UNIX AND NOT APPLE)
# For Linux, BSD, Solaris, Minix
message (STATUS "BUILDING FOR UNIX")
execute_process(COMMAND python${PYTHON_VERSION}-config --embed --libs
OUTPUT_VARIABLE PYTHON_LIBRARY_PATH
RESULT_VARIABLE FAILED_TO_DETECT_PYTHON
)
if(FAILED_TO_DETECT_PYTHON)
message (WARNING "Failed to detect Python")
else()
# Set library path
target_link_libraries(${TARGET_NAME} ${PYTHON_LIBRARY_PATH})
endif()
else()
message( WARNING "Unrecognized operating system")
endif()
# PYBIND
message (STATUS "=========== Including PYBIND =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/pybind11/include")
# EIGEN
message (STATUS "=========== Including Eigen at ${CMAKE_SOURCE_DIR}/src/third_party/eigen =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/src/third_party/eigen")
# ASSIMP
message (STATUS "=========== Including ASSIMP =============")
target_include_directories(${TARGET_NAME} PRIVATE
"${CMAKE_SOURCE_DIR}/../third_party/assimp/assimp-5.0.0/include"
"${CMAKE_SOURCE_DIR}/../third_party/assimp/assimp-5.0.0/build/include")
find_library(ASSIMP_DEBUG_LIB NAMES assimp_d HINTS "${CMAKE_SOURCE_DIR}/lib/assimp")
find_library(ASSIMP_LIB NAMES assimp HINTS "${CMAKE_SOURCE_DIR}/lib/assimp")
target_link_libraries(${TARGET_NAME}
debug ${ASSIMP_DEBUG_LIB} optimized ${ASSIMP_LIB})
# PhysX
message (STATUS "=========== Including PhysX as a static library =============")
add_definitions(-DPX_PHYSX_STATIC_LIB)
target_include_directories(${TARGET_NAME} PRIVATE
"${CMAKE_SOURCE_DIR}/../third_party/physx/physx/include"
"${CMAKE_SOURCE_DIR}/../third_party/physx/pxshared/include")
set( PHYSX_LIBRARY_DEBUG_DIR "${CMAKE_SOURCE_DIR}/lib/physx/debug")
set( PHYSX_LIBRARY_RELEASE_DIR "${CMAKE_SOURCE_DIR}/lib/physx/release")
message (STATUS "Debug directory is ${PHYSX_LIBRARY_DEBUG_DIR}")
target_link_libraries(${TARGET_NAME}
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysX_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysX_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXCharacterKinematic_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXCharacterKinematic_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXCommon_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXCommon_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXCooking_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXCooking_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXExtensions_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXExtensions_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXFoundation_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXFoundation_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXPvdSDK_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXPvdSDK_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXVehicle_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXVehicle_static_32.lib"
)
# FreeType
message (STATUS "=========== Including FreeType =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/freetype-2.10.1/include")
find_library(FREETYPE_DEBUG_LIB NAMES freetype HINTS "${CMAKE_SOURCE_DIR}/lib/freetype/debug")
find_library(FREETYPE_RELEASE_LIB NAMES freetype HINTS "${CMAKE_SOURCE_DIR}/lib/freetype/release")
target_link_libraries(${TARGET_NAME}
debug ${FREETYPE_DEBUG_LIB} optimized ${FREETYPE_RELEASE_LIB})
# SoLoud
message (STATUS "=========== Including SoLoud =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/soloud/include")
find_library(SOLOUD_DEBUG_LIB NAMES soloud_x86_d HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/debug")
find_library(SOLOUD_RELEASE_LIB NAMES soloud_x86 HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/release")
find_library(SOLOUD_STATIC_DEBUG_LIB NAMES soloud_static_x86_d HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/debug")
find_library(SOLOUD_STATIC_RELEASE_LIB NAMES soloud_static_x86 HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/release")
target_link_libraries(${TARGET_NAME}
debug ${SOLOUD_DEBUG_LIB} optimized ${SOLOUD_RELEASE_LIB}
debug ${SOLOUD_STATIC_DEBUG_LIB} optimized ${SOLOUD_STATIC_RELEASE_LIB}
)
# Visual Leak Detector
# See:
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/Visual Leak Detector/include/")
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
message(STATUS "=========== Including 64 Bit VLD =============")
# Is 64 bit
find_library(VLD_LIB NAMES vld HINTS "${CMAKE_SOURCE_DIR}/../third_party/Visual Leak Detector/lib/Win64")
target_link_libraries(${TARGET_NAME} ${VLD_LIB})
else()
# Is 32 Bit
message(STATUS "=========== Including 32 Bit VLD =============")
find_library(VLD_LIB NAMES vld HINTS "${CMAKE_SOURCE_DIR}/../third_party/Visual Leak Detector/lib/Win32")
target_link_libraries(${TARGET_NAME} ${VLD_LIB})
endif()
编辑:所以,已经过去几周了,我在弄清楚这里发生了什么方面完全没有取得任何进展。我已经为这两个构建系统生成了一些详细的报告,which can be found here. 到目前为止,没有任何线索对我来说很突出。事实上,我什至没有在报告中看到任何表明我的新构建系统速度变慢的信息!如果我没看错,应该会更快。
编辑 2:这也是我的链接器选项。 The old way, and the new way.
我明白了!! cmake 将我的应用程序构建为控制台应用程序,而不是 Windows 应用程序。在我的 cmake 构建中用 add_executable(${TARGET_NAME} WIN32 ${MY_SOURCES})
替换 add_executable(${TARGET_NAME} ${MY_SOURCES})
使性能匹配。今天学到了新东西,谢谢大家
所以,我正在将我的项目从 qmake 转换为 cmake,我即将完成!但是,至少在调试模式下,我的 qmake 构建运行速度提高了一倍以上。我想在两个构建配置中设置相同的编译标志,以便我比较苹果与苹果。
不幸的是,我并没有多少运气来弄清楚到底是什么导致了性能差异!我的 qmake 标志解决了这个问题:
/MP
/GS
/analyze-
/W3
/wd"4577"
/wd"4467"
/Zc:wchar_t
/I"."
/I"qt_generated"
/I"./qt_generated/Debug"
/I"..\third_party\Python38-32\include"
/I"..\third_party\PythonQt\src"
/I"..\third_party\pybind11\include"
/I"src\third_party\eigen"
/I"src\third_party\eigen\Eigen"
/I"..\third_party\assimp\assimp-5.0.0\include"
/I"..\third_party\assimp\assimp-5.0.0\build\include"
/I"..\..\PhysX\physx\include"
/I"..\..\PhysX\pxshared\include"
/I"..\third_party\freetype-2.10.1\include"
/I"..\third_party\soloud\include"
/I"..\third_party\Visual Leak Detector\include"
/I"C:\Qt.12.2\msvc2017\include"
/I"C:\Qt.12.2\msvc2017\include\QtOpenGL"
/I"C:\Qt.12.2\msvc2017\include\QtWidgets"
/I"C:\Qt.12.2\msvc2017\include\QtOpenGLExtensions"
/I"C:\Qt.12.2\msvc2017\include\QtMultimedia"
/I"C:\Qt.12.2\msvc2017\include\QtGamepad"
/I"C:\Qt.12.2\msvc2017\include\QtGui"
/I"C:\Qt.12.2\msvc2017\include\QtANGLE"
/I"C:\Qt.12.2\msvc2017\include\QtConcurrent"
/I"C:\Qt.12.2\msvc2017\include\QtNetwork"
/I"C:\Qt.12.2\msvc2017\include\QtCore"
/I"qt_generated\moc"
/I"qt_generated\ui"
/I"C:\VulkanSDK.0.51.0\include"
/I"C:\Qt.12.2\msvc2017\mkspecs\win32-msvc"
/I"C:\Program Files (x86)\Visual Leak Detector\include"
/Zi
/Gm-
/Od
/Fd"qt_generated\obj\vc141.pdb"
/Zc:inline
/fp:precise
/D "_WINDOWS"
/D "UNICODE"
/D "_UNICODE"
/D "WIN32"
/D "_ENABLE_EXTENDED_ALIGNED_STORAGE"
/D "DEBUG_MODE"
/D "WIN64"
/D "QT_DLL"
/D "QT_OPENGL_LIB"
/D "QT_OPENGLEXTENSIONS_LIB"
/D "QT_WIDGETS_LIB"
/D "DEVELOP_MODE"
/D "LINALG_USE_EIGEN"
/D "PYTHONQT_USE_RELEASE_PYTHON_FALLBACK"
/D "PX_PHYSX_STATIC_LIB"
/D "QT_MULTIMEDIA_LIB"
/D "QT_GAMEPAD_LIB"
/D "QT_GUI_LIB"
/D "QT_CONCURRENT_LIB"
/D "QT_NETWORK_LIB"
/D "QT_CORE_LIB"
/errorReport:prompt
/WX-
/Zc:forScope
/Gd
/Oy-
/MDd
/FC
/Fa"qt_generated\obj\"
/EHsc
/nologo
/Fo"qt_generated\obj\"
/Fp"qt_generated\obj\grand_blue_d.pch"
/diagnostics:classic
在尝试尽可能接近匹配后,我的 cmake 标志解决了这个问题:
/MP
/GS
/analyze-
/W3
/wd"4577"
/wd"4467"
/Zc:wchar_t
/I"C:\Users\me\Documents\Projects\my-engine\app"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine"
/I"C:\Users\me\Documents\Projects\my-engine\app\reverie_autogen\include_Debug"
/I"C:\Users\me\Documents\Projects\my-engine\third_party\Python38-32\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\pybind11\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\src\third_party\eigen"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\assimp\assimp-5.0.0\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\assimp\assimp-5.0.0\build\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\physx\physx\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\physx\pxshared\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\freetype-2.10.1\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\soloud\include"
/I"C:\Users\me\Documents\Projects\my-engine\my_engine\..\third_party\Visual Leak Detector\include"
/I"C:\Qt.12.2\msvc2017\include"
/I"C:\Qt.12.2\msvc2017\include\QtCore"
/I"C:\Qt.12.2\msvc2017\.\mkspecs\win32-msvc"
/I"C:\Qt.12.2\msvc2017\include\QtConcurrent"
/I"C:\Qt.12.2\msvc2017\include\QtGamepad"
/I"C:\Qt.12.2\msvc2017\include\QtGui"
/I"C:\Qt.12.2\msvc2017\include\QtANGLE"
/I"C:\Qt.12.2\msvc2017\include\QtOpenGLExtensions"
/I"C:\Qt.12.2\msvc2017\include\QtMultimedia"
/I"C:\Qt.12.2\msvc2017\include\QtNetwork"
/I"C:\Qt.12.2\msvc2017\include\QtMultimediaWidgets"
/I"C:\Qt.12.2\msvc2017\include\QtWidgets"
/I"C:\Program Files (x86)\Visual Leak Detector\include"
/Zi
/Gm-
/Od
/Fd"reverie.dir\Debug\vc141.pdb"
/Zc:inline
/fp:precise
/D "WIN32"
/D "_WINDOWS"
/D "DEBUG_MODE"
/D "_UNICODE"
/D "_ENABLE_EXTENDED_ALIGNED_STORAGE"
/D "WIN64"
/D "QT_DLL"
/D "QT_OPENGL_LIB"
/D "DEVELOP_MODE"
/D "LINALG_USE_EIGEN"
/D "_CRT_SECURE_NO_WARNINGS"
/D "PX_PHYSX_STATIC_LIB"
/D "QT_CORE_LIB"
/D "QT_CONCURRENT_LIB"
/D "QT_GAMEPAD_LIB"
/D "QT_GUI_LIB"
/D "QT_OPENGLEXTENSIONS_LIB"
/D "QT_MULTIMEDIA_LIB"
/D "QT_NETWORK_LIB"
/D "QT_MULTIMEDIAWIDGETS_LIB"
/D "QT_WIDGETS_LIB"
/D "CMAKE_INTDIR=\"Debug\""
/D "UNICODE"
/errorReport:prompt
/WX-
/Zc:forScope
/Gd
/Oy-
/MDd
/std:c++latest
/Fa"reverie.dir\Debug\"
/EHsc
/nologo
/Fo"reverie.dir\Debug\"
/Fp"reverie.dir\Debug\reverie.pch"
/diagnostics:classic
据我所知,这些应该具有相同的性能!关于我的 qmake 构建如何变得如此快,有什么想法吗?
编辑:为了更有趣,这是我的 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 my_project.pro")
TEMPLATE = app
TARGET = my_project
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 ////////////////////////////////////////////////////////////////////
INCLUDEPATH += ../third_party/pybind11/include
# 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(my_project.pri)
message("Loaded .pri files")
和我的 cmake 项目文件:
# CMake build for the Reverie Engine
# To run cmake, add cmake/bin directory to system path
## TODO:
## Implement source_group, for organizing in IDE, see:
## TODO: Remove DLLs from this folder, as they are not needed
message( STATUS "---------Beginning cmake build of Reverie Engine---------")
# MACROS =================================================================
macro(remove_flag_from_target _target _flag)
get_target_property(_target_cxx_flags ${_target} COMPILE_OPTIONS)
if(_target_cxx_flags)
list(REMOVE_ITEM _target_cxx_flags ${_flag})
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${_target_cxx_flags}")
endif()
endmacro()
# Project-level setup ====================================================
project( Reverie ) # TODO: Set version
cmake_minimum_required( VERSION 3.16 )
set(TARGET_NAME "reverie") # See:
message (STATUS "--------- Set target ${TARGET_NAME}---------")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON) # Saves having to use QT5_WRAP_CPP
set(CMAKE_AUTORCC ON) # Saves having to use QT5_ADD_RESOURCES
set(CMAKE_AUTOUIC ON) # Saves having to use QT5_WRAP_UI
# Set compiler flags =====================================================
# Use C++20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Multiprocess compiler, disable specific warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /wd4577 /wd4467")
# Remove unwanted flags
STRING (REGEX REPLACE "[/|-]RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
STRING (REGEX REPLACE "[/|-]Ob0" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
STRING (REGEX REPLACE "[/|-]GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# Set paths to find Qt ===================================================
# Find Qt itself
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(CMAKE_PREFIX_PATH "C:\Qt\5.12.2\msvc2017")
else()
message (WARNING "-------- System not supported ---------")
endif()
# Find UI files
# See:
set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ui")
# Find Required Qt Libraries =============================================
find_package(Qt5 COMPONENTS Core REQUIRED)# Core stuff
find_package(Qt5 COMPONENTS Concurrent REQUIRED) # For threading
find_package(Qt5 COMPONENTS Gamepad REQUIRED) # Controller support
find_package(Qt5 COMPONENTS Gui REQUIRED) # For OpenGL integration
find_package(Qt5 COMPONENTS OpenGLExtensions REQUIRED)
# find_package(Qt5OpenGL) # OpenGL should come from GUI
find_package(Qt5 COMPONENTS Multimedia REQUIRED) # Multimedia capabilities
find_package(Qt5 COMPONENTS MultimediaWidgets REQUIRED)
find_package(Qt5 COMPONENTS Widgets REQUIRED) # For widgets
# OpenGL libraries
# See:
find_package(OpenGL REQUIRED) # enforces as a requirement
# find_library(OPENGL_LIB names opengl32) # Also valid
# find_library(GLU_LIB names glu32) # Also valid
# Set build mode directory options ========================================
# add_definitions(-DAPPLETTUTORIAL1_LIBRARY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/release)
# Set directories to find libraries, need to do this before add_executable for desired target
# link_directories(${CMAKE_SOURCE_DIR} "${CMAKE_SOURCE_DIR}/lib")
file(TO_CMAKE_PATH "$ENV{PYTHON_LIB}" ENV_PYTHON_LIB)
message(STATUS "Setting link directory ${ENV_PYTHON_LIB}")
link_directories(${ENV_PYTHON_LIB})
# Works as alternative, but does not solve any of my runtime problems
# set(PYTHON_QT_PATH "${CMAKE_SOURCE_DIR}/../third_party/PythonQt")
# set(PYTHON_QT_LIB_PATH "${PYTHON_QT_PATH}/lib")
# link_directories(${PYTHON_QT_LIB_PATH})
# Build EXE ===============================================================
# Get all source files, headers, resources, and UI (forms) from src subdirectory
# See:
## TODO: Maybe don't include headers as source?, see
message (STATUS "-------- Finding source, header, resource, UI files relative to ${CMAKE_SOURCE_DIR} ---------")
file(GLOB_RECURSE MY_SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.cpp" "src/*.h"
"resources/*.qrc" "ui/*.ui")
message (STATUS "=========== FOUND FILES =============")
message (STATUS "${MY_SOURCES}")
message (STATUS "=========== END FILES ===============")
# Generate release PDB
#
add_compile_options("$<$<NOT:$<CONFIG:Debug>>:/Zi>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/DEBUG>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/OPT:REF>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/OPT:ICF>")
# Add an executable to be built from sources variable
add_executable(${TARGET_NAME} ${MY_SOURCES})
# Add compile definitions to the target ===================================
# Set options based on debug or release mode
# Generator expression, see:
#
# https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html
set(DEBUG_DEFINITIONS "DEBUG_MODE")
set(RELEASE_DEFINITIONS "QT_NO_DEBUG_OUTPUT")
target_compile_definitions(${TARGET_NAME} PUBLIC
$<$<CONFIG:DEBUG>:${DEBUG_DEFINITIONS}>
$<$<CONFIG:RELEASE>:${RELEASE_DEFINITIONS}>
)
# Remove unwanted flags ===================================================
# Doesn't work
# remove_flag_from_target(${TARGET_NAME} -RTC1)
# Pre-processor Defines ===================================================
add_definitions(-D_UNICODE -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DLL -DQT_OPENGL_LIB)
add_definitions(-DDEVELOP_MODE)
add_definitions(-DLINALG_USE_EIGEN)
# Disable warnings about deprecated things, like using strcpy (sorry, not sorry)
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
# Add compile options to the target =======================================
# target_compile_options(${TARGET_NAME} PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
# target_compile_options(${TARGET_NAME} PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
# Link Required Qt modules to main target =================================
# This MUST come after add_executable and find_package for each module
# Essentially, target_link_libraries links the two specified libraries
#
target_link_libraries(${TARGET_NAME} OpenGL::GL OpenGL::GLU)
target_link_libraries(${TARGET_NAME} Qt5::Core)
target_link_libraries(${TARGET_NAME} Qt5::Concurrent)
target_link_libraries(${TARGET_NAME} Qt5::Gamepad)
target_link_libraries(${TARGET_NAME} Qt5::Gui)
target_link_libraries(${TARGET_NAME} Qt5::OpenGLExtensions) # TODO: Probably unnecessary, remove
target_link_libraries(${TARGET_NAME} Qt5::Multimedia)
target_link_libraries(${TARGET_NAME} Qt5::MultimediaWidgets)
target_link_libraries(${TARGET_NAME} Qt5::Widgets)
# Add additional libraries ================================================
# Add a default search locations
# TODO: link_directories takes generators, so maybe split into debug and release that way
message(STATUS "Default library search directories: ${CMAKE_SOURCE_DIR}/lib ${CMAKE_SOURCE_DIR}/lib/assimp")
# Include directories:
#
# Linking libraries:
# ****
#
# Python
message (STATUS "=========== Including Python =============")
# To eliminate conflict with "slots" keyword: PyType_Slot *slots; /* terminated by slot==0. */
# Equivalent to CONFIG += no_keywords in qmake
# add_definitions(-DQT_NO_KEYWORDS)
# For system versions, see:
#
if(DEFINED ENV{PYTHON_VERSION})
set(PYTHON_VERSION $ENV{PYTHON_VERSION})
else()
if(WIN32)
# for Windows operating system in general
# if(MSVC OR MSYS OR MINGW) # for detecting Windows compilers
set(PYTHON_VERSION 38)
elseif(APPLE)
# for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
elseif(UNIX AND NOT APPLE)
# For Linux, BSD, Solaris, Minix
message(STATUS "Setting UNIX python version")
set(PYTHON_VERSION 3.8)
else()
message( WARNING "Unrecognized operating system")
endif()
endif()
message (STATUS "PYTHON VERSION $ENV{PYTHON_VERSION}")
# Set up include paths and libraries for Python itself
if(WIN32)
# for Windows operating system in general
# if(MSVC OR MSYS OR MINGW) # for detecting Windows compilers
# Convert paths to CMAKE-friendly versions
file(TO_CMAKE_PATH "$ENV{PYTHON_PATH}" ENV_PYTHON_PATH)
# Link Python
# Debug DLL fails to import third party modules, so always use release
target_include_directories(${TARGET_NAME} PRIVATE "${ENV_PYTHON_PATH}/include")
message(STATUS "Python include path for windows is ${ENV_PYTHON_PATH}/include")
message(STATUS "Python path is ${ENV_PYTHON_PATH}")
# find_library(PYTHON_DEBUG_LIB NAMES "python${PYTHON_VERSION}_d" HINTS ${ENV_PYTHON_LIB})
find_library(PYTHON_RELEASE_LIB NAMES "python${PYTHON_VERSION}" HINTS ${ENV_PYTHON_LIB})
# message(STATUS "Linking Python with debug path ${PYTHON_DEBUG_LIB} and release path ${PYTHON_RELEASE_LIB}")
target_link_libraries(${TARGET_NAME}
debug ${PYTHON_RELEASE_LIB} optimized ${PYTHON_RELEASE_LIB}
)
elseif(APPLE)
# for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
message (STATUS "BUILDING FOR APPLE")
# Include library directory
target_include_directories(${TARGET_NAME} PRIVATE "/System/Library/Frameworks/Python.framework/Headers")
# Find library with name Python, and link
find_library(PYTHON_LIBRARY_PATH NAMES "Python")
target_link_libraries(${TARGET_NAME}
${PYTHON_LIBRARY_PATH}
)
elseif(UNIX AND NOT APPLE)
# For Linux, BSD, Solaris, Minix
message (STATUS "BUILDING FOR UNIX")
execute_process(COMMAND python${PYTHON_VERSION}-config --embed --libs
OUTPUT_VARIABLE PYTHON_LIBRARY_PATH
RESULT_VARIABLE FAILED_TO_DETECT_PYTHON
)
if(FAILED_TO_DETECT_PYTHON)
message (WARNING "Failed to detect Python")
else()
# Set library path
target_link_libraries(${TARGET_NAME} ${PYTHON_LIBRARY_PATH})
endif()
else()
message( WARNING "Unrecognized operating system")
endif()
# PYBIND
message (STATUS "=========== Including PYBIND =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/pybind11/include")
# EIGEN
message (STATUS "=========== Including Eigen at ${CMAKE_SOURCE_DIR}/src/third_party/eigen =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/src/third_party/eigen")
# ASSIMP
message (STATUS "=========== Including ASSIMP =============")
target_include_directories(${TARGET_NAME} PRIVATE
"${CMAKE_SOURCE_DIR}/../third_party/assimp/assimp-5.0.0/include"
"${CMAKE_SOURCE_DIR}/../third_party/assimp/assimp-5.0.0/build/include")
find_library(ASSIMP_DEBUG_LIB NAMES assimp_d HINTS "${CMAKE_SOURCE_DIR}/lib/assimp")
find_library(ASSIMP_LIB NAMES assimp HINTS "${CMAKE_SOURCE_DIR}/lib/assimp")
target_link_libraries(${TARGET_NAME}
debug ${ASSIMP_DEBUG_LIB} optimized ${ASSIMP_LIB})
# PhysX
message (STATUS "=========== Including PhysX as a static library =============")
add_definitions(-DPX_PHYSX_STATIC_LIB)
target_include_directories(${TARGET_NAME} PRIVATE
"${CMAKE_SOURCE_DIR}/../third_party/physx/physx/include"
"${CMAKE_SOURCE_DIR}/../third_party/physx/pxshared/include")
set( PHYSX_LIBRARY_DEBUG_DIR "${CMAKE_SOURCE_DIR}/lib/physx/debug")
set( PHYSX_LIBRARY_RELEASE_DIR "${CMAKE_SOURCE_DIR}/lib/physx/release")
message (STATUS "Debug directory is ${PHYSX_LIBRARY_DEBUG_DIR}")
target_link_libraries(${TARGET_NAME}
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysX_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysX_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXCharacterKinematic_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXCharacterKinematic_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXCommon_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXCommon_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXCooking_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXCooking_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXExtensions_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXExtensions_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXFoundation_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXFoundation_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXPvdSDK_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXPvdSDK_static_32.lib"
debug "${PHYSX_LIBRARY_DEBUG_DIR}/PhysXVehicle_static_32.lib" optimized "${PHYSX_LIBRARY_RELEASE_DIR}/PhysXVehicle_static_32.lib"
)
# FreeType
message (STATUS "=========== Including FreeType =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/freetype-2.10.1/include")
find_library(FREETYPE_DEBUG_LIB NAMES freetype HINTS "${CMAKE_SOURCE_DIR}/lib/freetype/debug")
find_library(FREETYPE_RELEASE_LIB NAMES freetype HINTS "${CMAKE_SOURCE_DIR}/lib/freetype/release")
target_link_libraries(${TARGET_NAME}
debug ${FREETYPE_DEBUG_LIB} optimized ${FREETYPE_RELEASE_LIB})
# SoLoud
message (STATUS "=========== Including SoLoud =============")
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/soloud/include")
find_library(SOLOUD_DEBUG_LIB NAMES soloud_x86_d HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/debug")
find_library(SOLOUD_RELEASE_LIB NAMES soloud_x86 HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/release")
find_library(SOLOUD_STATIC_DEBUG_LIB NAMES soloud_static_x86_d HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/debug")
find_library(SOLOUD_STATIC_RELEASE_LIB NAMES soloud_static_x86 HINTS "${CMAKE_SOURCE_DIR}/lib/soloud/release")
target_link_libraries(${TARGET_NAME}
debug ${SOLOUD_DEBUG_LIB} optimized ${SOLOUD_RELEASE_LIB}
debug ${SOLOUD_STATIC_DEBUG_LIB} optimized ${SOLOUD_STATIC_RELEASE_LIB}
)
# Visual Leak Detector
# See:
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/../third_party/Visual Leak Detector/include/")
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
message(STATUS "=========== Including 64 Bit VLD =============")
# Is 64 bit
find_library(VLD_LIB NAMES vld HINTS "${CMAKE_SOURCE_DIR}/../third_party/Visual Leak Detector/lib/Win64")
target_link_libraries(${TARGET_NAME} ${VLD_LIB})
else()
# Is 32 Bit
message(STATUS "=========== Including 32 Bit VLD =============")
find_library(VLD_LIB NAMES vld HINTS "${CMAKE_SOURCE_DIR}/../third_party/Visual Leak Detector/lib/Win32")
target_link_libraries(${TARGET_NAME} ${VLD_LIB})
endif()
编辑:所以,已经过去几周了,我在弄清楚这里发生了什么方面完全没有取得任何进展。我已经为这两个构建系统生成了一些详细的报告,which can be found here. 到目前为止,没有任何线索对我来说很突出。事实上,我什至没有在报告中看到任何表明我的新构建系统速度变慢的信息!如果我没看错,应该会更快。
编辑 2:这也是我的链接器选项。 The old way, and the new way.
我明白了!! cmake 将我的应用程序构建为控制台应用程序,而不是 Windows 应用程序。在我的 cmake 构建中用 add_executable(${TARGET_NAME} WIN32 ${MY_SOURCES})
替换 add_executable(${TARGET_NAME} ${MY_SOURCES})
使性能匹配。今天学到了新东西,谢谢大家