[Orxonox-commit 585] r3117 - in branches/pch: cmake src/orxonox

rgrieder at orxonox.net rgrieder at orxonox.net
Wed Jun 3 20:40:17 CEST 2009


Author: rgrieder
Date: 2009-06-03 20:40:17 +0200 (Wed, 03 Jun 2009)
New Revision: 3117

Added:
   branches/pch/cmake/GetGCCCompilerFlags.cmake
   branches/pch/cmake/PrecompiledHeaderFiles.cmake
   branches/pch/src/orxonox/OrxonoxPrecompiledHeaders.h
Modified:
   branches/pch/cmake/BuildConfigGCC.cmake
   branches/pch/cmake/BuildConfigMSVC.cmake
   branches/pch/cmake/TargetUtilities.cmake
   branches/pch/src/orxonox/CMakeLists.txt
Log:
Adding experimental precompiled header file support. It seems to work quite well with MSVC, but has a performance penalty when used with GCC ^^

Modified: branches/pch/cmake/BuildConfigGCC.cmake
===================================================================
--- branches/pch/cmake/BuildConfigGCC.cmake	2009-06-03 18:28:37 UTC (rev 3116)
+++ branches/pch/cmake/BuildConfigGCC.cmake	2009-06-03 18:40:17 UTC (rev 3117)
@@ -42,6 +42,13 @@
   SET(GCC_NO_SYSTEM_HEADER_SUPPORT TRUE)
 ENDIF()
 
+# GCC only supports PCH in versions 3.4 and above
+INCLUDE(CompareVersionStrings)
+COMPARE_VERSION_STRINGS("${GCC_VERSION}" "3.4.0" _compare_result)
+IF(_compare_result GREATER -1)
+  SET(PCH_COMPILER_SUPPORT TRUE)
+ENDIF()
+
 # Also include environment flags. Could cause conflicts though
 SET_COMPILER_FLAGS("$ENV{CXXFLAGS}" CXX CACHE)
 SET_COMPILER_FLAGS("$ENV{CFLAGS}"   C   CACHE)

Modified: branches/pch/cmake/BuildConfigMSVC.cmake
===================================================================
--- branches/pch/cmake/BuildConfigMSVC.cmake	2009-06-03 18:28:37 UTC (rev 3116)
+++ branches/pch/cmake/BuildConfigMSVC.cmake	2009-06-03 18:40:17 UTC (rev 3117)
@@ -37,6 +37,10 @@
   OPTION(VISUAL_LEAK_DETECTOR_ENABLE "Memory leak detector" FALSE)
 ENDIF(MSVC80)
 
+# Orxonox only supports MSVC 8 and above, which gets asserted above
+SET(PCH_COMPILER_SUPPORT TRUE)
+
+
 #################### Compiler Flags #####################
 
 # -MD    Minimal Rebuild

