C++ 我的qmake构建在调试构建中的速度是cmake的两倍多,为什么?

C++ 我的qmake构建在调试构建中的速度是cmake的两倍多,为什么?,c++,qt,cmake,qmake,C++,Qt,Cmake,Qmake,所以,我正在将我的项目从qmake转换为cmake,我就要完成了!然而,至少在调试模式下,我的qmake构建的运行时速度提高了一倍多。我希望在两种构建配置中设置相同的编译标志,以便比较不同的版本 不幸的是,我还没有很幸运地弄清楚到底是什么导致了性能差异!我的qmake标志解决了以下问题: /MP /GS /analyze- /W3 /wd"4577" /wd"4467" /Zc:wchar_t /I"." /I"

所以,我正在将我的项目从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\5.12.2\msvc2017\include"
 /I"C:\Qt\5.12.2\msvc2017\include\QtOpenGL"
 /I"C:\Qt\5.12.2\msvc2017\include\QtWidgets"
 /I"C:\Qt\5.12.2\msvc2017\include\QtOpenGLExtensions"
 /I"C:\Qt\5.12.2\msvc2017\include\QtMultimedia"
 /I"C:\Qt\5.12.2\msvc2017\include\QtGamepad"
 /I"C:\Qt\5.12.2\msvc2017\include\QtGui"
 /I"C:\Qt\5.12.2\msvc2017\include\QtANGLE"
 /I"C:\Qt\5.12.2\msvc2017\include\QtConcurrent"
 /I"C:\Qt\5.12.2\msvc2017\include\QtNetwork"
 /I"C:\Qt\5.12.2\msvc2017\include\QtCore"
 /I"qt_generated\moc"
 /I"qt_generated\ui"
 /I"C:\VulkanSDK\1.0.51.0\include"
 /I"C:\Qt\5.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\5.12.2\msvc2017\include"
 /I"C:\Qt\5.12.2\msvc2017\include\QtCore"
 /I"C:\Qt\5.12.2\msvc2017\.\mkspecs\win32-msvc"
 /I"C:\Qt\5.12.2\msvc2017\include\QtConcurrent"
 /I"C:\Qt\5.12.2\msvc2017\include\QtGamepad"
 /I"C:\Qt\5.12.2\msvc2017\include\QtGui"
 /I"C:\Qt\5.12.2\msvc2017\include\QtANGLE"
 /I"C:\Qt\5.12.2\msvc2017\include\QtOpenGLExtensions"
 /I"C:\Qt\5.12.2\msvc2017\include\QtMultimedia"
 /I"C:\Qt\5.12.2\msvc2017\include\QtNetwork"
 /I"C:\Qt\5.12.2\msvc2017\include\QtMultimediaWidgets"
 /I"C:\Qt\5.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 build for the Reverie Engine
# To run cmake, add cmake/bin directory to system path
## TODO:
## Implement source_group, for organizing in IDE, see: https://stackoverflow.com/questions/31966135/cmake-source-group-not-working-correctly-with-hierarchical-project-setup
## 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: https://stackoverflow.com/questions/31037882/whats-the-cmake-syntax-to-set-and-use-variables

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: https://stackoverflow.com/questions/40630820/how-to-place-header-and-ui-file-in-different-folders-using-autouic-in-cmake
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: https://stackoverflow.com/questions/65100749/converting-from-qmake-to-cmake-how-do-i-find-libraries-in-the-same-way/65106458#65106458
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: https://stackoverflow.com/questions/2110795/how-to-use-all-c-files-in-a-directory-with-the-cmake-build-system
## TODO: Maybe don't include headers as source?, see https://stackoverflow.com/questions/19866424/cmake-and-qt5-automoc-error
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
# https://stackoverflow.com/questions/28178978/how-to-generate-pdb-files-for-release-build-with-cmake-flags/31264946
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://stackoverflow.com/questions/34490294/what-does-configdebugrelease-mean-in-cmake
# 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
# https://stackoverflow.com/questions/25909943/getting-a-cmake-error-cannot-specify-link-libraries-for-target-which-is-not-bui/41262868
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:
# https://stackoverflow.com/questions/13703647/how-to-properly-add-include-directories-with-cmake
# Linking libraries:
# **** https://stackoverflow.com/questions/48273378/qmake-to-cmake-transition-syntax-for-external-librairies
# https://stackoverflow.com/questions/60061299/convert-qmake-into-cmake

# 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: 
# https://stackoverflow.com/questions/9160335/os-specific-instructions-in-cmake-how-to
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: https://stackoverflow.com/questions/4029587/compiling-32-bit-vs-64-bit-project-using-cmake/15986042
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()

