|
| 1 | +## Open Source Routing Machine |
| 2 | + |
| 3 | +OSRM (Open Source Routing Machine) is a high performance routing engine written in C++ designed to run on OpenStreetMap data. |
| 4 | +It provides various routing services including route finding, distance/duration tables, GPS trace matching, and traveling salesman problem solving. |
| 5 | +It is accessible via HTTP API, C++ library interface, and Node.js wrapper. |
| 6 | +OSRM supports two routing algorithms: Contraction Hierarchies (CH) and Multi-Level Dijkstra (MLD). |
| 7 | + |
| 8 | +## Developing |
| 9 | + |
| 10 | +We target C++20 but need to deal with older compilers that only have partial support. |
| 11 | + |
| 12 | +Use `./scripts/format.sh` to format the code. Ensure clang-format-15 is available on the system. |
| 13 | + |
| 14 | +## Coding Standards |
| 15 | + |
| 16 | +Specific practices to follow (see [wiki](https://github.com/Project-OSRM/osrm-backend/wiki/Coding-Standards)): |
| 17 | + |
| 18 | +- **No `using namespace`**: Always use explicit `std::` prefixes, never `using namespace std;` (especially in headers) |
| 19 | +- **Naming conventions**: |
| 20 | + - Type names (classes, structs, enums): `UpperCamelCase` (e.g. `TextFileReader`) |
| 21 | + - Variables: `lower_case_with_underscores`, private members start with `m_` (e.g. `m_node_count`) |
| 22 | + - Functions: `lowerCamelCase` verb phrases (e.g. `openFile()`, `isValid()`) |
| 23 | + - Enumerators and public members: `UpperCamelCase` (e.g. `VK_Argument`) |
| 24 | +- **Include order**: (1) Module header, (2) Local headers, (3) Parent directory headers, (4) System includes - sorted lexicographically within each group |
| 25 | +- **Comments**: Minimal use of comments on internal interfaces. Use C++ style `//` comments, not C style `/* */`. Use `#if 0` / `#endif` to comment out blocks |
| 26 | +- **Integer types**: Use only `int`/`unsigned` for 32-bit, or precise-width types like `int16_t`, `int64_t` |
| 27 | +- **No RTTI/exceptions**: Avoid `dynamic_cast<>` and exceptions (except for IO operations) |
| 28 | +- **Compiler warnings**: Treat all warnings as errors - fix them, don't ignore them |
| 29 | +- **Assert liberally**: Use `BOOST_ASSERT` to check preconditions and assumptions |
| 30 | +- **Indentation**: 4 spaces (enforced by clang-format) |
| 31 | + |
| 32 | +## Building |
| 33 | + |
| 34 | +This project uses CMake. The build directory should be `build` or `build-{something}` or `build/{something}/`. For example: |
| 35 | +- `./build` |
| 36 | +- `./build-gcc-debug` |
| 37 | +- `./build/gcc-debug` |
| 38 | +- `./build/gcc` |
| 39 | +- `./build/clang-debug` |
| 40 | +- `./build-clang-release` |
| 41 | + |
| 42 | +Use `cmake --build ${BUILD_DIR} --target ${TARGET} -j $(nproc --ignore=2)` to build a target. |
| 43 | + |
| 44 | + |
| 45 | +## Running |
| 46 | + |
| 47 | +OSRM supports two data preparations: Contraction Hierarchies (CH) and Multi-Level Dijkstra (MLD). |
| 48 | + |
| 49 | +For CH: |
| 50 | +1. `./${BUILD_DIR}/osrm-extract -p profiles/car.lua data.osm.pbf` |
| 51 | +2. `./${BUILD_DIR}/osrm-partition data.osrm` (optional, improves CH performance due to cache locality of node reordering) |
| 52 | +3. `./${BUILD_DIR}/osrm-contract data.osrm` |
| 53 | +4. `./${BUILD_DIR}/osrm-routed -a CH data.osrm` |
| 54 | + |
| 55 | +For MLD: |
| 56 | +1. `./${BUILD_DIR}/osrm-extract -p profiles/car.lua data.osm.pbf` |
| 57 | +2. `./${BUILD_DIR}/osrm-partition data.osrm` |
| 58 | +3. `./${BUILD_DIR}/osrm-customize data.osrm` |
| 59 | +4. `./${BUILD_DIR}/osrm-routed -a MLD data.osrm` |
| 60 | + |
| 61 | +A dataset can be both MLD and CH if both `osrm-contract` and `osrm-customize` are executed: |
| 62 | +1. `./${BUILD_DIR}/osrm-extract -p profiles/car.lua data.osm.pbf` |
| 63 | +2. `./${BUILD_DIR}/osrm-partition data.osrm` |
| 64 | +3. `./${BUILD_DIR}/osrm-contract data.osrm` |
| 65 | +4. `./${BUILD_DIR}/osrm-customize data.osrm` |
| 66 | +5. `./${BUILD_DIR}/osrm-routed -a CH data.osrm` OR `./${BUILD_DIR}/osrm-routed -a MLD data.osrm` |
| 67 | + |
| 68 | + |
| 69 | +## Testing |
| 70 | + |
| 71 | +### Running Unit tests |
| 72 | + |
| 73 | +Unit tests are contained in `unit_tests/` using boost test and can be build with: |
| 74 | +```bash |
| 75 | +cmake --build ${BUILD_DIR} --target tests |
| 76 | +``` |
| 77 | + |
| 78 | +This will create various tests in `${BUILD_DIR}/unit_tests/`. |
| 79 | + |
| 80 | +### Running Integration Tests |
| 81 | + |
| 82 | +Integration tests are contained in `features/` using cucumber-js |
| 83 | + |
| 84 | +To run cucumber tests with the full test matrix across different algorithms (CH, MLD) and load methods (mmap, directly, datastore). |
| 85 | +```bash |
| 86 | +npm test |
| 87 | +``` |
| 88 | + |
| 89 | +To run cucumber tests for a specific configuration: |
| 90 | +```bash |
| 91 | +npx cucumber-js -p home -p ch -p datastore |
| 92 | +npx cucumber-js -p home -p mld -p mmap |
| 93 | +``` |
| 94 | + |
| 95 | + |
| 96 | +## Contributing |
| 97 | + |
| 98 | +<IMPORTANT> |
| 99 | +Use the [PR template](.github/PULL_REQUEST_TEMPLATE.md) to build the PR description. |
| 100 | +Remove irrelevant tasks, but NEVER remove `review` or submit it checked. |
| 101 | +Ensure the description includes which AI tool and model was used, add a robot emoji to the description. |
| 102 | +</IMPORTANT> |
| 103 | + |
0 commit comments