Added: branches/pch/cmake/GetGCCCompilerFlags.cmake
===================================================================
--- branches/pch/cmake/GetGCCCompilerFlags.cmake	                        (rev 0)
+++ branches/pch/cmake/GetGCCCompilerFlags.cmake	2009-06-03 18:40:17 UTC (rev 3117)
@@ -0,0 +1,73 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Reto Grieder
+ #  Description:
+ #    Tries to return all GCC compiler flags set for a target. This also
+ #    all definitions of the current directory.
+ #
+
+INCLUDE(SeparateFlags)
+
+FUNCTION(GET_GCC_COMPILER_FLAGS _target _flagsvar)
+
+  # General flags
+  STRING(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_upper)
+  SET(_flag_str "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_build_type_upper}}")
+
+  # Include directories
+  GET_DIRECTORY_PROPERTY(_include_dirs INCLUDE_DIRECTORIES)
+  IF(_include_dirs)
+    FOREACH(_directory ${_include_dirs})
+      SET(_flag_str "${_flag_str} -I${_directory}")
+    ENDFOREACH(_directory)
+  ENDIF()
+
+  # For shared libraries linked with gcc, we have to add -fPIC
+  #GET_TARGET_PROPERTY(_target_type ${_target} TYPE)
+  #IF(${_target_type} STREQUAL SHARED_LIBRARY)
+  #  SET(_flag_str "${_flag_str} -fPIC")
+  #ENDIF()
+
+  # Target compile flags
+  GET_TARGET_PROPERTY(_target_flags ${_target} COMPILE_FLAGS)
+  IF(_target_flags)
+    SET(_flag_str "${_flag_str} ${_target_flags}")
+  ENDIF()
+
+  # Definitions from target and directory
+  GET_DIRECTORY_PROPERTY(_directory_defs                 COMPILE_DEFINITIONS)
+  GET_DIRECTORY_PROPERTY(_directory_defs_build_type      COMPILE_DEFINITIONS_${_build_type_upper})
+  GET_TARGET_PROPERTY(_target_defs            ${_target} COMPILE_DEFINITIONS)
+  GET_TARGET_PROPERTY(_target_defs_build_type ${_target} COMPILE_DEFINITIONS_${_build_type_upper})
+  GET_TARGET_PROPERTY(_target_def_symbol      ${_target} DEFINE_SYMBOL)
+  # Prefix them all with a "-D" if the property was found
+  FOREACH(_def ${_directory_defs} ${_directory_defs_build_type} ${_target_defs}
+               ${_target_defs_build_type} ${_target_def_symbol})
+    IF(_def)
+      SET(_flag_str "${_flag_str} -D${_def}")
+    ENDIF(_def)
+  ENDFOREACH(_def)
+
+  SEPARATE_FLAGS("${_flag_str}" _flags)
+  LIST(REMOVE_DUPLICATES _flags)
+  SET(${_flagsvar} ${_flags} PARENT_SCOPE)
+
+ENDFUNCTION(GET_GCC_COMPILER_FLAGS)


Property changes on: branches/pch/cmake/GetGCCCompilerFlags.cmake
___________________________________________________________________
Added: svn:eol-style
   + native

