diff --git a/CMakeLists.txt b/CMakeLists.txt index 91ea434f..bd895658 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -288,6 +288,17 @@ if(SFML_INSTALL_PKGCONFIG_FILES) endforeach() endif() +# option to enable precompiled headers +sfml_set_option(SFML_ENABLE_PCH FALSE BOOL "TRUE to enable precompiled headers for SFML builds -- only supported on Windows/Linux and for static library builds") + +if(SFML_ENABLE_PCH AND BUILD_SHARED_LIBS) + message(FATAL_ERROR "Precompiled headers are currently not supported for shared library builds") +endif() + +if(SFML_ENABLE_PCH AND SFML_OS_MACOSX) + message(FATAL_ERROR "Precompiled headers are currently not supported in MacOS builds") +endif() + # setup the install rules if(NOT SFML_BUILD_FRAMEWORKS) install(DIRECTORY include diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index 6bd93000..36aa89ee 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -3,6 +3,14 @@ include(CMakeParseArguments) # include the compiler warnings helpers include(${CMAKE_CURRENT_LIST_DIR}/CompilerWarnings.cmake) +# helper function to tweak visibility of public symbols +function(set_public_symbols_hidden target) + # ensure public symbols are hidden by default (exported ones are explicitly marked) + set_target_properties(${target} PROPERTIES + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN YES) +endfunction() + # This little macro lets you set any Xcode specific property macro(sfml_set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE) set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE}) @@ -80,6 +88,13 @@ macro(sfml_add_library module) endif() set_target_warnings(${target}) + set_public_symbols_hidden(${target}) + + # enable precompiled headers + if (SFML_ENABLE_PCH AND (NOT ${target} STREQUAL "sfml-system")) + message(VERBOSE "enabling PCH for SFML library '${target}'") + target_precompile_headers(${target} REUSE_FROM sfml-system) + endif() # define the export symbol of the module string(REPLACE "-" "_" NAME_UPPER "${target}") @@ -164,18 +179,22 @@ macro(sfml_add_library module) PDB_NAME "${target}${SFML_PDB_POSTFIX}" PDB_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") else() - # Static libraries have no linker PDBs, thus the compiler PDBs are relevant - set_target_properties(${target} PROPERTIES - COMPILE_PDB_NAME "${target}-s${SFML_PDB_POSTFIX}" - COMPILE_PDB_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") + if(SFML_ENABLE_PCH) + message(VERBOSE "overriding PDB name for '${target}' with \"sfml-s${SFML_PDB_POSTFIX}\" due to PCH being enabled") + + # For PCH builds with PCH reuse, the PDB name must be the same as the target that's being reused + set_target_properties(${target} PROPERTIES + COMPILE_PDB_NAME "sfml-system" + COMPILE_PDB_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") + else() + # Static libraries have no linker PDBs, thus the compiler PDBs are relevant + set_target_properties(${target} PROPERTIES + COMPILE_PDB_NAME "${target}-s${SFML_PDB_POSTFIX}" + COMPILE_PDB_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") + endif() endif() endif() - # ensure public symbols are hidden by default (exported ones are explicitly marked) - set_target_properties(${target} PROPERTIES - CXX_VISIBILITY_PRESET hidden - VISIBILITY_INLINES_HIDDEN YES) - # build frameworks or dylibs if(SFML_OS_MACOSX AND BUILD_SHARED_LIBS AND NOT THIS_STATIC) if(SFML_BUILD_FRAMEWORKS) @@ -285,7 +304,14 @@ macro(sfml_add_example target) set_property(TARGET ${target} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") endif() + # enable precompiled headers + if (SFML_ENABLE_PCH) + message(VERBOSE "enabling PCH for SFML example '${target}'") + target_precompile_headers(${target} REUSE_FROM sfml-system) + endif() + set_target_warnings(${target}) + set_public_symbols_hidden(${target}) # set the debug suffix set_target_properties(${target} PROPERTIES DEBUG_POSTFIX -d) @@ -322,6 +348,12 @@ function(sfml_add_test target SOURCES DEPENDS) # create the target add_executable(${target} ${SOURCES}) + # enable precompiled headers + if (SFML_ENABLE_PCH) + message(VERBOSE "enabling PCH for SFML test '${target}'") + target_precompile_headers(${target} REUSE_FROM sfml-system) + endif() + # set the target's folder (for IDEs that support it, e.g. Visual Studio) set_target_properties(${target} PROPERTIES FOLDER "Tests") @@ -329,6 +361,7 @@ function(sfml_add_test target SOURCES DEPENDS) target_link_libraries(${target} PRIVATE ${DEPENDS} sfml-test-main) set_target_warnings(${target}) + set_public_symbols_hidden(${target}) # If coverage is enabled for MSVC and we are linking statically, use /WHOLEARCHIVE # to make sure the linker doesn't discard unused code sections before coverage can be measured diff --git a/src/SFML/PCH.hpp b/src/SFML/PCH.hpp new file mode 100644 index 00000000..514bab97 --- /dev/null +++ b/src/SFML/PCH.hpp @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2022 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_SFML_PCH_HPP +#define SFML_SFML_PCH_HPP + +//////////////////////////////////////////////////////////// +// Precompiled Headers +//////////////////////////////////////////////////////////// + +#include + +#ifdef SFML_SYSTEM_WINDOWS + +#define UNICODE 1 +#define _UNICODE 1 +#include + +#endif // SFML_SYSTEM_WINDOWS + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // SFML_SFML_PCH_HPP diff --git a/src/SFML/System/CMakeLists.txt b/src/SFML/System/CMakeLists.txt index 3a9c8f6e..87475629 100644 --- a/src/SFML/System/CMakeLists.txt +++ b/src/SFML/System/CMakeLists.txt @@ -67,6 +67,12 @@ endif() sfml_add_library(System SOURCES ${SRC} ${PLATFORM_SRC}) +# enable precompiled headers +if (SFML_ENABLE_PCH) + message(VERBOSE "enabling PCH for SFML library 'sfml-system' (reused as the PCH for other SFML libraries)") + target_precompile_headers(sfml-system PRIVATE ${PROJECT_SOURCE_DIR}/src/SFML/PCH.hpp) +endif() + if(SFML_OS_ANDROID) # glad sources target_include_directories(sfml-system PRIVATE "${PROJECT_SOURCE_DIR}/extlibs/headers/glad/include")