diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index db25a0b..240b7cb 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -9,16 +9,18 @@ on: jobs: build: runs-on: ubuntu-latest - + env: + CMAKE_BUILD_TYPE: Debug + BUILD_DIR: ${{github.workspace}}/build steps: - uses: actions/checkout@v3 - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Debug -DTESTING=ON + run: cmake -B "$BUILD_DIR" - name: Build - run: cmake --build ${{github.workspace}}/build + run: cmake --build "$BUILD_DIR" --config $CMAKE_BUILD_TYPE - name: Test working-directory: ${{github.workspace}}/build - run: ctest + run: ctest --config $CMAKE_BUILD_TYPE --output-on-failure diff --git a/.gitignore b/.gitignore index 7ec5089..a8d858e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /win-build /.idea /build +/build-* /cmake-build* diff --git a/CMakeLists.txt b/CMakeLists.txt index b0bb4fa..c90a5d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,14 @@ -cmake_minimum_required(VERSION 3.22) -option(TESTING "Enables unit testing" OFF) +cmake_minimum_required(VERSION 3.15) project(ULS CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) option(ULS_WITH_TESTS "ULS Unit Tests" ON) +option(ULS_WITH_WERROR "Enable warnings as errors" ON) #Hack used to force UTAP to compile statically set(BUILD_SHARED_LIBS OFF) @@ -16,6 +17,16 @@ set(BUILD_SHARED_LIBS OFF) include(cmake/utap.cmake) include(cmake/nlohmann.cmake) +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang") + add_compile_options(-Wpedantic -Wall -Wextra) + if (ULS_WITH_WERROR) + add_compile_options(-Werror) + endif(ULS_WITH_WERROR) +elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + add_compile_options(/W4) +endif() + + add_subdirectory(src) if (ULS_WITH_TESTS) diff --git a/README.md b/README.md index ba78609..1945880 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,23 @@ This is the UPPAAL language server or ULS for short ### Building -`cmake -B build` -`cmake --build build` +```shell +cmake -B build +cmake --build build +``` -### Windows crosscompilation -Install x86_64-w64-mingw32 gcc compiler and run with toolchain file -`cmake -B build -DCMAKE_TOOLCHAIN_FILE=toolchains/mingw-w64_toolchain.cmake` +### Windows Cross-Compilation +Install `x86_64-w64-mingw32` GCC cross-compiler and run with toolchain file: +```shell +cmake -B build -DCMAKE_TOOLCHAIN_FILE=toolchains/x86_64-w64-mingw32.cmake +cmake --build build +``` + +See `compile.sh` for other build options. ### Dependencies This project uses the following libraries under licenses: -UTAP --- https://github.com/UPPAALModelChecker/utap +UTAP UPPAAL https://github.com/UPPAALModelChecker/utap nlohmann json MIT https://github.com/nlohmann/json doctest MIT https://github.com/doctest/doctest diff --git a/compile.sh b/compile.sh new file mode 100755 index 0000000..b165f9c --- /dev/null +++ b/compile.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -e + +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" +BUILD_TYPE="$CMAKE_BUILD_TYPE" + +if [ "$#" == 0 ]; then + echo "Script $0 compiles the project for specific targets specified as arguments." + echo "The following targets are supported:" + for f in "$PROJECT_DIR"/toolchains/*.cmake ; do + target=$(basename "$f") + target=${target%.cmake} + echo -n " $target" + done + echo "" + echo "The script is sensitive to CMAKE_BUILD_TYPE and CMAKE_TOOLCHAIN_FILE." + exit 1 +fi + +for target in "$@" ; do + if [ -z "$TOOLCHAIN_FILE" ]; then + if [ -r "$PROJECT_DIR/toolchains/$target.cmake" ]; then + export CMAKE_TOOLCHAIN_FILE="$PROJECT_DIR/toolchains/$target.cmake" + else + unset CMAKE_TOOLCHAIN_FILE + fi + fi + if [ -z "$BUILD_TYPE" ]; then + export CMAKE_BUILD_TYPE=Debug + fi + BUILD_DIR="build-$target-${CMAKE_BUILD_TYPE,,}" + cmake -B "$BUILD_DIR" -S "$PROJECT_DIR" + cmake --build "$BUILD_DIR" --config $CMAKE_BUILD_TYPE + ctest --test-dir "$BUILD_DIR" --config $CMAKE_BUILD_TYPE --output-on-failure +done diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31bf00d..864c613 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,3 @@ -add_compile_options(-Wpedantic -Wall -Wextra -Werror) - add_library(uls_lib OBJECT server.cpp highlight.cpp system.cpp utap_extension.cpp declarations.cpp renaming.cpp common_data.cpp autocomplete.cpp) target_link_libraries(uls_lib PUBLIC UTAP nlohmann_json::nlohmann_json) target_include_directories(uls_lib PUBLIC "${CMAKE_SOURCE_DIR}/include/") @@ -7,4 +5,4 @@ target_include_directories(uls_lib PUBLIC "${CMAKE_SOURCE_DIR}/include/") add_executable(uls main.cpp) target_link_libraries(uls PRIVATE uls_lib) -install(TARGETS uls RUNTIME) \ No newline at end of file +install(TARGETS uls RUNTIME) diff --git a/src/server.cpp b/src/server.cpp index 449164e..b09d984 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -12,13 +12,12 @@ using json = nlohmann::json; nlohmann::json OK_RESPONSE = {{"res", "OK"}}; nlohmann::json FAIL_RESPONSE = {{"res", "FAIL"}}; -const Command& get_command(const std::vector& commands, const std::string& command_name) +std::vector::const_iterator find_command(const std::vector& commands, const std::string& name) { - for (const auto& command : commands) { - if (command.name == command_name) - return command; - } - throw std::invalid_argument("Unknown command name " + command_name); + auto it = std::find_if(commands.begin(), commands.end(), [&name](const Command& cmd) { return cmd.name == name; }); + if (it == commands.end()) + throw std::invalid_argument("Unknown command " + name); + return it; } void Server::start() @@ -31,10 +30,9 @@ void Server::start() while (is_running) { try { io.in >> message; - - const Command& command = get_command(commands, message["cmd"].get()); - auto response = command.callback(message["args"]); - send("response/" + command.name, response); + auto cmd = find_command(commands, message["cmd"].get()); + auto response = cmd->callback(message["args"]); + send("response/" + cmd->name, response); } catch (nlohmann::json::parse_error& e) { send("error", e.what()); stop(); diff --git a/toolchains/clang.cmake b/toolchains/clang.cmake new file mode 100644 index 0000000..ab5e0c3 --- /dev/null +++ b/toolchains/clang.cmake @@ -0,0 +1,12 @@ +# which tools to use +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +# adjust the default behavior of the FIND_XXX() commands: + +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# search headers and libraries in the target environment +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/toolchains/gcc10.cmake b/toolchains/gcc10.cmake new file mode 100644 index 0000000..21c85da --- /dev/null +++ b/toolchains/gcc10.cmake @@ -0,0 +1,12 @@ +# which tools to use +set(CMAKE_C_COMPILER gcc-10) +set(CMAKE_CXX_COMPILER g++-10) + +# adjust the default behavior of the FIND_XXX() commands: + +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# search headers and libraries in the target environment +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/toolchains/gcc11.cmake b/toolchains/gcc11.cmake new file mode 100644 index 0000000..f26814a --- /dev/null +++ b/toolchains/gcc11.cmake @@ -0,0 +1,12 @@ +# which tools to use +set(CMAKE_C_COMPILER gcc-11) +set(CMAKE_CXX_COMPILER g++-11) + +# adjust the default behavior of the FIND_XXX() commands: + +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# search headers and libraries in the target environment +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/toolchains/gcc12.cmake b/toolchains/gcc12.cmake new file mode 100644 index 0000000..a9072cd --- /dev/null +++ b/toolchains/gcc12.cmake @@ -0,0 +1,12 @@ +# which tools to use +set(CMAKE_C_COMPILER gcc-12) +set(CMAKE_CXX_COMPILER g++-12) + +# adjust the default behavior of the FIND_XXX() commands: + +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# search headers and libraries in the target environment +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/toolchains/gcc13.cmake b/toolchains/gcc13.cmake new file mode 100644 index 0000000..c0cea3a --- /dev/null +++ b/toolchains/gcc13.cmake @@ -0,0 +1,12 @@ +# which tools to use +set(CMAKE_C_COMPILER gcc-13) +set(CMAKE_CXX_COMPILER g++-13) + +# adjust the default behavior of the FIND_XXX() commands: + +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# search headers and libraries in the target environment +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/toolchains/mingw-w64_toolchain.cmake b/toolchains/x86_64-w64-mingw32.cmake similarity index 75% rename from toolchains/mingw-w64_toolchain.cmake rename to toolchains/x86_64-w64-mingw32.cmake index 9989421..681af80 100644 --- a/toolchains/mingw-w64_toolchain.cmake +++ b/toolchains/x86_64-w64-mingw32.cmake @@ -4,15 +4,12 @@ set(CMAKE_SYSTEM_NAME Windows) # which tools to use -set(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc) -set(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++) +set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) add_compile_options(-static) add_link_options(-static) -# here is where the target environment located -set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) - # adjust the default behavior of the FIND_XXX() commands: # search programs in the host environment @@ -28,4 +25,4 @@ set(CMAKE_INSTALL_PREFIX ${CMAKE_FIND_ROOT_PATH}/usr CACHE FILEPATH # initialize required linker flags set(CMAKE_EXE_LINKER_FLAGS_INIT "-static-libgcc -static-libstdc++") -# end of toolchain file \ No newline at end of file +# end of toolchain file