karolherbst / Gamekeeper-Framework

Library for hooking up game stores and merging them into one single library
GNU Lesser General Public License v2.1
2 stars 0 forks source link

[RFC] Use Cotire and automatically generate precompiled headers. #79

Closed Jookia closed 10 years ago

Jookia commented 10 years ago

This fixes #20 in a simple and elegant way, by including Cotire in all the CMake targets. In the future if we want to use single precompiled headers across multiple targets that's possible too, or precompile the Gamekeeper includes, but let's cut to some benchmarks:

Without Cotire:

% mkdir build && cd build && git checkout master && cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/../install 
% time make
make  106.46s user 6.04s system 98% cpu 1:54.28 total
% for i in ../src/**/*.cpp; touch $i # Pretend we've edited all source files.
% time make
make  62.11s user 3.45s system 98% cpu 1:06.56 total
% touch ../src/core/curlfiledownloader.cpp # Pretend to edit a file that includes a lot of Boost.
% time make
make  7.57s user 0.56s system 97% cpu 8.301 total

With Cotire:

% mkdir build && cd build && git checkout pch && cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/../install 
% time make
make  52.43s user 3.98s system 98% cpu 57.363 total
% for i in ../src/**/*.cpp; touch $i # Pretend we've edited all source files.
% time make
make  31.24s user 2.52s system 98% cpu 34.244 total
% touch ../src/core/curlfiledownloader.cpp # Pretend to edit a file that includes a lot of Boost.
% time make
make  2.47s user 0.27s system 98% cpu 2.797 total

With these benchmarks, Cotire effectively halves compile times across the board.

Here's the precompiled header used in gamekeeperCore:

/* cotire.cmake 1.6.3 generated file */
/* libgamelib/build/src/core/cotire/gamekeeperCore_CXX_prefix.cxx */
#pragma GCC system_header
#ifdef __cplusplus
#include "/usr/include/c++/4.9.0/cstdint"
#include "/usr/include/c++/4.9.0/map"
#include "/usr/include/boost/any.hpp"
#include "/usr/include/boost/program_options/variables_map.hpp"
#include "/usr/include/boost/filesystem/path.hpp"
#include "/usr/include/c++/4.9.0/unordered_map"
#include "/usr/include/c++/4.9.0/thread"
#include "/usr/include/boost/algorithm/string/classification.hpp"
#include "/usr/include/boost/algorithm/string/replace.hpp"
#include "/usr/include/boost/algorithm/string/split.hpp"
#include "/usr/include/boost/filesystem/fstream.hpp"
#include "/usr/include/boost/filesystem/operations.hpp"
#include "/usr/include/boost/iostreams/device/array.hpp"
#include "/usr/include/boost/iostreams/stream.hpp"
#include "/usr/include/curl/curl.h"
#include "/usr/include/boost/lexical_cast.hpp"
#include "/usr/include/log4cpp/CategoryStream.hh"
#include "/usr/include/log4cpp/Category.hh"
#include "/usr/include/boost/algorithm/string/erase.hpp"
#include "/usr/include/log4cpp/Configurator.hh"
#include "/usr/include/log4cpp/OstreamAppender.hh"
#include "/usr/include/log4cpp/PatternLayout.hh"
#include "/usr/include/c++/4.9.0/atomic"
#include "/usr/include/c++/4.9.0/mutex"
#include "/usr/include/c++/4.9.0/forward_list"
#include "/usr/include/c++/4.9.0/climits"
#include "/usr/include/c++/4.9.0/cstdlib"
#endif

Some issues with this (not pressing):

  1. There's no way to disable Cotire. I'm not sure if this is needed considering the advantages it brings and it's entirely in CMake. But the choice would be nice.
  2. There's only precompiled headers being generated for gamekeeperCore, gamekeeperClient and gamekeeperBackend. This may be intentional with cost/benefits weighed by Cotire.
  3. I'm not sure of the penalty hit we'd get if one of the generated headers would need to be recompiled.
  4. It's only halved. I'm not sure if this is the expected result. Based on this and the previous two points, we might want to find a compiler profiler for sticky spots.
  5. I grabbed Cotire out of Git, I'm not sure if including it is the right thing considering versioning.
karolherbst commented 10 years ago
  1. what does cotire do with unsupported platforms/compiler?
  2. is okay, because pch only make sense for targets with more than just one source file
  3. the entire target has to be recompiled
  4. I didn't expect much more, because there aren't many files yet and half of the source files are compiled in about a second anyway.
  5. I would use the newest (stable?) version and only cherry-pick commits, which are helpful.

In general I like the idea, because it is making pch stuff pretty easy for us. I have some notes though:

Jookia commented 10 years ago

I've fixed the #includes and added a way to disable Cotire. It's on by default. I'm still working on MinGW support (I need to set up my cross compiler), but I still don't quite understand how to identify single unit compiles...?

karolherbst commented 10 years ago

I noticed, that single unit compiles are separated targets

karolherbst commented 10 years ago

I left some comment, but it looks pretty good now.

Jookia commented 10 years ago

I've rebased it, made it use instead of stringutils and removed the pch.h comment in the utils CMakeLists.

karolherbst commented 10 years ago

one a little minor thing, but this looks pretty good now. I think I will merge this tomorrow

Jookia commented 10 years ago

Fixed.