Added: branches/pch/cmake/PrecompiledHeaderFiles.cmake
===================================================================
--- branches/pch/cmake/PrecompiledHeaderFiles.cmake	                        (rev 0)
+++ branches/pch/cmake/PrecompiledHeaderFiles.cmake	2009-06-03 18:40:17 UTC (rev 3117)
@@ -0,0 +1,161 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Reto Grieder
+ #
+
+INCLUDE(GetGCCCompilerFlags)
+ 
+MACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET _target_name _header_file_arg _sourcefile_var)
+
+  GET_FILENAME_COMPONENT(_pch_header_file ${_header_file_arg} ABSOLUTE)
+  GET_FILENAME_COMPONENT(_pch_header_filename ${_pch_header_file} NAME)
+  GET_FILENAME_COMPONENT(_pch_header_filename_we ${_pch_header_file} NAME_WE)
+
+  IF(NOT EXISTS ${_pch_header_file})
+    MESSAGE(FATAL_ERROR "Specified precompiled headerfile '${_header_file_arg}' does not exist.")
+  ENDIF()
+
+  # Extract arguments from ARGN
+  FOREACH(_arg ${ARGN})
+    IF(NOT "${_arg}" STREQUAL "EXCLUDE")
+      IF(NOT _arg_second)
+        # Source files with PCH support
+        SET(_included_files ${_included_files} ${_arg})
+      ELSE()
+        # Source files to be excluded from PCH support (easier syntax this way)
+        SET(_excluded files ${_excluded_files} ${_arg})
+      ENDIF()
+    ELSE()
+      SET(_arg_second TRUE)
+    ENDIF()
+  ENDFOREACH(_arg)
+
+  # Use ${_sourcefile_var} if no files were specified explicitely
+  IF(NOT _included_files)
+    SET(_source_files ${${_sourcefile_var}})
+  ELSE()
+    SET(_source_files ${_included_files})
+  ENDIF()
+
+  # Exclude files (if specified)
+  FOREACH(_file ${_excluded_files})
+    LIST(FIND _source_files ${_file} _list_index)
+    IF(_list_index GREATER -1)
+      LIST(REMOVE_AT _source_files _list_index)
+    ELSE()
+      MESSAGE(FATAL_ERROR "Could not exclude file ${_file} in target ${_target_name}")
+    ENDIF()
+  ENDFOREACH(_file)
+
+  LIST(FIND ${_sourcefile_var} ${_pch_header_file} _list_index)
+  IF(_list_index EQUAL -1) # Header file could already be included with GET_ALL_HEADER_FILES
+    LIST(APPEND ${_sourcefile_var} ${_pch_header_file})
+  ENDIF()
+  SOURCE_GROUP("PCH" FILES ${_pch_header_file})
+
+  IF(MSVC)
+
+    # Write and add one source file, which generates the precompiled header file
+    SET(_pch_source_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename_we}.cc")
+    IF(NOT EXISTS ${_pch_source_file})
+      FILE(WRITE ${_pch_source_file} "#include \"${_pch_header_file}\"\n")
+    ENDIF()
+    SET_SOURCE_FILES_PROPERTIES(_pch_source_file PROPERTIES GENERATED TRUE)
+    LIST(APPEND ${_sourcefile_var} ${_pch_source_file})
+    SOURCE_GROUP("PCH" FILES ${_pch_source_file})
+
+    SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${_pch_header_filename}.pch")
+    # Set compile flags for generated source file
+    SET_SOURCE_FILES_PROPERTIES(${_pch_source_file} PROPERTIES COMPILE_FLAGS "/c /Yc\"${_pch_header_file}\" /Fp\"${_pch_file}\"")
+    # Set Compile flags for the other source files
+    FOREACH(_file ${_source_files})
+      GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY)
+      IF(NOT _is_header)
+        GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS)
+        IF(NOT _old_flags)
+          SET(_old_flags "")
+        ENDIF()
+	SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES COMPILE_FLAGS "${_old_flags} /FI\"${_pch_header_file}\" /Yu\"${_pch_header_file}\" /Fp\"${_pch_file}\"")
+      ENDIF(NOT _is_header)
+    ENDFOREACH(_file)
+
+  ELSEIF(CMAKE_COMPILER_IS_GNU)
+
+    SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename}.gch")
+    SET(_pch_dep_helper_file "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}_pch_dependency_helper.cc")
+
+    # Append the gch-dir to make sure gcc finds the pch file
+    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+    # Get compiler flags of the source files (target does not yet exist!)
+    # This is just the best possible opportunity to address this dependency issue
+    GET_GCC_COMPILER_FLAGS(${_target_name} _pch_gcc_flags)
+    # Make sure we recompile the pch file even if only the flags change
+    FILE(WRITE ${_pch_dep_helper_file} "/* ${_pch_gcc_flags} */")
+
+    # Set Compile flags for the other source files
+    FOREACH(_file ${_source_files})
+      GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY)
+      IF(NOT _is_header)
+        GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS)
+        IF(NOT _old_flags)
+          SET(_old_flags "")
+        ENDIF()
+        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES
+          COMPILE_FLAGS "${_old_flags} -include ${_pch_header_filename}"
+	  OBJECT_DEPENDS "${_pch_header_file};${_pch_file}"
+        )
+      ENDIF(NOT _is_header)
+    ENDFOREACH(_file)
+
+  ENDIF()
+
+ENDMACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET)
+
+FUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET _target_name)
+    # This macro is only necessary for GCC
+    IF(CMAKE_COMPILER_IS_GNU)
+
+      # Workaround for distcc
+      IF(CMAKE_CXX_COMPILER_ARG1)
+        # remove leading space in compiler argument
+        STRING(REGEX REPLACE "^ +" "" _pch_cmake_cxx_compiler_arg1 "${CMAKE_CXX_COMPILER_ARG1}")
+      ENDIF()
+
+      # Get compiler flags of the source files again (target exists this time)
+      GET_GCC_COMPILER_FLAGS(${_target_name} _pch_gcc_flags)
+
+      # Compile the header file
+      ADD_CUSTOM_COMMAND(
+        OUTPUT ${_pch_file}
+        COMMAND ${CMAKE_CXX_COMPILER}
+        ARGS ${pchsupport_compiler_cxx_arg1} ${_pch_gcc_flags} -c -x c++-header -o ${_pch_file} ${_pch_header_file}
+	WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        DEPENDS ${_pch_header_file} ${_pch_dep_helper_file}
+        IMPLICIT_DEPENDS ${_pch_header_file}
+        VERBATIM
+      )
+
+    ENDIF(CMAKE_COMPILER_IS_GNU)
+ENDFUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET)
+
+# TODO: Investigate what happens when we suddenly disable PCH for a library
+# TODO: C and CXX


