diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 114377c7..2a8187ec 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -22,6 +22,7 @@ jobs: matrix: config: - preset: clang-release + artifact: linux-amd64 - preset: clang-debug - preset: gcc-release - preset: gcc-debug @@ -58,11 +59,85 @@ jobs: - name: Build run: | buildcache -z - cmake --build build/${{ matrix.config.preset }} --target soro-server-client + cmake --build build/${{ matrix.config.preset }} --target soro-server buildcache -s # ==== WEB TESTS ==== - name: Run Server run: | cd ./build/${{ matrix.config.preset }} - ./soro-server -t + ./soro-server -t --resource_dir ../../resources + + # ==== DISTRIBUTION ==== + - name: Create Distribution + if: matrix.config.artifact + run: | + mkdir -p soro-s + rm -rf build/clang-release/server_resources/infrastructure + rm -rf build/clang-release/server_resources/timetable + mv build/clang-release/soro-server soro-s/ + mv build/clang-release/server_resources soro-s/ + tar cjf soro-s-${{ matrix.config.artifact }}.tar.bz2 soro-s + + - name: Upload Distribution + if: matrix.config.artifact + uses: actions/upload-artifact@v1 + with: + name: soro-s-${{ matrix.config.artifact }} + path: soro-s-${{ matrix.config.artifact }}.tar.bz2 + + # ==== RELEASE ==== + - name: Upload Release + if: github.event.action == 'published' && matrix.config.artifact + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./soro-s-${{ matrix.config.artifact }}.tar.bz2 + asset_name: soro-s-${{ matrix.config.artifact }}.tar.bz2 + asset_content_type: application/x-tar + + docker: + runs-on: ubuntu-20.04 + needs: linux + steps: + - uses: actions/checkout@v3 + + - name: Download artifacts + uses: actions/download-artifact@v3 + + - name: Docker setup-buildx + uses: docker/setup-buildx-action@v2 + with: + install: true + + - name: Docker Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: | + ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=edge + + - name: Docker build and push + uses: docker/build-push-action@v3 + with: + push: true + context: . + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f80995ea..d1d04371 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -11,13 +11,14 @@ on: jobs: windows-build: - runs-on: windows-2019 + runs-on: windows-2022 strategy: fail-fast: false matrix: config: - preset: msvc-release + artifact: windows-amd64 - preset: msvc-debug env: @@ -42,10 +43,49 @@ jobs: $devShell = &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -find **\Microsoft.VisualStudio.DevShell.dll $installPath = &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationpath Import-Module $devShell - Enter-VsDevShell -VsInstallPath $installPath -SkipAutomaticLocation -DevCmdArguments "-arch=amd64 -vcvars_ver=14.29" + Enter-VsDevShell -VsInstallPath $installPath -SkipAutomaticLocation -DevCmdArguments "-arch=amd64 -vcvars_ver=14.34" cmake --preset=${{ matrix.config.preset }} + cmake --build build\${{ matrix.config.preset }} --target soro-server cmake --build build\${{ matrix.config.preset }} --target soro-test # ==== TESTS ==== - name: Run Tests - run: .\build\${{ matrix.config.preset }}\soro-test.exe \ No newline at end of file + run: .\build\${{ matrix.config.preset }}\soro-test.exe + + # ==== WEB TESTS ==== + - name: Run Server + run: | + .\build\${{ matrix.config.preset }}\soro-server.exe -t --resource_dir .\resources --server_resource_dir .\build\${{ matrix.config.preset }}\server_resources\ + + # ==== DISTRIBUTION ==== + - name: Delete unnecessary files + if: matrix.config.artifact + run: | + rm .\build\${{ matrix.config.preset }}\server_resources\infrastructure -r -force + rm .\build\${{ matrix.config.preset }}\server_resources\timetable -r -force + + - name: Create Distribution + if: matrix.config.artifact + run: > + 7z a soro-s-${{ matrix.config.artifact }}.zip + .\build\${{ matrix.config.preset }}\soro-server.exe + .\build\${{ matrix.config.preset }}\server_resources + + - name: Upload Distribution + if: matrix.config.artifact + uses: actions/upload-artifact@v1 + with: + name: soro-s-${{ matrix.config.artifact }} + path: soro-s-${{ matrix.config.artifact }}.zip + + # ==== RELEASE ==== + - name: Upload Release + if: github.event.action == 'published' && matrix.config.artifact + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./soro-s-${{ matrix.config.artifact }}.zip + asset_name: soro-s-${{ matrix.config.artifact }}.zip + asset_content_type: application/zip diff --git a/.pkg b/.pkg index f94141c7..a2e6b7ba 100644 --- a/.pkg +++ b/.pkg @@ -25,7 +25,7 @@ [tiles] url=git@github.com:motis-project/tiles.git branch=master - commit=84b3686006d748b2c48c5ef05763af21b0f8403f + commit=653637bd3fb595eaaca71d9a153ddfcc59930a8b [rapidjson] url=git@github.com:motis-project/rapidjson.git branch=master diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a2345fe..e1bd0193 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,9 @@ option(SORO_LINT "Run clang-tidy with the compiler." OFF) if (SORO_SAN) SET(SORO_COMPILE_DEFINITIONS SORO_SAN ${SORO_COMPILE_DEFINITIONS}) + SET(SORO_LINK_STATIC "") +else () + SET(SORO_LINK_STATIC "-static") endif () if (SORO_LINT) @@ -68,7 +71,6 @@ find_package(Threads REQUIRED) set(SORO_COMPILE_OPTIONS "") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(SORO_COMPILE_OPTIONS ${SORO_COMPILE_OPTIONS} - # -fno-strict-aliasing -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic @@ -87,11 +89,13 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") -Wno-missing-noreturn -Wno-deprecated-experimental-coroutine -Werror + -fcoroutines-ts + ${SORO_LINK_STATIC} ) - if (CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 13) + if (CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 15) set(SORO_COMPILE_OPTIONS ${SORO_COMPILE_OPTIONS} - -Wno-reserved-identifier) + -Wno-deprecated-non-prototype) endif () if (SORO_SAN) @@ -108,6 +112,7 @@ else () -Wextra -Werror -fcoroutines + ${SORO_LINK_STATIC} ) endif () @@ -115,11 +120,38 @@ set(SORO_COMPILE_FEATURES cxx_std_20) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -# Gets us the soro-lib library -include(cmake/soro-lib.cmake) +# === soro-lib === +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + +file(GLOB_RECURSE soro-lib-files src/*.cc) +add_library(soro-lib STATIC EXCLUDE_FROM_ALL ${soro-lib-files}) + +if (SORO_CUDA) + add_library(infrastructure-cuda src/infrastructure/gpu/exclusion.cu) + set_target_properties(infrastructure-cuda PROPERTIES + WINDOWS_EXPORT_ALL_SYMBOLS ON + CUDA_STANDARD 20 + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} + INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/") + target_include_directories(infrastructure-cuda PUBLIC include) + set_property(TARGET infrastructure-cuda PROPERTY CUDA_ARCHITECTURES 75 61) +endif () + +target_compile_options(soro-lib PRIVATE ${SORO_COMPILE_OPTIONS}) +target_compile_features(soro-lib PRIVATE ${SORO_COMPILE_FEATURES}) +target_compile_definitions(soro-lib PRIVATE ${SORO_COMPILE_DEFINITIONS}) +target_include_directories(soro-lib PUBLIC include) +target_link_libraries(soro-lib PRIVATE utl cista date pugixml Threads::Threads) + +if (SORO_CUDA) + target_link_libraries(soro-lib PUBLIC infrastructure-cuda) +endif () # Gets us the soro-server-client target -include(cmake/soro-server-client.cmake) +set(SORO_SERVER_DIR ${CMAKE_CURRENT_BINARY_DIR}) +add_subdirectory(web/server) +add_subdirectory(web/client) # Generate file_paths.h for locating the test resources configure_file(test/include/test/file_paths.h.in @@ -133,7 +165,7 @@ target_compile_options(soro-test PRIVATE ${SORO_COMPILE_OPTIONS}) target_compile_features(soro-test PRIVATE ${SORO_COMPILE_FEATURES}) target_compile_definitions(soro-test PRIVATE ${SORO_COMPILE_DEFINITIONS}) -target_link_libraries(soro-test PUBLIC doctest soro-lib soro-server-lib) +target_link_libraries(soro-test PUBLIC utl doctest date soro-lib soro-server-lib) target_include_directories(soro-test PUBLIC test/include) # Make clang-tidy only output on soro-s files, not on dependencies. @@ -161,9 +193,3 @@ if (SORO_LINT) ) endforeach () endif () - -# add an ALL target for CLion convenience -add_custom_target(ALL) -add_dependencies(ALL - soro-test - soro-server-client) diff --git a/CMakePresets.json b/CMakePresets.json index 0d09988b..f6f7790f 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -17,7 +17,9 @@ "hidden": true, "cacheVariables": { "CMAKE_C_COMPILER": "clang-15", - "CMAKE_CXX_COMPILER": "clang++-15" + "CMAKE_CXX_COMPILER": "clang++-15", + "CMAKE_CXX_FLAGS": "-stdlib=libc++", + "CMAKE_EXE_LINKER_FLAGS": "-lstdc++ -lc++abi -fuse-ld=lld" } }, { @@ -33,7 +35,7 @@ "hidden": true, "binaryDir": "${sourceDir}/build/${presetName}", "toolset": { - "value": "version=14.29", + "value": "version=14.34", "strategy": "external" }, "cacheVariables": { diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..497792a5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM alpine:3.14 +ARG TARGETARCH +ADD soro-s-linux-$TARGETARCH/soro-s-linux-$TARGETARCH.tar.bz2 / +RUN addgroup -S soro-s && adduser -S soro-s -G soro-s && \ + chown -R soro-s:soro-s /soro-s/ + +EXPOSE 8080 +VOLUME ["/resources"] +WORKDIR /soro-s +USER soro-s +CMD ["/soro-s/soro-server", "--resource_dir", "/resources"] diff --git a/README.md b/README.md index 30b87897..1b8bebed 100644 --- a/README.md +++ b/README.md @@ -1,182 +1,21 @@