#----------------------------------------------------
#此文件由Qt Visual Studio工具生成。
# ------------------------------------------------------
#见:https://www.toptal.com/qt/vital-guide-qmake
#注意:调试构建应该使用/MDd运行时库,发布应该使用/MD(可能是Qt的默认值)
#TODO:转换为cmake:https://www.executionunit.com/blog/2014/01/22/moving-from-qmake-to-cmake/
消息(“开始我的_project.pro的qmake构建”)
模板=应用程序
目标=我的项目
QT+=核心\
opengl\
桂\
小部件\
并发\#互斥体/多线程
openglextensions\
多媒体\
gamepad\#控制器支持
网络#TCP/IP
#设置编译器标志/////////////////////////////////////////////////////////////
QMAKE_cxflags+/MP#多进程编译,速度更快
在15.3之后,SysMsVC版本是多变的,需要使用更多现代C++变体的标志。
QMAKE_cxflags*=/std:c++17#添加如果没有,这可能就是问题所在
#QMAKE_cxflags+=-std=c++17#用于GCC/Clang
#QMAKE_cxflags+=-std=c++1z
#设置常规配置选项/////////////////////////////////////////////////
CONFIG+=c++最新版本#添加对c++17的支持。
#CONFIG+=c++1z#对c++17支持的又一次尝试
CONFIG+=qt#console#目标是一个qt应用程序或库,需要qt库和头文件
CONFIG+=线程#已启用线程支持。当配置中包含默认的qt时,将启用此选项。
CONFIG+=debug_和_release#创建额外的调试和发布文件夹,但需要用于调试
配置(调试,调试|发布){
DESTDIR=../app/debug
定义+=调试模式
} 
否则{
DESTDIR=../app/release
}
#将O2标志替换为O3标志
#配置(发布、调试|发布){
#QMAKE_CXXFLAGS_发布-=-O1
#QMAKE_CXXFLAGS_释放-=-O2
#QMAKE_CXXFLAGS_发布*=-O3
#}
#在发布模式下不显示调试输出
配置(调试,调试|发布):配置+=调试|信息
CONFIG(release,debug | release):定义+=QT_NO_debug_输出
CONFIG+=nolflags_merge#确保LIBS变量中存储的库列表在使用前不会缩减为唯一值列表。
#CONFIG+=CONSOLE#使其成为一个控制台应用程序
CONFIG-=flat#展平文件层次结构,如果不需要,则减去
#定义//////////////////////////////////////////////////////////////////////////
定义+=\u UNICODE\u ENABLE\u EXTENDED\u ALIGNED\u STORAGE WIN64 QT\u DLL QT\u OPENGL\u LIB QT\u OPENGLEXTENSIONS\u LIB QT\u WIDGETS\u LIB
定义+=开发模式
定义+=LINALG\u使用\u特征值
INCLUDEPATH+=/qt\u生成\
. \
./qt_生成/$(配置名称)
LIBS+=-lopengl32\
-lglu32
DEPENDPATH+=。
#添加库////////////////////////////////////////////////////////////////////
INCLUDEPATH+=../third\u party/pybind11/include
#根据python的发行版编译
CONFIG(debug,debug | release):定义+=PYTHONQT_使用_发布_PYTHON_回退
#本征
INCLUDEPATH+=$$PWD/src/第三方/eigen\
$$PWD/src/第三方/eigen/eigen
#助理
#会写
INCLUDEPATH+=../third\u party/assimp/assimp-5.0.0/include
INCLUDEPATH+=../third\u party/assimp/assimp-5.0.0/build/include
配置(调试,调试|发布):LIBS+=-L$$PWD/lib/assimp-lassimp\d
配置(发布,调试|发布):LIBS+=-L$$PWD/lib/assimp-lassimp
#PhysX
定义+=PX_PHYSX_STATIC_LIB
INCLUDEPATH+=../../PhysX/PhysX/include\
../../PhysX/pxshared/include
配置(调试,调试|发布){
LIBS+=-L$$PWD/lib/physx/debug-lPhysX\u static\u 32
LIBS+=-L$$PWD/lib/physx/debug-lphysxcharactermotional\u static\u 32
LIBS+=-L$$PWD/lib/physx/debug-lPhysXCommon\u static\u 32
LIBS+=-L$$PWD/lib/physx/debug-lPhysXCooking\u static\u 32
LIBS+=-L$$PWD/lib/physx/debug-lPhysXExtensions\u static\u 32
LIBS+=-L$$PWD/lib/physx/debug-lPhysXFoundation\u static\u 32
LIBS+=-L$$PWD/lib/physx/debug-lPhysXPvdSDK\u static\u 32
LIBS+=-L$$PWD/lib/physx/debug-lPhysXVehicle\u static\u 32
}
配置(发布,调试|发布){
#总是需要
LIBS+=-L$$PWD/lib/physx/release-lPhysXCommon\u static\u 32
#总是需要
LIBS+=-L$$PWD/lib/physx/release-lPhysX\u static\u 32
#总是需要
LIBS+=-L$$PWD/lib/physx/release-lPhysXFoundation\u static\u 32
#动态烹饪几何体数据的步骤
LIBS+=-L$$PWD/lib/physx/release-lPhysXCooking\u static\u 32
#其他
LIBS+=-L$$PWD/lib/physx/release-lphysxcharactermotional\u static\u 32
LIBS+=-L$$PWD/lib/physx/release-lPhysXExtensions\u static\u 32
LIBS+=-L$$PWD/lib/physx/release-lPhysXPvdSDK\u static\u 32
LIBS+=-L$$PWD/lib/physx/release-lPhysXVehicle\u static\u 32
}
#自由式
INCLUDEPATH+=../third\u 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
#索卢德
INCLUDEPATH+=../third\u party/soloud/include
配置(调试,调试|发布){
LIBS+=-L$$PWD/lib/soloud/debug-lsoloud\u x86\u d
LIBS+=-L$$PWD/lib/soloud/debug-lsoloud\u static\u x86\u d
}
配置(发布、调试|发布){