- remove profiling/coverage mix from debug build, as it is useless as of
now, re-enable this for a separate coverage build in the future
- use gcc's `-ggdb` and `-Og` flag (requires recent gcc) to provide
better debug information targeted for gdb and optimize what we can
- use `-fno-inline` and `-fno-omit-stack-pointer`, in order to be able
to jump around in gdb without functions being gone and keeping the
stack reference
This refines the last commit of parallelizing lto.
Discussion: this is ugly as hell, dispatching 1/ on the availability of
the `-flto` flag, then 2/ on the compiler since GCC allows `-flto=n`
whereas Clang for example does not.
I tried setting the CMake property `INTERPROCEDURAL_OPTIMIZATION`,
without any effect. All I could see was some lto related utilities in
the cmake debug output, but not in the actual compiler or linker
invocation.
This would eliminate the need for our hacks, with 1/ using an option
`WITH_LTO` setting `ON` by default, and based on this value setting the
`INTERPROCEDURAL_OPTIMIZATION` flag with CMake doing the actual work of
selecting the best LTO method on the target platform.
By the way, this also fixes a bug where we reset the `CMAKE_CXX_FLAGS`
to a variable that was never defined, resulting in setting the flags to
an empty string. Yay CMake, as usual.
References:
- http://www.cmake.org/cmake/help/v3.0/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.html
GCC with link time optimizations does not to respect this mode
unfortunately, reuslting in warnings in release (default) build
mode from system includes such as boost, luabind and so on.
This remove the `-fPIC` flag, indicating position independant code
generation, from the build system.
Citing GCC's official code generation docs:
> This option makes a difference on the m68k, PowerPC and SPARC.
We do not support any of these architectures, so remove the flag!
References:
- https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options
These are for standard compliance and should on by default:
-Wall -Wextra -pedantic
The problem is that even `-Wall` and `-Wextra` does not cover all
warnings, as to not break backward compatibility. Clang therefore
has the `-Weverything` flag, that really includes everything but is
overkill for the day to day development.
Thus, we in addition add:
-Wuninitialized -Wunreachable-code
to guard against undefined behavior from reading uninitialized variables
and warn for unreachable code.
With:
-Wstrict-overflow=1
the compiler warns us when it's doing optimizations based on the fact
that signed integer overflows are undefined behavior.
With:
-D_FORTIFY_SOURCE=2
we tell the compiler to replace functions like strcpy with strncpy where
it can do so, resulting in cheap and useful buffer overflow protection.
References:
- https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
- https://securityblog.redhat.com/2014/03/26/fortify-and-you/
- https://wiki.debian.org/Hardening
This rips out the Bost Spirit / Karma conversion code, using the stdlib
and lightweight alternatives instead.
The main benefit is an immense decrease in compilation times, for every
translation unit that requires the `util/cast.hpp` header.
Note: compared to the version before, there is a minor change in
behavior: the double `-0` was printed as `0` before and is now printed
as `-0`. This comes from the IEE754 standard, specifying signed zeros,
that is `+0` and `-0`. Interesting for us: JavaScript uses IEE754,
resulting in no breakage if used in arithmetic.
Small test case, left hand side was before, right hand side is now:
$ ./a.out
-1.123457 vs -1.123457
-1 vs -1
-1.3 vs -1.3
0 vs -0
0 vs 0
0 vs 0
1.3 vs 1.3
1.123457 vs 1.123457
References:
- https://en.wikipedia.org/wiki/Signed_zero
- http://www.boost.org/doc/libs/1_59_0/doc/html/boost/algorithm/trim_right_if.html
- http://www.boost.org/doc/libs/1_59_0/doc/html/boost/algorithm/is_any_of.html
With C++11 the stdlib gains:
- `std::stoi` function family to convert from `std::string` to integral type
- `std::to_string` to convert from number types to `std::string`
The only reason for hand-writing the conversion code therefore is
performance. I benchmarked an `osrm-extract` with the hand-written code
against one with the stdlib conversion features and could not find any
significant difference (we switch back and forth between C++ and Lua,
shaving off a few us in conversion doesn't gain us much).
Formatting arithmetic types in the default format with given precision
requires streams, but is doable in a few lines of idiomatic stdlib code.
For this, there is now the following function template available:
template <Arithmetic T, int Precision = 6>
inline std::string to_string_with_precision(const T);
that requires integral or floating point types and returns a formatted
string in the defaukt format with the given precision applied.
In addition this completely rips out Boost.Spirit from the `casts.hpp`
header, resulting in faster compile times.
Boom!
References:
- http://en.cppreference.com/w/cpp/string/basic_string/stol
- http://en.cppreference.com/w/cpp/string/basic_string/to_string
- http://www.kumobius.com/2013/08/c-string-to-int/
We needed this for Boost < 1.48, but per our Wiki on building OSRM:
> On Ubuntu 12.04 you will be limited to OSRM tag v0.3.10 because
> later versions **require Boost v1.49+** and installing this
> causes problems with libluabind-dev package.
Thus, rip it out!
To keep the commits atomic and isolated, I also refactored all call
sites that used the functionality from the portability fix.
While doing this, I also simplified the monster of around ~100 lines of
file path checking --- lambda's are awesome' use them!
References:
- http://stackoverflow.com/a/1750710
- https://github.com/Project-OSRM/osrm-backend/wiki/Building-on-Ubuntu
- removes `noexcept` specifier as we can not guarantee for not throwing
- uses a namespace instead of a struct + static function combination
- asserts for heading degree in [0, 360] range (both sides inclusive!)
- header only since implementation does not hide anything
- adds `inline` specifier as compiler hint
This reverts @6b2bf49 on the server components.
We do not want to parallelize there, as node should be used for
parallelizing the user requests onto multiple processes.
This switches out the `<variant/optional.hpp>` implementation of the
optional monad to the one from Boost.
The following trick makes sure we keep compile times down:
- use `<boost/optional/optional_fwd.hpp>` to forward declare the
optional type in header, then include the full blown optional header
only in the implementation file.
- do the same for the files we touch, e.g. forward declare osmium types,
allowing us to remove the osmium header dependency from our headers:
`namespace osmium { class Relation; }
and then include the appropriate osmium headers in the implementation
file only. We should do this globally...
References:
- http://www.boost.org/doc/libs/1_59_0/libs/optional/doc/html/index.html
- https://github.com/osmcode/libosmium/issues/123
This removes the custom `replaceAll` function, replacing it with
`std::replace` from the stdlib's `<algorithm>` header.
This also removes the respective unit test.
More importantly, this removes the dependency on the
`<boost/algorithm/string.hpp>` header in the `string_util.hpp` header.
The `static_rtree.hpp` header included `<booost/thread.hpp>` without using
anything from this header.
Removing it showed why:
the unit test for the rtree no longer built, since it was missing symbols
for Boost's `hash_combine`, used in the unit test.
Instead of relying on `<boost/thread.hpp>` including the proper header
for `hash_combine` by chance that we only use in the unit test, do the
following:
- remove `<boost/thread.hpp>` from the rtree implementation
- add `<boost/functional/hash.hpp>` to the rtree unit test
As always, include what you use.
This provides a wrapper script to invoke the Static Analyzer on the code
base. The script simply wraps your commands, that is you have to do the
following:
..scripts/analyze cmake ..
..scripts/analyze cmake --build .
Note: the Static Analyzer is integrated in Xcode, so if you are on a
Mac, consider using Xcode natively instead of this wrapper script that
will only give you HTML output.
Reference:
- http://clang-analyzer.llvm.org/
Only specify the flags we change from the default.
doxygen -g Doxyfile
Generates a default Doxyfile.
Also, make the docs not depend on `dot`, but conditionally create graphs
if `dot` is available, and if not still generate docs.
Automate cucumber tests bisecting by providing a `git bisect` script.
Because it is stored in source control, but bisecting changes the HEAD,
it is advised to first copy over the script to a place outside source
control, e.g. `/tmp`.
Usage:
git bisect start HEAD HEAD~10
bit bisect run /tmp/bisect_cucumber.sh
This automatically configures and builds OSRM, spawns the cucumber tests
and communicates with `git bisect` based on its return code.
Reference:
- man git-bisect
This extends the compressed output vector's lifetime, as we issue an
asynchronous write operation that only receives a non-owning buffer to
the compressed data.
When the compressed output vector then goes out of scope, its destructor
is called and the data gets (potentially) destroyed. If the asynchronous
write happens afterwards, it's accessing data that is no longer there.
This is the reason for race conditions --- well, for undefined behavior
in general, but it manifests in the routed _sometimes_ not responding at
all.
The fix works like this: keep the compressed output associated with a
connection. Connections inherit from `std::enable_shared_from_this` and
issues a `shared_from_this()` call, passing a `std::shared_ptr` to the
asynchronous write function, thus extending their lifetime.
Connecitons thus manage their lifetime by themselves, extending it when
needed (and of course via the `std::shared_pointers` pointing to it).
Buffer's non owning property, from the `async_write` documentation:
> One or more buffers containing the data to be written. Although
> the buffers object may be copied as necessary, ownership of the
> underlying memory blocks is retained by the caller, which must
> guarantee that they remain valid until the handler is called.
Reference:
- http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/reference/async_write/overload1.html
This caches iterators, i.e. especially the end iterator when possible.
The problem:
for (auto it = begin(seq); it != end(seq); ++it)
this has to call `end(seq)` on every iteration, since the compiler is
not able to reason about the call's site effects (to bad, huh).
Instead do it like this:
for (auto it = begin(seq), end = end(seq); it != end; ++it)
caching the end iterator.
Of course, still better would be:
for (auto&& each : seq)
if all you want is value semantics.
Why `auto&&` you may ask? Because it binds to everything and never copies!
Skim the referenced proposal (that was rejected, but nevertheless) for a
detailed explanation on range-based for loops and why `auto&&` is great.
Reference:
- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3853.htm