-![Linux & Mac OS Build](https://github.com/motis-project/rapid/workflows/Unix%20Build/badge.svg) +![Linux & Mac OS Build](https://github.com/motis-project/rapid/workflows/Linux%20Build/badge.svg) ![Windows Build](https://github.com/motis-project/rapid/workflows/Windows%20Build/badge.svg) -## SORO-S Setup (Ubuntu 20.04) +## Developer Setup -If this setup does not work for you check out the unix.yml or windows.yml file -for the github actions. There should -always be a configuration for a successful build. +To setup SORO-S for developing purposes please follow one of these instructions. -Newer versions of Ubuntu or other distributions might not need to excute all -steps, since some packages might already be -included. +- [Linux Developer Setup (Ubuntu 20.04)](https://github.com/motis-project/soro-s/wiki/Linux-Developer-Setup) +- [Windows Developer Setup (Visual Studio 2022)](https://github.com/motis-project/soro-s/wiki/Windows-Developer-Setup) -### Tools: +## Usage Setup -- Git -- CMake >= 3.19 -- GCC 11 -- Clang 15 -- Ninja +To simply use SORO-S you can build it yourself you have the following options: -### Steps: - -Install either clang or GCC or both. - -#### Installing Clang - -Add Repositories and signing key. - -```shell -wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - -echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main" | sudo tee -a /etc/apt/sources.list -sudo apt update -``` - -Install clang and additional tooling. - -```shell -sudo apt install clang-15 lldb-15 lld-15 clangd-15 clang-tidy-15 clang-format-15 clang-tools-15 llvm-15-dev llvm-15-tools libomp-15-dev libc++-15-dev libc++abi-15-dev libclang-common-15-dev libclang-15-dev libclang-cpp15-dev libunwind-15-dev -``` - -#### Installing GCC - -Add Toolchains Repo. - -```shell -sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa && sudo apt update -``` - -Install GCC. - -```shell -sudo apt install g++-11 -``` - -#### Installing remaining tools - -First add the kitware repository for the latest cmake version. To do this add -the kitware signing key. - -```shell -wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null -``` - -Then add the kitware repository itself. - -```shell -sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' -``` - -Then install the remaining tools. - -```shell -sudo apt install git cmake ninja-build -``` - -#### Cloning the SORO-S repository - -First add your SSH key to your ssh-agent (adjust path to your github SSH key). - -```shell -ssh-add ~./ssh/id_rsa -``` - -Clone the repository. - -```shell -git clone git@github.com:motis-project/soro-s.git -``` - -#### Building the tests - -Invoke cmake with the 'clang-release' preset for a build with clang .. - -```shell -cd soro-s && cmake --preset clang-release -``` - -.. or 'gcc-release' for a build with gcc. - -[comment]: <> (Create soro-test build files either with GCC as the compiler ...) - -```shell -cd soro-s && cmake --preset gcc-release -``` - -Navigate to the build directory and build the tests for a clang build .. - -```shell -cd build/clang-release && ninja -``` - -.. or a gcc build. - -```shell -cd build/gcc-release && ninja -``` - -Test & Run. - -```shell -./soro-test -``` - -### Webinterface - -To use the webinterface locally you need the following: - -- Python 3 - -Install the dependencies: - -```shell -sudo apt install python3 -``` - -#### Building the web interface - -Build the webinterface by invoking the following in a build directory. - -```shell -ninja soro-server-client -``` - -Start the soro-server. - -```shell -./soro-server -``` - -You can access the interface now on [localhost:8080](http://localhost:8080). - -### SORO-S CMake Flags - -These are the custom CMake flags. Turn them on by passing -D{Flag Name}=On to -CMake. - -| Flag Name | Effect | -|-----------|--------| -|SORO_LINT | Runs clang-tidy alongside the compilation process.| -|SORO_SAN | Only works when clang is set as the compiler. Compiles SORO-S with the C/CXX flags "-fsanitize=address,undefined".| -|SERIALIZE | When enabled uses [cista](https://github.com/felixguendling/cista) to enable serialization.| -|USE_CISTA_RAW | Only works when SERIALIZE=On. Uses the cista::raw instead of cista::offset. | -|SORO_CUDA | Enables GPU-accelerated computing for select tasks. | - -## SORO-S Setup (Visual Studio 2022) - -Please make sure that you have the following tools installed and available in -the build environment. - -- Git -- Ninja -- CMake -- Python (only needed for the web interface) - -Currently, only MSVC 14.29 is supported. Please make sure that you have the -appropriate version installed. - -After adding the repository in Visual Studio select either the MSVC Debug or -MSVC Release preset to compile. +- Building it yourself by following one of the developer setup guides above +- Follow + the [Docker Container Setup Guide](https://github.com/motis-project/soro-s/wiki/Docker-Container-Usage) +- Use one of the + supplied [binaries](https://github.com/motis-project/soro-s/releases) diff --git a/cmake/buildcache.cmake b/cmake/buildcache.cmake index 35d7ba6c..5e758851 100644 --- a/cmake/buildcache.cmake +++ b/cmake/buildcache.cmake @@ -3,33 +3,33 @@ option(NO_BUILDCACHE "Disable build caching using buildcache" Off) set(buildcache-bin ${CMAKE_CURRENT_BINARY_DIR}/buildcache/bin/buildcache) get_property(rule-launch-set GLOBAL PROPERTY RULE_LAUNCH_COMPILE SET) if (NO_BUILDCACHE) - message(STATUS "NO_BUILDCACHE set, buildcache disabled") -elseif(rule-launch-set) - message(STATUS "Global property RULE_LAUNCH_COMPILE already set - skipping buildcache") -else() - find_program(buildcache_program buildcache HINTS ${CMAKE_CURRENT_BINARY_DIR}/buildcache/bin) - if(buildcache_program) - message(STATUS "Using buildcache: ${buildcache_program}") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${buildcache_program}") - else() - message(STATUS "buildcache not found - downloading") - if (APPLE) - set(buildcache-archive "buildcache-macos.zip") - elseif(UNIX) - set(buildcache-archive "buildcache-linux.tar.gz") - elseif(WIN32) - set(buildcache-archive "buildcache-win-msvc.zip") - else() - message(FATAL "Error: NO_BUILDCACHE was not set but buildcache was not in path and system OS detection failed") - endif() + message(STATUS "NO_BUILDCACHE set, buildcache disabled") +elseif (rule-launch-set) + message(STATUS "Global property RULE_LAUNCH_COMPILE already set - skipping buildcache") +else () + find_program(buildcache_program buildcache HINTS ${CMAKE_CURRENT_BINARY_DIR}/buildcache/bin) + if (buildcache_program) + message(STATUS "Using buildcache: ${buildcache_program}") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${buildcache_program}") + else () + message(STATUS "buildcache not found - downloading") + if (APPLE) + set(buildcache-archive "buildcache-macos.zip") + elseif (UNIX) + set(buildcache-archive "buildcache-linux.tar.gz") + elseif (WIN32) + set(buildcache-archive "buildcache-win-msvc.zip") + else () + message(FATAL "Error: NO_BUILDCACHE was not set but buildcache was not in path and system OS detection failed") + endif () - set(buildcache-url "https://github.com/mbitsnbites/buildcache/releases/download/v0.22.3/${buildcache-archive}") - message(STATUS "Downloading buildcache binary from ${buildcache-url}") - file(DOWNLOAD "${buildcache-url}" ${CMAKE_CURRENT_BINARY_DIR}/${buildcache-archive}) - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_CURRENT_BINARY_DIR}/${buildcache-archive} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - message(STATUS "using buildcache: ${buildcache-bin}") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${buildcache-bin}) - endif() -endif() \ No newline at end of file + set(buildcache-url "https://github.com/mbitsnbites/buildcache/releases/download/v0.22.3/${buildcache-archive}") + message(STATUS "Downloading buildcache binary from ${buildcache-url}") + file(DOWNLOAD "${buildcache-url}" ${CMAKE_CURRENT_BINARY_DIR}/${buildcache-archive}) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_CURRENT_BINARY_DIR}/${buildcache-archive} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + message(STATUS "using buildcache: ${buildcache-bin}") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${buildcache-bin}) + endif () +endif () \ No newline at end of file diff --git a/cmake/soro-lib.cmake b/cmake/soro-lib.cmake deleted file mode 100644 index 15154415..00000000 --- a/cmake/soro-lib.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# This file is responsible for defining the 'soro-lib' target - -file(GLOB_RECURSE soro-lib-files src/*.cc) -add_library(soro-lib EXCLUDE_FROM_ALL ${soro-lib-files}) - -if (SORO_CUDA) - add_library(infrastructure-cuda src/infrastructure/gpu/exclusion.cu) - set_target_properties(infrastructure-cuda PROPERTIES - WINDOWS_EXPORT_ALL_SYMBOLS ON - CUDA_STANDARD 20 - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} - INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/") - target_include_directories(infrastructure-cuda PUBLIC include) - set_property(TARGET infrastructure-cuda PROPERTY CUDA_ARCHITECTURES 75 61) -endif () - -if (${CMAKE_USE_PTHREADS_INIT}) - set(SORO_LIB_COMPILE_OPTIONS "-pthread") -endif () - -target_compile_options(soro-lib PRIVATE ${SORO_COMPILE_OPTIONS} ${SORO_LIB_COMPILE_OPTIONS}) -target_compile_features(soro-lib PRIVATE ${SORO_COMPILE_FEATURES}) -target_compile_definitions(soro-lib PUBLIC ${SORO_COMPILE_DEFINITIONS}) -target_include_directories(soro-lib PUBLIC include) -target_link_libraries(soro-lib PUBLIC utl cista date pugixml tar Threads::Threads) - -if (SORO_CUDA) - target_link_libraries(soro-lib PUBLIC infrastructure-cuda) -endif () diff --git a/cmake/soro-server-client.cmake b/cmake/soro-server-client.cmake deleted file mode 100644 index cd4abbe6..00000000 --- a/cmake/soro-server-client.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# This file is responsible for building the soro-server, -# which includes the soro-client - -add_custom_target(soro-server-client) - -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - -# SERVER -set(SORO_SERVER_DIR ${CMAKE_CURRENT_BINARY_DIR}) -file(MAKE_DIRECTORY ${SORO_SERVER_DIR}) - -add_subdirectory(web/server/) -add_dependencies(soro-server-client soro-server) - -# CLIENT -file(GLOB_RECURSE soro-client-files - web/client/*.html - web/client/*.css - web/client/*.js - web/client/*.ico - web/client/*.png - web/client/*.svg - web/client/*.map) - -foreach (file ${soro-client-files}) - set(path ${file}) - cmake_path(RELATIVE_PATH path BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/web/client/ OUTPUT_VARIABLE relative-path) - configure_file(${file} ${SORO_SERVER_DIR}/server_resources/${relative-path} COPYONLY) -endforeach () diff --git a/include/soro/utls/coroutine/generator.h b/include/soro/utls/coroutine/generator.h index d16ff5b3..867cefed 100644 --- a/include/soro/utls/coroutine/generator.h +++ b/include/soro/utls/coroutine/generator.h @@ -9,7 +9,7 @@ #pragma once -#if defined(__EMSCRIPTEN__) +#if defined(__clang__) #include #else #include @@ -23,7 +23,7 @@ namespace soro::utls { -#if defined(__EMSCRIPTEN__) +#if defined(__clang__) namespace coro = std::experimental; #else namespace coro = std; diff --git a/include/soro/utls/coroutine/iterator.h b/include/soro/utls/coroutine/iterator.h index b2c17680..3024af89 100644 --- a/include/soro/utls/coroutine/iterator.h +++ b/include/soro/utls/coroutine/iterator.h @@ -1,6 +1,6 @@ #pragma once -#if defined(__EMSCRIPTEN__) +#if defined(__clang__) #include #else #include @@ -8,7 +8,7 @@ namespace soro::utls { -#if defined(__EMSCRIPTEN__) +#if defined(__clang__) namespace coro = std::experimental; #else namespace coro = std; diff --git a/include/soro/utls/coroutine/recursive_generator.h b/include/soro/utls/coroutine/recursive_generator.h index cace7bba..b3d34df9 100644 --- a/include/soro/utls/coroutine/recursive_generator.h +++ b/include/soro/utls/coroutine/recursive_generator.h @@ -9,7 +9,7 @@ #pragma once -#if defined(__EMSCRIPTEN__) +#if defined(__clang__) #include #else #include @@ -26,7 +26,7 @@ namespace soro::utls { -#if defined(__EMSCRIPTEN__) +#if defined(__clang__) namespace coro = std::experimental; #else namespace coro = std; diff --git a/include/soro/utls/file/tar_reader.h b/include/soro/utls/file/tar_reader.h deleted file mode 100644 index 8fab8360..00000000 --- a/include/soro/utls/file/tar_reader.h +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "tar/util.h" - -// TODO(julian) move this and zstd_file into utl/tar - -namespace soro::utls { - -inline unsigned parse_oct(std::string_view s) { - unsigned i = 0; - - auto p = begin(s); - auto n = s.size(); - while ((*p < '0' || *p > '7') && n > 0) { - ++p; - --n; - } - - while (*p >= '0' && *p <= '7' && n > 0) { - i *= 8; - i += static_cast(*p - '0'); - ++p; - --n; - } - - return i; -} - -inline bool is_end_of_archive(std::string_view header) { - tar::verify(header.length() == 512); - return std::all_of(begin(header), end(header), - [](auto&& c) { return c == 0; }); -} - -inline bool check_checksum(std::string_view p) { - auto u = 0U; - for (auto n = 0U; n < 512; ++n) { - if (n < 148 || n > 155) { - u += static_cast(p[n]); - } else { - u += 0x20; - } - } - return u == parse_oct(p.substr(148, 8)); -} - -inline bool is_file(std::string_view buf) { - auto const file_type = buf[156]; - return file_type == 0 || file_type == '0'; -} - -inline unsigned next_multiple_512(unsigned n) { - if (n == 0) { - return 0; - } else { - unsigned a = n - 1; - a = a >> 9; - a = a + 1; - return a << 9; - } -} - -template -struct tar_reader { - explicit tar_reader(Reader&& r) : reader_{std::move(r)}, next_skip_{0} {} - - std::optional read() { - while (true) { - reader_.skip(next_skip_); - next_skip_ = 0; - - auto const opt_header = reader_.read(512); - tar::verify(opt_header.has_value(), "invalid end of archive"); - - auto const header = *opt_header; - if (is_end_of_archive(header)) { - return {}; - } - - tar::verify(header.size() == 512, "invalid tar file (size < 512)"); - tar::verify(check_checksum(header), "invalid checksum"); - - auto const file_size = parse_oct(header.substr(124, 12)); - auto const bytes_to_read = next_multiple_512(file_size); - current_file_name_ = header.substr( - 0, std::min(header.find('\0'), static_cast(200ULL))); - if (is_file(header)) { - auto const buf = reader_.read(file_size); - tar::verify(buf.value_or("").size() == file_size, - "invalid file in tar"); - next_skip_ = bytes_to_read - file_size; - return buf; - } - - reader_.skip(bytes_to_read); - } - } - - float progress() const { return reader_.progress(); } - - std::string current_file_name() const { return current_file_name_; } - - Reader reader_; - size_t next_skip_; - std::string current_file_name_; -}; - -} // namespace soro::utls diff --git a/include/soro/utls/file/zstd_file.h b/include/soro/utls/file/zstd_file.h deleted file mode 100644 index c15d2660..00000000 --- a/include/soro/utls/file/zstd_file.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "utl/verify.h" -#include "zstd.h" - -namespace soro { - -struct zstd_file { - static constexpr auto const MAX_CONSUMED_BUFFER = 1024 * 1024; - - zstd_file(unsigned char const* data, std::size_t const size) - : it_{data}, - data_{data}, - size_{size}, - out_(2 * ZSTD_DStreamOutSize() + MAX_CONSUMED_BUFFER), - out_fill_{0}, - prev_read_size_{0}, - dstream_{ZSTD_createDStream(), &ZSTD_freeDStream}, - next_to_read_{dstream_ ? ZSTD_initDStream(dstream_.get()) : 0}, - offset_{0} { - utl::verify(dstream_ != nullptr, "ZSTD_createDStream() error"); - utl::verify(!static_cast(ZSTD_isError(next_to_read_)), - "ZSTD_initDStream() error"); - } - - std::optional read(std::size_t const n) { - consume(n); - read_to_out(n); - return out_fill_ >= n - ? std::make_optional(std::string_view{out_.data() + offset_, n}) - : std::nullopt; - } - - void read_to_out(std::size_t const min_size) { - while (true) { - if (out_fill_ >= min_size) { - break; - } - - auto const start = it_; - auto const last = data_ + size_; - auto const rest_size = static_cast(last - start); - auto const bytes_read = std::min(next_to_read_, rest_size); - it_ += bytes_read; - auto const buf_in = start; - auto const num_bytes_read = bytes_read; - - if (num_bytes_read == 0) { - break; - } - - auto input = ZSTD_inBuffer{buf_in, num_bytes_read, 0}; - while (input.pos < input.size) { - resize_buffer(); - auto output = ZSTD_outBuffer{out_.data() + offset_ + out_fill_, - ZSTD_DStreamOutSize(), 0}; - next_to_read_ = ZSTD_decompressStream(dstream_.get(), &output, &input); - utl::verify(!static_cast(ZSTD_isError(next_to_read_)), - ZSTD_getErrorName(next_to_read_)); - out_fill_ += output.pos; - } - } - } - - void resize_buffer() { - if (out_.size() - offset_ - out_fill_ >= ZSTD_DStreamOutSize()) { - return; - } - - out_.resize(offset_ + out_fill_ + 2 * ZSTD_DStreamOutSize()); - } - - void skip(std::size_t const n) { - consume(n); - read_to_out(n); - } - - void consume(std::size_t const next_read_size) { - offset_ += prev_read_size_; - out_fill_ -= prev_read_size_; - prev_read_size_ = next_read_size; - - if (offset_ > MAX_CONSUMED_BUFFER) { - out_.erase(begin(out_), - std::next(begin(out_), static_cast(offset_))); - offset_ = 0; - } - } - - unsigned char const* it_; - unsigned char const* data_; - std::size_t size_; - std::vector out_; - std::size_t out_fill_; - std::size_t prev_read_size_; - std::unique_ptr dstream_; - std::size_t next_to_read_; - std::size_t offset_; -}; - -} // namespace soro diff --git a/include/soro/utls/parse_fp.h b/include/soro/utls/parse_fp.h index 57a4a8dc..59576ec0 100644 --- a/include/soro/utls/parse_fp.h +++ b/include/soro/utls/parse_fp.h @@ -2,10 +2,7 @@ #include #include - -#if defined(__EMSCRIPTEN__) -#include -#endif +#include #include "utl/verify.h" @@ -22,25 +19,19 @@ constexpr bool contains_char(char const* start, char const* end, return std::any_of(start, end, [&](auto&& c) { return c == needle; }); } -#if defined(__EMSCRIPTEN__) -template -constexpr T parse_fp(const char* const start, const char* const) { - T result = std::numeric_limits::max(); - - result = static_cast(std::atof(start)); - - utl::verify(!std::isnan(result), - "Error while parsing floating point with atof: {}.", - std::quoted(start)); - - return result; -} -#else - template constexpr T parse_fp(const char* const start, const char* const end) { T result = std::numeric_limits::max(); +#if defined(_LIBCPP_VERSION) + // TODO(julian) this can be removed when libc++ supports from_chars for fp + std::size_t processed = 0; + result = static_cast(std::stod(start, &processed)); + sassert(processed == static_cast(end - start), + "Processed only {} chars while parsing floating point {}, should " + "have processed {}.", + processed, start, end - start); +#else auto const [ptr, ec] = std::from_chars(start, end, result); sassert(ec == std::errc{}, "Error while parsing floating point input {}.", @@ -49,9 +40,10 @@ constexpr T parse_fp(const char* const start, const char* const end) { sassert(ptr == end, "Error while parsing floating point input {}.", std::quoted(start)); +#endif + return result; } -#endif } // namespace detail diff --git a/include/soro/utls/sassert.h b/include/soro/utls/sassert.h index e4cf6f71..d74fdd2d 100644 --- a/include/soro/utls/sassert.h +++ b/include/soro/utls/sassert.h @@ -4,6 +4,7 @@ #include #include #include +#include // TODO(julian) replace this with the c++20 header when available #include "fmt/ostream.h" diff --git a/src/infrastructure/parsers/iss/iss_files.cc b/src/infrastructure/parsers/iss/iss_files.cc index 524feb2d..8c687a25 100644 --- a/src/infrastructure/parsers/iss/iss_files.cc +++ b/src/infrastructure/parsers/iss/iss_files.cc @@ -6,8 +6,6 @@ #include "utl/timer.h" #include "soro/utls/file/file_to_binary_buffer.h" -#include "soro/utls/file/tar_reader.h" -#include "soro/utls/file/zstd_file.h" namespace fs = std::filesystem; diff --git a/web/CMakeLists.txt b/web/CMakeLists.txt new file mode 100644 index 00000000..e69de29b diff --git a/web/client/CMakeLists.txt b/web/client/CMakeLists.txt new file mode 100644 index 00000000..8a4d5354 --- /dev/null +++ b/web/client/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.18) +project(soro) + +file(GLOB_RECURSE soro-client-files + *.html + *.css + *.js + *.ico + *.png + *.svg + *.map) + +foreach (file ${soro-client-files}) + set(path ${file}) + cmake_path(RELATIVE_PATH path BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE relative-path) + configure_file(${file} ${SORO_SERVER_DIR}/server_resources/${relative-path} COPYONLY) +endforeach () + + diff --git a/web/server/CMakeLists.txt b/web/server/CMakeLists.txt index 93c47c43..804aa8bf 100644 --- a/web/server/CMakeLists.txt +++ b/web/server/CMakeLists.txt @@ -1,32 +1,27 @@ cmake_minimum_required(VERSION 3.18) project(soro) -if (MSVC) - set(TILES_WARNINGS "/W4") -else () - set(TILES_WARNINGS "-Wall" "-Wextra") -endif () +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") file(GLOB_RECURSE soro-server-files src/*.cc) add_library(soro-server-lib STATIC EXCLUDE_FROM_ALL ${soro-server-files}) -target_compile_options(soro-server-lib PRIVATE ${TILES_WARNINGS}) -target_compile_definitions(soro-server-lib PRIVATE ${SORO_COMPILE_DEFINITIONS} BOOST_BEAST_USE_STD_STRING_VIEW=1) +target_compile_options(soro-server-lib PRIVATE ${SORO_COMPILE_OPTIONS}) target_compile_features(soro-server-lib PRIVATE ${SORO_COMPILE_FEATURES}) +target_compile_definitions(soro-server-lib PRIVATE ${SORO_COMPILE_DEFINITIONS} BOOST_BEAST_USE_STD_STRING_VIEW=1) target_include_directories(soro-server-lib PUBLIC include) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/server_resources/) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/server_resources/icons) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/server_resources/client) +file(MAKE_DIRECTORY ${SORO_SERVER_DIR}/server_resources/) +file(MAKE_DIRECTORY ${SORO_SERVER_DIR}/server_resources/icons) # Copy the lua profiles to the binary directory file(GLOB_RECURSE soro-server-profiles profile/*.lua) foreach (file ${soro-server-profiles}) set(path ${file}) cmake_path(RELATIVE_PATH path BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE relative-path) - configure_file(${file} ${CMAKE_BINARY_DIR}/${relative-path} COPYONLY) + configure_file(${file} ${SORO_SERVER_DIR}/server_resources/${relative-path} COPYONLY) endforeach () # Copy the server resources to the server_resources directory in the binary directory. Includes: @@ -36,9 +31,17 @@ file(GLOB_RECURSE soro-server-resources server_resources/*.png server_resources/ foreach (file ${soro-server-resources}) set(path ${file}) cmake_path(RELATIVE_PATH path BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE relative-path) - configure_file(${file} ${CMAKE_BINARY_DIR}/${relative-path} COPYONLY) + configure_file(${file} ${SORO_SERVER_DIR}/${relative-path} COPYONLY) endforeach () +configure_file(../../resources/misc/btrs_geo.csv ${SORO_SERVER_DIR}/server_resources/misc/btrs_geo.csv COPYONLY) +file(MAKE_DIRECTORY ${SORO_SERVER_DIR}/server_resources/resources/) +file(MAKE_DIRECTORY ${SORO_SERVER_DIR}/server_resources/resources/infrastructure) +file(MAKE_DIRECTORY ${SORO_SERVER_DIR}/server_resources/resources/timetable) + +# Disable warnings for tiles dependency by configuring it as a systems dependency +set_target_properties(tiles PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) + target_link_libraries(soro-server-lib PUBLIC pugixml rapidjson @@ -47,13 +50,16 @@ target_link_libraries(soro-server-lib PUBLIC tiles-import-library boost soro-lib + ${SORO_LINK_STATIC} ) -add_executable(soro-server EXCLUDE_FROM_ALL src/server.cc) +add_executable(soro-server src/server.cc) +set_target_properties(soro-server PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${SORO_SERVER_DIR}) -target_compile_options(soro-server PRIVATE ${TILES_WARNINGS}) -target_compile_definitions(soro-server PRIVATE ${SORO_COMPILE_DEFINITIONS}) +target_compile_options(soro-server PRIVATE ${SORO_COMPILE_OPTIONS}) target_compile_features(soro-server PRIVATE ${SORO_COMPILE_FEATURES}) +target_compile_definitions(soro-server PRIVATE ${SORO_COMPILE_DEFINITIONS}) target_link_libraries(soro-server PUBLIC soro-server-lib) diff --git a/web/server/include/soro/server/import/import.h b/web/server/include/soro/server/import/import.h index 1b33fcb9..527bdf39 100644 --- a/web/server/include/soro/server/import/import.h +++ b/web/server/include/soro/server/import/import.h @@ -9,11 +9,12 @@ namespace soro::server { namespace fs = std::filesystem; struct import_settings { - import_settings(fs::path osm_path, fs::path db_path, fs::path tmp_dir) + import_settings(fs::path osm_path, fs::path db_path, fs::path tmp_dir, + fs::path profile_path) : osm_path_{std::move(osm_path)}, db_path_{std::move(db_path)}, tmp_dir_{std::move(tmp_dir)}, - osm_profile_{"profile/profile.lua"} {} + osm_profile_{std::move(profile_path)} {} fs::path osm_path_; fs::path db_path_; diff --git a/web/server/src/http_server.cc b/web/server/src/http_server.cc index 0a72758c..35ca8e25 100644 --- a/web/server/src/http_server.cc +++ b/web/server/src/http_server.cc @@ -24,7 +24,7 @@ void http_connection::start() { try { self->callback_(self->request_, self->response_); } catch (std::exception const& e) { - uLOG(err) << "unhandled error: {}", e.what(); + uLOG(err) << "unhandled error: {}" << e.what(); self->response_.result(http::status::internal_server_error); } catch (...) { uLOG(err) << "unhandled unknown error"; @@ -33,9 +33,9 @@ void http_connection::start() { self->response_.set(http::field::content_length, std::to_string(self->response_.body().size())); http::async_write(self->socket_, self->response_, - [self](beast::error_code ec, std::size_t) { + [self](beast::error_code async_ec, std::size_t) { self->socket_.shutdown(tcp::socket::shutdown_send, - ec); + async_ec); self->deadline_.cancel(); }); } diff --git a/web/server/src/osm_export/osm_export.cc b/web/server/src/osm_export/osm_export.cc index aec218f1..6e9caa8d 100644 --- a/web/server/src/osm_export/osm_export.cc +++ b/web/server/src/osm_export/osm_export.cc @@ -70,10 +70,12 @@ void create_way_osm(pugi::xml_node& osm_node, element_id const first, osm_add_tag(railway_str, rail_str, way); } -std::size_t create_interpolation_osm(auto osm, auto const& interpolation, - auto id, auto& osm_info) { +infra::element_id create_interpolation_osm(pugi::xml_node osm, + interpolation const& interpolation, + infra::element_id const id, + osm_information& osm_info) { std::vector ids; - osm_info.ways_.emplace_back(std::pair(interpolation.first_elem_, id)); + osm_info.ways_.emplace_back(interpolation.first_elem_, id); for (auto i = 0UL; i < interpolation.points_.size(); i++) { if (i < interpolation.points_.size() - 1) { osm_info.ways_.emplace_back(std::pair(id + i, id + i + 1)); @@ -85,11 +87,12 @@ std::size_t create_interpolation_osm(auto osm, auto const& interpolation, osm_add_coordinates(auxiliary_coords, auxiliary_node); osm_add_tag(type_str, interpolation_str, auxiliary_node); } - osm_info.ways_.emplace_back(std::pair(id + interpolation.points_.size() - 1, - interpolation.second_elem_)); + osm_info.ways_.emplace_back( + static_cast(id + interpolation.points_.size() - 1), + interpolation.second_elem_); osm_info.element_to_interpolation_nodes_[interpolation.first_elem_] = std::make_pair(interpolation.second_elem_, ids); - return id + interpolation.points_.size(); + return static_cast(id + interpolation.points_.size()); } void create_ways(auto& osm_info, infrastructure_t const& iss, element_ptr e) { @@ -195,7 +198,7 @@ pugi::xml_document export_to_osm(soro::infra::infrastructure_t const& iss) { append_fragment(osm_node, e.get()); } - auto id = osm_info.nodes_.back().first + 1; + auto id = static_cast(osm_info.nodes_.back().first + 1); uLOG(info) << "[ OSM Export ] Interpolations to OSM."; for (const auto& interpolation : osm_info.interpolations_) { diff --git a/web/server/src/server.cc b/web/server/src/server.cc index df6665d7..ed54c5b5 100644 --- a/web/server/src/server.cc +++ b/web/server/src/server.cc @@ -14,12 +14,7 @@ namespace fs = std::filesystem; struct server_settings { utl::cmd_line_flag - resource_dir_{"../../resources/"}; - - utl::cmd_line_flag - misc_dir_{"../../resources/misc/"}; + resource_dir_{"server_resources/resources/"}; utl::cmd_line_flag @@ -67,7 +62,7 @@ int main(int argc, char const** argv) { return failed_startup(); } - auto const coord_file = s.misc_dir_ / "btrs_geo.csv"; + auto const coord_file = s.server_resource_dir_ / "misc" / "btrs_geo.csv"; fs::path const tt_dir = s.server_resource_dir_ / "timetable"; fs::path const infra_dir = s.server_resource_dir_ / "infrastructure"; @@ -128,7 +123,7 @@ int main(int argc, char const** argv) { osm_file, infra_res_dir / "tiles" / infra_file.filename().replace_extension(".mdb"), - tmp_dir); + tmp_dir, s.server_resource_dir_ / "profile" / "profile.lua"); soro::server::import_tiles(import_settings); }