So, I am converting my project from qmake to cmake, and I'm just about done! However, I'm getting more than double the runtime speed on my qmake build, at least in debug mode. I'd like to have the same compile flags set in both build configurations so that I'm comparing apples to apples.
Unfortunately, I haven't had much luck figuring out what the heck is accounting for the performance difference! My qmake flags resolve out to this:
/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
And my cmake flags resolve out to this, after trying to get as close a match as possible:
/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
As far as I can see, these should see identical performance! Any ideas at all as to how my qmake build could be so much faster?
Edit: For even more fun, here is my qmake project file:
# ----------------------------------------------------
# This file is generated by the Qt Visual Studio Tools.
# ------------------------------------------------------
# See: https://www.toptal.com/qt/vital-guide-qmake
# NOTE: Debug build should use /MDd runtime library, and release should use /MD (may be default for Qt)
# TODO: Convert to cmake: https://www.executionunit.com/blog/2014/01/22/moving-from-qmake-to-cmake/
message("Beginning qmake build of 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")
and my cmake project file:
# 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()
Edit: So, it's been a few weeks, and I've made absolutely no headway in figuring out what's going on here. I've generated some detailed reports for both build systems, which can be found here. So far, no clues that stand out to me. In fact, I don't even see anything in the reports that would suggest that my new build system is slower at all! If I'm reading things correctly, it should be faster.
Edit 2: Here are my linker options as well. The old way, and the new way.