Property changes on: branches/pch/cmake/PrecompiledHeaderFiles.cmake
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: branches/pch/cmake/TargetUtilities.cmake
===================================================================
--- branches/pch/cmake/TargetUtilities.cmake	2009-06-03 18:28:37 UTC (rev 3116)
+++ branches/pch/cmake/TargetUtilities.cmake	2009-06-03 18:40:17 UTC (rev 3117)
@@ -33,12 +33,16 @@
  #      NO_SOURCE_GROUPS:  Don't create msvc source groups
  #      STATIC/SHARED:     Inherited from ADD_LIBRARY
  #      WIN32:             Inherited from ADD_EXECUTABLE
+ #      PCH_NO_DEFAULT:    Do not make precompiled header files default if
+ #                         specified with PCH_FILE
  #    Lists:
  #      LINK_LIBRARIES:    Redirects to TARGET_LINK_LIBRARIES
  #      VERSION:           Set version to the binary
  #      SOURCE_FILES:      Source files for the target
  #      DEFINE_SYMBOL:     Sets the DEFINE_SYMBOL target property
  #      TOLUA_FILES:       Files with tolua interface
+ #      PCH_FILE:          Precompiled header file
+ #      PCH_EXCLUDE:       Source files to be excluded from PCH support
  #  Note:
  #    This function also installs the target!
  #  Prerequisistes:
@@ -51,6 +55,9 @@
 INCLUDE(GenerateToluaBindings)
 INCLUDE(ParseMacroArguments)
 INCLUDE(SourceFileUtilities)
+IF(PCH_COMPILER_SUPPORT)
+  INCLUDE(PrecompiledHeaderFiles)
+ENDIF()
 
 FUNCTION(ORXONOX_ADD_LIBRARY _target_name)
   TU_ADD_TARGET(${_target_name} LIBRARY "STATIC;SHARED" ${ARGN})
@@ -66,9 +73,10 @@
 
   # Specify all possible options (either switch or with add. arguments)
   SET(_switches   FIND_HEADER_FILES  EXCLUDE_FROM_ALL  ORXONOX_EXTERNAL
-                  NO_DLL_INTERFACE   NO_SOURCE_GROUPS  ${_additional_switches})
+                  NO_DLL_INTERFACE   NO_SOURCE_GROUPS  ${_additional_switches}
+                  PCH_NO_DEFAULT)
   SET(_list_names LINK_LIBRARIES  VERSION   SOURCE_FILES  DEFINE_SYMBOL
-                  TOLUA_FILES)
+                  TOLUA_FILES     PCH_FILE  PCH_EXCLUDE)
   PARSE_MACRO_ARGUMENTS("${_switches}" "${_list_names}" ${ARGN})
 
 
@@ -102,6 +110,22 @@
                             INPUTFILES ${_arg_TOLUA_FILES})
   ENDIF()
 
+  # First part (pre target) of precompiled header files
+  IF(PCH_COMPILER_SUPPORT AND _arg_PCH_FILE)
+    # Provide convenient option to control PCH
+    STRING(TOUPPER "${_target_name}" _target_name_upper)
+    IF(_arg_PCH_NO_DEFAULT)
+      SET(PCH_DEFAULT FALSE)
+    ELSE()
+      SET(PCH_DEFAULT TRUE)
+    ENDIF()
+    OPTION(PCH_ENABLE_${_target_name_upper} "Enable using precompiled header files for library ${_target_name}." ${PCH_DEFAULT})
+
+    IF(PCH_ENABLE_${_target_name_upper})
+      PRECOMPILED_HEADER_FILES_PRE_TARGET(${_target_name} ${_arg_PCH_FILE} _${_target_name}_files EXCLUDE ${_arg_PCH_EXCLUDE})
+    ENDIF()
+  ENDIF()
+
   # Certain libraries don't have dllexport/dllimport and can't be linked shared with msvc
   IF(MSVC AND _arg_NO_DLL_INTERFACE)
     SET(_arg_SHARED)
@@ -143,6 +167,11 @@
     SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${ORXONOX_VERSION})
   ENDIF()
 
+  # Second part of precompiled header files
+  IF(PCH_COMPILER_SUPPORT AND PCH_ENABLE_${_target_name_upper} AND _arg_PCH_FILE)
+    PRECOMPILED_HEADER_FILES_POST_TARGET(${_target_name} ${_arg_PCH_FILE})
+  ENDIF()
+
   IF(NOT _arg_STATIC)
     INSTALL(TARGETS ${_target_name}
       RUNTIME DESTINATION ${ORXONOX_RUNTIME_INSTALL_PATH}

Modified: branches/pch/src/orxonox/CMakeLists.txt
===================================================================
--- branches/pch/src/orxonox/CMakeLists.txt	2009-06-03 18:28:37 UTC (rev 3116)
+++ branches/pch/src/orxonox/CMakeLists.txt	2009-06-03 18:40:17 UTC (rev 3117)
@@ -40,6 +40,9 @@
     objects/pickup/PickupInventory.h
     objects/quest/QuestDescription.h
     objects/quest/QuestManager.h
+  PCH_FILE
+    OrxonoxPrecompiledHeaders.h
+  PCH_NO_DEFAULT
   LINK_LIBRARIES
     ${OGRE_LIBRARY}
     ${CEGUI_LIBRARY}

Added: branches/pch/src/orxonox/OrxonoxPrecompiledHeaders.h
===================================================================
--- branches/pch/src/orxonox/OrxonoxPrecompiledHeaders.h	                        (rev 0)
+++ branches/pch/src/orxonox/OrxonoxPrecompiledHeaders.h	2009-06-03 18:40:17 UTC (rev 3117)
@@ -0,0 +1,91 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+ at file
+ at brief
+    Compilation of the most often used header files in the orxonox executable
+*/
+
+// including std headers here is useless since they're already precompiled
+
+#ifndef WIN32_LEAN_AND_MEAN
+// prevent Ogre from including winsock.h that messes with winsock2.h from enet
+#  define WIN32_LEAN_AND_MEAN
+#endif
+#ifndef NOMINMAX
+#  define NOMINMAX // required to stop windows.h screwing up std::min definition
+#endif
+#include <Ogre.h>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/filesystem.hpp>
+
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "tinyxml/ticpp.h"
+#include "tolua/tolua++.h"
+
+//--------- Orxonox files --------
+//--------------------------------
+
+#include "util/Convert.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/Math.h"
+#include "util/MathConvert.h"
+#include "util/Multitype.h"
+#include "util/Sleep.h"
+#include "util/String.h"
+#include "util/SubString.h"
+
+#include "core/BaseObject.h"
+#include "core/ClassTreeMask.h"
+#include "core/Clock.h"
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CommandExecutor.h"
+#include "core/CommandLine.h"
+#include "core/Core.h"
+#include "core/EventIncludes.h"
+#include "core/Executor.h"
+#include "core/Game.h"
+#include "core/GameMode.h"
+#include "core/GameState.h"
+#include "core/ObjectList.h"
+#include "core/Super.h"
+#include "core/Template.h"
+#include "core/XMLFile.h"
+#include "core/XMLIncludes.h"
+#include "core/XMLPort.h"
+#include "core/input/SimpleInputState.h"
+#include "core/input/InputManager.h"
+
+#include "network/synchronisable/Synchronisable.h"
+#include "network/ClientInformation.h"


Property changes on: branches/pch/src/orxonox/OrxonoxPrecompiledHeaders.h
___________________________________________________________________
Added: svn:eol-style
   + native




More information about the Orxonox-commit mailing list