diff --git a/.clang-format b/.clang-format index c4fe09a..6df5d3f 100644 --- a/.clang-format +++ b/.clang-format @@ -66,104 +66,6 @@ ForEachMacros: - Q_FOREACH - BOOST_FOREACH IncludeBlocks: Regroup -IncludeCategories: - - Regex: '^"[a-zA-Z0-9_]*\.' - Priority: 1 - SortPriority: 1 - - Regex: '^"testutils/' - Priority: 2 - SortPriority: 2 - - Regex: '^"tron/' - Priority: 2 - SortPriority: 3 - - Regex: '^"fmi/' - Priority: 2 - SortPriority: 4 - - Regex: '^"verifier/' - Priority: 2 - SortPriority: 5 - - Regex: '^"cora/' - Priority: 2 - SortPriority: 6 - - Regex: '^"tiga/' - Priority: 2 - SortPriority: 7 - - Regex: '^"statmc/' - Priority: 2 - SortPriority: 8 - - Regex: '^"xmltrace/' - Priority: 2 - SortPriority: 9 - - Regex: '^"pipeline/' - Priority: 2 - SortPriority: 10 - - Regex: '^"protocol/' - Priority: 2 - SortPriority: 11 - - Regex: '^"storage/' - Priority: 2 - SortPriority: 12 - - Regex: '^"system/' - Priority: 2 - SortPriority: 13 - - Regex: '^"dbm/' - Priority: 2 - SortPriority: 14 - - Regex: '^"cdd/' - Priority: 2 - SortPriority: 15 - - Regex: '^"polyhedra/' - Priority: 2 - SortPriority: 16 - - Regex: '^"tracer/' - Priority: 2 - SortPriority: 17 - - Regex: '^"utap/' - Priority: 2 - SortPriority: 18 - - Regex: '^"io/' - Priority: 2 - SortPriority: 19 - - Regex: '^"formats/' - Priority: 2 - SortPriority: 20 - - Regex: '^"base/' - Priority: 2 - SortPriority: 21 - - Regex: '^"hash/' - Priority: 2 - SortPriority: 22 - - Regex: '^"debug/' - Priority: 2 - SortPriority: 23 - - Regex: '^$' - Priority: 4 - SortPriority: 31 - - Regex: '^> $GITHUB_ENV +# - name: Build without getlibs +# run: | +# BUILD=build-$TARGET-$CMAKE_BUILD_TYPE +# cmake -B $BUILD +# cmake --build $BUILD --config $CMAKE_BUILD_TYPE +# ctest --test-dir $BUILD -C $CMAKE_BUILD_TYPE + - name: Get dependencies + run: CMAKE_BUILD_TYPE=Release ./getlibs.sh $TARGET + - name: Build with getlibs + run: | + BUILD=build-$TARGET-libs-$CMAKE_BUILD_TYPE + cmake -B $BUILD -DCMAKE_PREFIX_PATH="${{ github.workspace }}/local/$TARGET" + cmake --build $BUILD --config $CMAKE_BUILD_TYPE + ctest --test-dir $BUILD -C $CMAKE_BUILD_TYPE build-win: runs-on: ubuntu-latest + env: + TARGET: x86_64-w64-mingw32 + WINARCH: win64 + CMAKE_BUILD_TYPE: Debug + CTEST_OUTPUT_ON_FAILURE: 1 steps: - - uses: actions/checkout@v2 - - name: Get dependencies - run: | - sudo apt-get update - sudo apt-get install cmake make g++-mingw-w64-x86-64 mingw-w64-x86-64-dev mingw-w64-tools wine wine-binfmt + - uses: actions/checkout@v3 + - name: Setup the toolchain + run: | + sudo apt-get -qqy update + sudo apt-get -qqy install cmake make g++-mingw-w64-x86-64 mingw-w64-x86-64-dev mingw-w64-tools wine wine-binfmt sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix - CMAKE_TOOLCHAIN_FILE="$(pwd)/toolchains/x86_64-w64-mingw32.cmake" ./getlibs.sh - - name: Build and test - run: | - export CTEST_OUTPUT_ON_FAILURE=1 - cmake -DSTATIC=yes -DTESTING=yes -DCMAKE_TOOLCHAIN_FILE=toolchains/x86_64-w64-mingw32.cmake . -B build - cmake --build build - (cd build ; ctest) + WINEPATH=$(${{ github.workspace }}/winepath-for $TARGET) + echo "WINEPATH=$WINEPATH" >> $GITHUB_ENV + CMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/cmake/toolchain/${{ env.TARGET }}.cmake" + echo "CMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE" >> $GITHUB_ENV +# - name: Build without getlibs +# run: | +# BUILD=build-$TARGET-$CMAKE_BUILD_TYPE +# cmake -S . -B $BUILD -DSTATIC=yes +# cmake --build $BUILD --config $CMAKE_BUILD_TYPE +# ctest --test-dir $BUILD -C $CMAKE_BUILD_TYPE + - name: Get dependencies + run: + CMAKE_BUILD_TYPE=Release ./getlibs.sh $TARGET + - name: Build with getlibs + run: | + BUILD=build-$TARGET-libs-$CMAKE_BUILD_TYPE + cmake -B $BUILD -DCMAKE_PREFIX_PATH="${{ github.workspace }}/local/$TARGET" -DSTATIC=yes + cmake --build $BUILD --config $CMAKE_BUILD_TYPE + ctest --test-dir $BUILD -C $CMAKE_BUILD_TYPE build-macos: runs-on: macos-latest + env: + TARGET: x86_64-darwin + CMAKE_BUILD_TYPE: Debug + CTEST_OUTPUT_ON_FAILURE: 1 steps: - - uses: actions/checkout@v2 - - name: Get dependencies - run: brew install boost doctest && ./getlibs.sh - - name: Build and test - run: | - export CTEST_OUTPUT_ON_FAILURE=1 - cmake -DTESTING=yes . -B build - cmake --build build - (cd build ; ctest) + - uses: actions/checkout@v3 + - name: Setup the toolchain + run: | + CMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/cmake/toolchain/$TARGET.cmake" + echo "CMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE" >> $GITHUB_ENV +# - name: Build without getlibs +# run: | +# BUILD=build-$TARGET-$CMAKE_BUILD_TYPE +# cmake -B $BUILD +# cmake --build $BUILD --config $CMAKE_BUILD_TYPE +# ctest --test-dir $BUILD -C $CMAKE_BUILD_TYPE + - name: Get dependencies + run: CMAKE_BUILD_TYPE=Release ./getlibs.sh $TARGET + - name: Build with getlibs + run: | + BUILD=build-$TARGET-libs-$CMAKE_BUILD_TYPE + cmake -S . -B $BUILD -DCMAKE_PREFIX_PATH="${{ github.workspace }}/local/$TARGET" + cmake --build $BUILD --config $CMAKE_BUILD_TYPE + ctest --test-dir $BUILD -C $CMAKE_BUILD_TYPE diff --git a/.gitignore b/.gitignore index 9a9b338..416069f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,7 @@ build* cmake-build* # Getlibs -/libs -/libs-i686-linux -/libs-x86_64-w64-mingw32 -/libs-i686-w64-mingw32 +local # Prerequisites *.d diff --git a/CMakeLists.txt b/CMakeLists.txt index 45bb88e..731a1bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,39 +1,28 @@ -cmake_minimum_required(VERSION 3.15) -project(UCDD VERSION 0.2.1 LANGUAGES CXX C) +cmake_minimum_required(VERSION 3.30) +project(UCDD VERSION 0.2.2 LANGUAGES CXX C) include(CMakePackageConfigHelpers) include(GNUInstallDirs) -option(TESTING "Unit tests" OFF) -option(ASAN "Address Sanitizer" OFF) +option(UCDD_WITH_TESTS "UCDD Unit tests" ON) +option(FIND_FATAL "Stop upon find_package errors" OFF) +include(cmake/sanitizer.cmake) cmake_policy(SET CMP0048 NEW) # project() command manages VERSION variables -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(MULTI_TERMINAL 1) CONFIGURE_FILE("src/config.h.cmake" "include/cdd/config.h") -if(CMAKE_TOOLCHAIN_FILE) - get_filename_component(TARGET ${CMAKE_TOOLCHAIN_FILE} NAME_WLE) - set(LIBS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libs-${TARGET}") -else(CMAKE_TOOLCHAIN_FILE) - set(LIBS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libs") -endif(CMAKE_TOOLCHAIN_FILE) -message(STATUS "Using libs in ${LIBS_DIR}") +if (UCDD_WITH_TESTS) + include(cmake/doctest.cmake) + enable_testing() +endif (UCDD_WITH_TESTS) -set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${LIBS_DIR}") -find_package(xxHash 0.8.0 REQUIRED COMPONENTS xxhash PATHS ${LIBS_DIR}/xxHash) -find_package(UUtils 1.1.1 REQUIRED PATHS ${LIBS_DIR}/UUtils) -find_package(UDBM 2.0.11 REQUIRED PATHS ${LIBS_DIR}/UDBM) - -include_directories( - PRIVATE - # where the library itself will look for its internal headers - ${CMAKE_BINARY_DIR}/include - PUBLIC - # where top-level project will look for the library's public headers - $ - # where external projects will look for the library's public headers - $ -) +include(cmake/xxhash.cmake) +include(cmake/UUtils.cmake) +include(cmake/UDBM.cmake) if(STATIC) # The project does not use neither threads nor networking, but @@ -42,23 +31,15 @@ if(STATIC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive") endif(STATIC) -if (ASAN) - add_compile_options(-fno-omit-frame-pointer -fsanitize=address) - add_link_options(-fno-omit-frame-pointer -fsanitize=address) - message(STATUS "Using Address Sanitizer") -endif(ASAN) - add_subdirectory("src") -if(TESTING) - enable_testing() +if (UCDD_WITH_TESTS) add_subdirectory("test") -endif(TESTING) +endif(UCDD_WITH_TESTS) -write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/UCDDConfigVersion.cmake VERSION ${PACKAGE_VERSION} COMPATIBILITY SameMajorVersion) +write_basic_package_version_file(${PROJECT_BINARY_DIR}/UCDDConfigVersion.cmake VERSION ${PACKAGE_VERSION} COMPATIBILITY SameMajorVersion) install(DIRECTORY include DESTINATION .) -install(TARGETS UCDD EXPORT UCDDConfig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(EXPORT UCDDConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/UCDD) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/UCDDConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/UCDD ) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/cdd/config.h DESTINATION include/cdd/) +install(FILES ${PROJECT_BINARY_DIR}/UCDDConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/UCDD) +install(FILES ${PROJECT_BINARY_DIR}/include/cdd/config.h DESTINATION include/cdd/) diff --git a/README.md b/README.md index 7ee464c..75da04f 100644 --- a/README.md +++ b/README.md @@ -13,48 +13,69 @@ For instance, in nine industrial examples the savings are on average 42% and wit **"Efficient Timed Reachability Analysis Using Clock Difference Diagrams"** by *Gerd Behrmann, Kim Guldstrand Larsen, Justin Pearson, Carsten Weise and Wang Yi*. "Computer Aided Verification, 11th International Conference, CAV'99", Trento, Italy, July 6-10, 1999, Proceedings. [[doi:10.1007/3-540-48683-6_30](https://doi.org/10.1007/3-540-48683-6_30)] [[bib](https://dblp.uni-trier.de/rec/conf/cav/BehrmannLPWY99.html?view=bibtex)] - ## Compile -The following packages need to be installed: `cmake gcc xxHash doctest boost`. +The following packages need to be installed: `cmake`, `gcc`, `g++` and `ninja-build` or `make`. -In addition, [UUtils](https://github.com/UPPAALModelChecker/UUtils) and [UDBM](https://github.com/UPPAALModelChecker/UDBM) are needed, which can be installed system-wide, or locally by running the script [`getlibs.sh`](getlibs.sh). +In addition, [UUtils](https://github.com/UPPAALModelChecker/UUtils) and [UDBM](https://github.com/UPPAALModelChecker/UDBM) will be built. -Get the dependencies, compile the source into `build` directory and run the unit tests: -```sh +Compile the source into `build` directory and run the unit tests: +```shell unset CMAKE_TOOLCHAIN_FILE # If it was set before -./getlibs.sh # If UUtils and UDBM are not installed system-wide -cmake -B build -DTESTING=ON +cmake -B build cmake --build build -(cd build ; ctest --output-on-failure) +ctest --test-dir build --output-on-failure ``` +## Reuse Dependencies +Use [getlibs.sh](getlibs.sh) script to build dependencies and install them into `local/$TARGET`: +```shell +unset CMAKE_TOOLCHAIN_FILE # If it was set before +TARGET=x86_64-linux +CMAKE_BUILD_TYPE=Release ./getlibs.sh $TARGET # install dependencies +BUILD=build-$TARGET-libs +cmake -B $BUILD -DCMAKE_PREFIX_PATH=$PWD/local/$TARGET -DFIND_FATAL=ON +cmake --build $BUILD +ctest --test-dir $BUILD --output-on-failure +``` +For possible values of `TARGET` consult with `getlibs.sh` by running it or see the names of toolchain files in [cmake/toolchain](cmake/toolchain). + ### Cross-compile For Linux 32-bit (i686): -```sh -export CMAKE_TOOLCHAIN_FILE=$PWD/toolchains/i686-linux.cmake -./getlibs.sh -cmake -B build-linux32 -DTESTING=ON -cmake --build build-linux32 -(cd build-linux32 ; ctest --output-on-failure) +```shell +TARGET=i686-linux +CMAKE_BUILD_TYPE=Release ./getlibs.sh $TARGET # install dependencies +BUILD=build-$TARGET-libs +export CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/$TARGET.cmake +cmake -B $BUILD -DCMAKE_PREFIX_PATH=$PWD/local/$TARGET -DFIND_FATAL=ON +cmake --build $BUILD +ctest --test-dir $BUILD --output-on-failure ``` ### Cross-compile For Windows 64-bit (x64_86) using MinGW/[MSYS2](https://www.msys2.org/): -```sh -export CMAKE_TOOLCHAIN_FILE=$PWD/toolchains/x86_64-w64-mingw32.cmake -./getlibs.sh -cmake -B build-win64 -DTESTING=ON -DSTATIC=ON -cmake --build build-win64 -(cd build-win64 ; ctest --output-on-failure) +```shell +TARGET=x86_64-w64-mingw32 +CMAKE_BUILD_TYPE=Release ./getlibs.sh $TARGET # install dependencies +BUILD=build-$TARGET-libs +export CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/$TARGET.cmake +cmake -B $BUILD -DCMAKE_PREFIX_PATH=$PWD/local/$TARGET -DFIND_FATAL=ON -DSTATIC=ON +cmake --build $BUILD +ctest --test-dir $BUILD --output-on-failure ``` ### Cross-compile For Windows 32-bit (i686) using MinGW/[MSYS2](https://www.msys2.org/): -```sh -export CMAKE_TOOLCHAIN_FILE=$PWD/toolchains/i686-w64-mingw32.cmake -./getlibs.sh -cmake -B build-win32 -DTESTING=ON -DSTATIC=ON -cmake --build build-win32 -(cd build-win32 ; ctest --output-on-failure) +```shell +TARGET=i686-w64-mingw32 +CMAKE_BUILD_TYPE=Release ./getlibs.sh $TARGET # install dependencies +BUILD=build-$TARGET-libs +export CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/$TARGET.cmake +cmake -B $BUILD -DCMAKE_PREFIX_PATH=$PWD/local/$TARGET -DFIND_FATAL=ON -DSTATIC=ON +cmake --build $BUILD +ctest --test-dir $BUILD --output-on-failure ``` ## Debugging +To enable debug build define `CMAKE_BUILD_TYPE` to `Debug` before build generation: +```shell +export CMAKE_BUILD_TYPE=Debug +``` Address-sanitizer can be enabled by adding `-DASAN=ON` option to `cmake` build generation line. This relies on the compiler support (currently GCC does not support sanitizers on Windows). diff --git a/cmake/UDBM.cmake b/cmake/UDBM.cmake new file mode 100644 index 0000000..bbf8dfc --- /dev/null +++ b/cmake/UDBM.cmake @@ -0,0 +1,32 @@ +find_package(UDBM 2.0.15 QUIET) + +if (UDBM_FOUND) + message(STATUS "Found UDBM: ${UDBM_DIR}") +else(UDBM_FOUND) + message(STATUS "Failed to find UDBM, going to compile from source.") + if (FIND_FATAL) + message(FATAL_ERROR "Failed to find UDBM with CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}") + endif(FIND_FATAL) + include(FetchContent) + set(UDBM_WITH_TESTS OFF CACHE BOOL "UDBM tests") + FetchContent_Declare( + UDBM + GIT_REPOSITORY https://github.com/UPPAALModelChecker/UDBM.git + GIT_TAG v2.0.15 + GIT_SHALLOW TRUE # get only the last commit version + GIT_PROGRESS TRUE # show progress of download + # FIND_PACKAGE_ARGS NAMES doctest + USES_TERMINAL_DOWNLOAD TRUE # show progress in ninja generator + USES_TERMINAL_CONFIGURE ON + USES_TERMINAL_BUILD ON + USES_TERMINAL_INSTALL ON + ) + FetchContent_GetProperties(UDBM) + if (udbm_POPULATED) + message(STATUS "Found populated UUtils: ${uutils_SOURCE_DIR}") + else (udbm_POPULATED) + FetchContent_Populate(UDBM) + add_subdirectory(${udbm_SOURCE_DIR} ${udbm_BINARY_DIR} EXCLUDE_FROM_ALL) + message(STATUS "Got UDBM: ${udbm_SOURCE_DIR}") + endif (udbm_POPULATED) +endif(UDBM_FOUND) diff --git a/cmake/UUtils.cmake b/cmake/UUtils.cmake new file mode 100644 index 0000000..58b1416 --- /dev/null +++ b/cmake/UUtils.cmake @@ -0,0 +1,34 @@ +find_package(Boost 1.88 COMPONENTS headers math REQUIRED) +find_package(UUtils 2.0.7 COMPONENTS base hash debug QUIET) + +if (UUtils_FOUND) + message(STATUS "Found UUtils: ${UUtils_DIR}") +else(UUtils_FOUND) + message(STATUS "Failed to find UUtils, going to compile from source.") + if (FIND_FATAL) + message(FATAL_ERROR "Failed to find UUtils with CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}") + endif(FIND_FATAL) + include(FetchContent) + set(UUtils_WITH_TESTS OFF CACHE BOOL "UUtils tests") + set(UUtils_WITH_BENCHMARKS OFF CACHE BOOL "UUtils benchmarks") + FetchContent_Declare( + UUtils + GIT_REPOSITORY https://github.com/UPPAALModelChecker/UUtils.git + GIT_TAG v2.0.5 + GIT_SHALLOW TRUE # get only the last commit version + GIT_PROGRESS TRUE # show progress of download + # FIND_PACKAGE_ARGS NAMES doctest + USES_TERMINAL_DOWNLOAD TRUE # show progress in ninja generator + USES_TERMINAL_CONFIGURE ON + USES_TERMINAL_BUILD ON + USES_TERMINAL_INSTALL ON + ) + FetchContent_GetProperties(UUtils) + if (uutils_POPULATED) + message(STATUS "Found populated UUtils: ${uutils_SOURCE_DIR}") + else (uutils_POPULATED) + FetchContent_Populate(UUtils) + add_subdirectory(${uutils_SOURCE_DIR} ${uutils_BINARY_DIR} EXCLUDE_FROM_ALL) + message(STATUS "Got UUtils: ${uutils_SOURCE_DIR}") + endif (uutils_POPULATED) +endif(UUtils_FOUND) diff --git a/cmake/doctest.cmake b/cmake/doctest.cmake new file mode 100644 index 0000000..acbd69a --- /dev/null +++ b/cmake/doctest.cmake @@ -0,0 +1,45 @@ +find_package(doctest 2.4.11 QUIET) + +if (doctest_FOUND) + if (TARGET doctest::doctest_with_main) + message(STATUS "Found doctest::doctest_with_main") + add_library(doctest_with_main INTERFACE) + target_link_libraries(doctest_with_main PRIVATE doctest::doctest_with_main) + else(TARGET doctest::doctest_with_main) # workaround for old doctest + message(STATUS "Workaround for doctest::doctest_with_main") + add_library(doctest_with_main INTERFACE) + target_compile_definitions(doctest_with_main INTERFACE DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) + target_link_libraries(doctest_with_main INTERFACE doctest::doctest) + endif(TARGET doctest::doctest_with_main) + message(STATUS "Found doctest: ${doctest_DIR}") +else(doctest_FOUND) + message(STATUS "Failed to find doctest, going to compile from source.") + if (FIND_FATAL) + message(FATAL_ERROR "Failed to find doctest with CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}") + endif(FIND_FATAL) + include(FetchContent) + set(DOCTEST_WITH_TESTS OFF CACHE BOOL "doctest tests and examples") + set(DOCTEST_WITH_MAIN_IN_STATIC_LIB ON CACHE BOOL "static lib (cmake target) with a default main entry point") + set(DOCTEST_NO_INSTALL ON CACHE BOOL "Skip the installation process") + set(DOCTEST_USE_STD_HEADERS OFF CACHE BOOL "Use std headers") + FetchContent_Declare( + doctest + GIT_REPOSITORY https://github.com/doctest/doctest + GIT_TAG v2.4.11 + GIT_SHALLOW TRUE # get only the last commit version + GIT_PROGRESS TRUE # show progress of download + # FIND_PACKAGE_ARGS NAMES doctest + USES_TERMINAL_DOWNLOAD TRUE # show progress in ninja generator + USES_TERMINAL_CONFIGURE ON + USES_TERMINAL_BUILD ON + USES_TERMINAL_INSTALL ON + ) + FetchContent_MakeAvailable(doctest) + if (doctest_POPULATED) + message(STATUS "Found populated doctest: ${doctest_SOURCE_DIR}") + else (doctest_POPULATED) + FetchContent_Populate(doctest) + add_subdirectory(${doctest_SOURCE_DIR} ${doctest_BINARY_DIR} EXCLUDE_FROM_ALL) + message(STATUS "Got doctest: ${doctest_SOURCE_DIR}") + endif (doctest_POPULATED) +endif(doctest_FOUND) diff --git a/cmake/sanitizer.cmake b/cmake/sanitizer.cmake new file mode 100644 index 0000000..2ebe277 --- /dev/null +++ b/cmake/sanitizer.cmake @@ -0,0 +1,99 @@ +# Various sanitizers (runtime checks) for debugging +option(SSP "Stack Smashing Protector (GCC/Clang/ApplClang on Unix)" OFF + )# Available on Windows too +option(UBSAN "Undefined Behavior Sanitizer (GCC/Clang/AppleClang on Unix)" OFF) +option(ASAN "Address Sanitizer (GCC/Clang/AppleClang on Unix, MSVC on Windows)" + OFF) +option(TSAN "Thread Sanitizer (GCC/Clang/AppleClang on Unix)" OFF) +option(RTC_C "Runtime Checks for Conversions (MSVC on Windows)" OFF) +option(RTC_S "Runtime Checks for Stack (MSVC on Windows)" OFF) +option(RTC_U "Runtime Checks for Uninitialized (MSVC on Windows)" OFF) + +if(SSP) + add_compile_options(-fstack-protector) + add_link_options(-fstack-protector) + message(STATUS "Enable Stack Smashing Protector") +endif(SSP) + +if(ASAN + OR UBSAN + OR TSAN) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + + else() + add_compile_options(-fno-omit-frame-pointer) + add_link_options(-fno-omit-frame-pointer) + endif() +endif() + +if(UBSAN) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/fsanitize=undefined) + message( + STATUS + "Please see if MSVC supports undefined behavior sanitizer: https://learn.microsoft.com/en-us/cpp/sanitizers/asan" + ) + else() + add_compile_options(-fsanitize=undefined) + add_link_options(-fsanitize=undefined) + endif() + message(STATUS "Enabled Undefined Behavior Sanitizer") +endif(UBSAN) + +if(ASAN) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/fsanitize=address) + else() + add_compile_options(-fsanitize=address) + add_link_options(-fsanitize=address) + endif() + message(STATUS "Enabled Address Sanitizer") +endif(ASAN) + +if(TSAN) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/fsanitize=thread) + message( + STATUS + "Please see if MSVC supports thread sanitizer: https://learn.microsoft.com/en-us/cpp/sanitizers/asan" + ) + else() + add_compile_options(-fsanitize=thread) + add_link_options(-fsanitize=thread) + endif() + message(STATUS "Enabled Thread Sanitizer") +endif(TSAN) + +if(RTC_C) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/RTCc) + add_compile_definitions(_ALLOW_RTCc_IN_STL) + message(STATUS "Enabled Runtime Check Conversions") + else() + message( + WARNING + "Runtime Check Conversions is not enabled for ${CMAKE_CXX_COMPILER_ID}") + endif() +endif(RTC_C) + +if(RTC_S) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/RTCs) + message(STATUS "Enabled Runtime Check Stack") + else() + message( + WARNING "Runtime Check Stack is not enabled for ${CMAKE_CXX_COMPILER_ID}") + endif() +endif(RTC_S) + +if(RTC_U) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/RTCu) + message(STATUS "Enabled Runtime Check Uninitialized") + else() + message( + WARNING + "Runtime Check Uninitialized is not enabled for ${CMAKE_CXX_COMPILER_ID}" + ) + endif() +endif(RTC_U) diff --git a/cmake/toolchain/i686-linux-gcc14.cmake b/cmake/toolchain/i686-linux-gcc14.cmake new file mode 100644 index 0000000..2572f6e --- /dev/null +++ b/cmake/toolchain/i686-linux-gcc14.cmake @@ -0,0 +1,20 @@ +# the name of the target operating system +set(CMAKE_SYSTEM_NAME Linux) + +# which compilers to use for C and C++ +set(CMAKE_C_COMPILER gcc-14) +set(CMAKE_C_FLAGS -m32) +set(CMAKE_CXX_COMPILER g++-14) +set(CMAKE_CXX_FLAGS -m32) +set(CMAKE_ASM_FLAGS -m32) + +# where is the target environment located +set(CMAKE_FIND_ROOT_PATH "${CMAKE_PREFIX_PATH}") + +# adjust the default behavior of the FIND_XXX() commands: +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + +# 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/i686-linux.cmake b/cmake/toolchain/i686-linux.cmake similarity index 86% rename from toolchains/i686-linux.cmake rename to cmake/toolchain/i686-linux.cmake index 01c0b6b..00af252 100644 --- a/toolchains/i686-linux.cmake +++ b/cmake/toolchain/i686-linux.cmake @@ -2,10 +2,11 @@ set(CMAKE_SYSTEM_NAME Linux) # which compilers to use for C and C++ -set(CMAKE_C_COMPILER gcc) +set(CMAKE_C_COMPILER cc) set(CMAKE_C_FLAGS -m32) -set(CMAKE_CXX_COMPILER g++) +set(CMAKE_CXX_COMPILER c++) set(CMAKE_CXX_FLAGS -m32) +set(CMAKE_ASM_FLAGS -m32) # where is the target environment located set(CMAKE_FIND_ROOT_PATH "${CMAKE_PREFIX_PATH}") diff --git a/toolchains/i686-w64-mingw32.cmake b/cmake/toolchain/i686-w64-mingw32.cmake similarity index 100% rename from toolchains/i686-w64-mingw32.cmake rename to cmake/toolchain/i686-w64-mingw32.cmake diff --git a/cmake/toolchain/x86_64-darwin.cmake b/cmake/toolchain/x86_64-darwin.cmake new file mode 100644 index 0000000..470aac9 --- /dev/null +++ b/cmake/toolchain/x86_64-darwin.cmake @@ -0,0 +1,20 @@ +# the name of the target operating system +set(CMAKE_SYSTEM_NAME Darwin) + +# which compilers to use for C and C++ +set(CMAKE_C_COMPILER cc) +set(CMAKE_C_FLAGS -m64) +set(CMAKE_CXX_COMPILER c++) +set(CMAKE_CXX_FLAGS -m64) +set(CMAKE_ASM_FLAGS -m64) + +# where is the target environment located +set(CMAKE_FIND_ROOT_PATH "${CMAKE_PREFIX_PATH}") + +# adjust the default behavior of the FIND_XXX() commands: +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + +# 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/cmake/toolchain/x86_64-linux-gcc14.cmake b/cmake/toolchain/x86_64-linux-gcc14.cmake new file mode 100644 index 0000000..2be5fed --- /dev/null +++ b/cmake/toolchain/x86_64-linux-gcc14.cmake @@ -0,0 +1,20 @@ +# the name of the target operating system +set(CMAKE_SYSTEM_NAME Linux) + +# which compilers to use for C and C++ +set(CMAKE_C_COMPILER gcc-14) +set(CMAKE_C_FLAGS -m64) +set(CMAKE_CXX_COMPILER g++-14) +set(CMAKE_CXX_FLAGS -m64) +set(CMAKE_ASM_FLAGS -m64) + +# where is the target environment located +set(CMAKE_FIND_ROOT_PATH "${CMAKE_PREFIX_PATH}") + +# adjust the default behavior of the FIND_XXX() commands: +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + +# 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/cmake/toolchain/x86_64-linux.cmake b/cmake/toolchain/x86_64-linux.cmake new file mode 100644 index 0000000..6864b56 --- /dev/null +++ b/cmake/toolchain/x86_64-linux.cmake @@ -0,0 +1,20 @@ +# the name of the target operating system +set(CMAKE_SYSTEM_NAME Linux) + +# which compilers to use for C and C++ +set(CMAKE_C_COMPILER cc) +set(CMAKE_C_FLAGS -m64) +set(CMAKE_CXX_COMPILER c++) +set(CMAKE_CXX_FLAGS -m64) +set(CMAKE_ASM_FLAGS -m64) + +# where is the target environment located +set(CMAKE_FIND_ROOT_PATH "${CMAKE_PREFIX_PATH}") + +# adjust the default behavior of the FIND_XXX() commands: +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + +# 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/x86_64-w64-mingw32.cmake b/cmake/toolchain/x86_64-w64-mingw32.cmake similarity index 100% rename from toolchains/x86_64-w64-mingw32.cmake rename to cmake/toolchain/x86_64-w64-mingw32.cmake diff --git a/cmake/xxhash.cmake b/cmake/xxhash.cmake new file mode 100644 index 0000000..14ca08d --- /dev/null +++ b/cmake/xxhash.cmake @@ -0,0 +1,68 @@ +set(XXHASH_VERSION_MINIMUM 0.8.3) +find_file(XXHASH_PATH xxhash.h) +if (XXHASH_PATH) + cmake_path(GET XXHASH_PATH PARENT_PATH xxHash_DIR) + file(READ "${XXHASH_PATH}" XXHASH_H) + string(REGEX MATCH "#define XXH_VERSION_MAJOR([ \t])*([0-9])*" _ ${XXHASH_H}) + set(XXHASH_VERSION_MAJOR ${CMAKE_MATCH_2}) + string(REGEX MATCH "#define XXH_VERSION_MINOR([ \t])*([0-9])*" _ ${XXHASH_H}) + set(XXHASH_VERSION_MINOR ${CMAKE_MATCH_2}) + string(REGEX MATCH "#define XXH_VERSION_RELEASE([ \t])*([0-9])*" _ ${XXHASH_H}) + set(XXHASH_VERSION_PATCH ${CMAKE_MATCH_2}) + set(XXHASH_VERSION "${XXHASH_VERSION_MAJOR}.${XXHASH_VERSION_MINOR}.${XXHASH_VERSION_PATCH}") + if (XXHASH_VERSION VERSION_GREATER_EQUAL ${XXHASH_VERSION_MINIMUM}) + set(xxHash_FOUND TRUE) + cmake_path(GET XXHASH_PATH PARENT_PATH XXHASH_INCLUDE_DIR) + add_library(xxHash INTERFACE) + target_compile_definitions(xxHash INTERFACE XXH_INLINE_ALL) + target_include_directories(xxHash + INTERFACE + $ + $ + ) + else() + message(STATUS "Found xxHash-${XXHASH_VERSION} is too old, need at lease ${XXHASH_VERSION_MINIMUM}") + endif() +endif(XXHASH_PATH) + +if (xxHash_FOUND) + message(STATUS "Found xxHash-${XXHASH_VERSION}: ${XXHASH_PATH}") +else(xxHash_FOUND) + message(STATUS "Failed to find xxHash, going to compile from source.") + if (FIND_FATAL) + message(FATAL_ERROR "Failed to find xxHash with CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}") + endif(FIND_FATAL) + include(ExternalProject) + set(XXHASH_BUILD_ENABLE_INLINE_API ON CACHE BOOL "adds xxhash.c for the -DXXH_INLINE_ALL api. Default ON") + set(XXHASH_BUILD_XXHSUM OFF CACHE BOOL "build the command line binary. Default ON") + set(BUILD_SHARED_LIBS OFF CACHE BOOL "build dynamic library. Default ON") + # set(DISPATCH OFF CACHE BOOL "enable dispatch mode. Default OFF") + FetchContent_Declare( + xxHash + GIT_REPOSITORY https://github.com/Cyan4973/xxHash + GIT_TAG v0.8.3 + GIT_SHALLOW TRUE # get only the last commit version + GIT_PROGRESS TRUE # show progress of download + SOURCE_SUBDIR cmake_unofficial # CMakeLists.txt is not in the main folder + FIND_PACKAGE_ARGS NAMES xxHash COMPONENTS xxhash # for future when xxhash supports cmake + USES_TERMINAL_DOWNLOAD TRUE # show progress in ninja generator + USES_TERMINAL_CONFIGURE ON + USES_TERMINAL_BUILD ON + USES_TERMINAL_INSTALL ON + ) + FetchContent_MakeAvailable(xxHash) + if (xxhash_POPULATED) + message(STATUS "Found populated xxHash: ${xxhash_SOURCE_DIR}") + else (xxhash_POPULATED) + FetchContent_Populate(xxHash) + add_subdirectory(${xxhash_SOURCE_DIR}/cmake_unofficial ${xxhash_BINARY_DIR} EXCLUDE_FROM_ALL) + add_library(xxHash INTERFACE) + target_compile_definitions(xxHash INTERFACE XXH_INLINE_ALL) + target_include_directories(xxHash + INTERFACE + $ + $ + ) + message(STATUS "Got xxHash: ${xxhash_SOURCE_DIR}") + endif (xxhash_POPULATED) +endif(xxHash_FOUND) diff --git a/compile.sh b/compile.sh new file mode 100755 index 0000000..5866d0c --- /dev/null +++ b/compile.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +set -eo pipefail + +PROJECT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +if [ $# -eq 0 ]; then + targets="x86_64-linux-libs-release x86_64-w64-mingw32-libs-release" +else + targets="$@" +fi + +function show_cmake_vars() { + for var in CMAKE_TOOLCHAIN_FILE CMAKE_BUILD_TYPE CMAKE_PREFIX_PATH CMAKE_INSTALL_PREFIX \ + CMAKE_GENERATOR CMAKE_BUILD_PARALLEL_LEVEL; do + echo " $var=${!var:- (unset)}" + done +} + +for target in $targets ; do + unset BUILD_EXTRA + unset CMAKE_BUILD_TYPE + case $target in + x86_64-linux-gcc14*) + PLATFORM=x86_64-linux-gcc14 + ;; + linux64*|x86_64-linux*) + PLATFORM=x86_64-linux + ;; + i686-linux-gcc14*) + PLATFORM=i686-linux-gcc14 + ;; + linux32*|i686-linux*) + PLATFORM=i686-linux + ;; + win64*|x86_64-w64-mingw32*) + PLATFORM=x86_64-w64-mingw32 + export WINEPATH=$("$PROJECT_DIR"/winepath-for $PLATFORM) + ;; + win32*|i686-w64-mingw32*) + PLATFORM=i686-w64-mingw32 + export WINEPATH=$("$PROJECT_DIR"/winepath-for $PLATFORM) + ;; + darwin-brew-gcc14*) + PLATFORM=darwin-brew-gcc14 + ;; + darwin*) + PLATFORM=darwin + ;; + x86_64-darwin-brew-gcc14*) + PLATFORM=x86_64-darwin-brew-gcc14 + ;; + macos*|x86_64-darwin*) + PLATFORM=x86_64-darwin + ;; + *) + echo "Unrecognized target platform: $target" + exit 1 + esac + export CMAKE_TOOLCHAIN_FILE="$PROJECT_DIR/cmake/toolchain/$PLATFORM.cmake" + BUILD_DIR="build-$PLATFORM" + + case $target in + *-libs*) + CMAKE_BUILD_TYPE=Release ./getlibs.sh $PLATFORM + BUILD_EXTRA="$BUILD_EXTRA -DFIND_FATAL=ON" + export CMAKE_PREFIX_PATH="$PROJECT_DIR/local/$PLATFORM" + ;; + esac + + case $target in + *-ubsan-*) + BUILD_EXTRA="$BUILD_EXTRA -DUBSAN=ON" + BUILD_DIR="${BUILD_DIR}-ubsan" + ;; + esac + case $target in + *-lsan-*) + BUILD_EXTRA="$BUILD_EXTRA -DLSAN=ON" + BUILD_DIR="${BUILD_DIR}-lsan" + ;; + esac + case $target in + *-asan-*) + BUILD_EXTRA="$BUILD_EXTRA -DASAN=ON" + BUILD_DIR="${BUILD_DIR}-asan" + ;; + esac + case $target in + *-debug) + export CMAKE_BUILD_TYPE=Debug + BUILD_DIR="${BUILD_DIR}-debug" + ;; + *-release) + export CMAKE_BUILD_TYPE=Release + BUILD_DIR="${BUILD_DIR}-release" + ;; + *) + export CMAKE_BUILD_TYPE=Release + BUILD_DIR="${BUILD_DIR}-release" + echo "Unrecognized build type: $target, assuming $CMAKE_BUILD_TYPE" + esac + echo "Building $target${BUILD_EXTRA:+ with$BUILD_EXTRA} into $BUILD_DIR" + show_cmake_vars + cmake -S "$PROJECT_DIR" -B "$BUILD_DIR" $BUILD_EXTRA + cmake --build "$BUILD_DIR" --config $CMAKE_BUILD_TYPE + ctest --test-dir "$BUILD_DIR" -C $CMAKE_BUILD_TYPE --output-on-failure +done diff --git a/getlibs.sh b/getlibs.sh index 167ab58..2cdafb4 100755 --- a/getlibs.sh +++ b/getlibs.sh @@ -1,79 +1,181 @@ #!/usr/bin/env bash +#set -euxo pipefail set -euo pipefail -# Cursed line that should also work on macos -# https://stackoverflow.com/questions/59895/how-can-i-get-the-source-directory-of-a-bash-script-from-within-the-script-itsel -SOURCE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -if [ -z "${CMAKE_TOOLCHAIN_FILE+x}" ]; then - CMAKE_PREFIX_PATH="${SOURCE_DIR}/libs" - CMAKE_ARGS="" - echo "Not using a custom toolchain, building for $(uname -m)-$(uname -s) in libs"; +if [ $# -eq 0 ] ; then + echo "Script $0 compiles and installs dependent libraries for a set of targets specified as arguments." + echo "Possible arguments:" + toolchains=$(cd cmake/toolchain/ ; ls *.cmake) + for toolchain in $toolchains ; do + echo " ${toolchain%%.cmake}" + done + echo "The script is sensitive to CMake environment variables like:" + echo " CMAKE_TOOLCHAIN_FILE CMAKE_BUILD_TYPE CMAKE_PREFIX_PATH" + exit 1 else - TARGET=$(basename "${CMAKE_TOOLCHAIN_FILE}") - TARGET=${TARGET%.*} - CMAKE_PREFIX_PATH="${SOURCE_DIR}/libs-${TARGET}" - CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" - echo "Using toolchain ${CMAKE_TOOLCHAIN_FILE} for ${TARGET} in libs-${TARGET}" + targets="$@" fi -CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -LIBS_SOURCES="${CMAKE_PREFIX_PATH}/sources" -mkdir -p "${LIBS_SOURCES}" -cd "${LIBS_SOURCES}" - -# DOCTEST -PREFIX="$CMAKE_PREFIX_PATH/doctest" -if [ ! -d "$PREFIX" ]; then - wget -nv -N https://github.com/doctest/doctest/archive/refs/tags/v2.4.9.tar.gz - tar -xf v2.4.9.tar.gz - SRC_DIR="${LIBS_SOURCES}/doctest-2.4.9" - BLD_DIR="$SRC_DIR/build" - cmake $CMAKE_ARGS -DCMAKE_INSTALL_PREFIX="$PREFIX" -DBUILD_SHARED_LIBS=OFF "$SRC_DIR" -B "$BLD_DIR" - cmake --build "$BLD_DIR" --config Release - cmake --install "$BLD_DIR" --config Release -else - echo "$PREFIX already exists, skipping" +if [ -z "${CMAKE_BUILD_TYPE+x}" ]; then + export CMAKE_BUILD_TYPE=Release +elif [ "$CMAKE_BUILD_TYPE" != Release ]; then + echo "WARNING: building libs with CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" fi -# XXHASH -PREFIX="$CMAKE_PREFIX_PATH/xxHash" -if [ ! -d "$PREFIX" ]; then - wget -nv -N https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.0.tar.gz - tar -xf v0.8.0.tar.gz - SRC_DIR="${LIBS_SOURCES}/xxHash-0.8.0" - BLD_DIR="$SRC_DIR/build" - cmake $CMAKE_ARGS -DCMAKE_INSTALL_PREFIX="$PREFIX" -DBUILD_SHARED_LIBS=OFF "$SRC_DIR/cmake_unofficial" -B "$BLD_DIR" - cmake --build "$BLD_DIR" --config Release - cmake --install "$BLD_DIR" --config Release -else - echo "$PREFIX already exists, skipping" +if [ -n "${CMAKE_TOOLCHAIN_FILE+x}" ]; then + TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" fi -# UUtils -PREFIX="$CMAKE_PREFIX_PATH/UUtils" -if [ ! -d "$PREFIX" ]; then - wget -nv -N https://github.com/UPPAALModelChecker/UUtils/archive/refs/tags/v1.1.1.tar.gz - tar -xf v1.1.1.tar.gz - SRC_DIR="${LIBS_SOURCES}/UUtils-1.1.1" - BLD_DIR="$SRC_DIR/build" - cmake $CMAKE_ARGS -DCMAKE_INSTALL_PREFIX="$PREFIX" "$SRC_DIR" -B "$BLD_DIR" - cmake --build "$BLD_DIR" --config Release - cmake --install "$BLD_DIR" --config Release -else - echo "$PREFIX already exists, skipping" -fi +function show_cmake_vars() { + for var in CMAKE_TOOLCHAIN_FILE CMAKE_BUILD_TYPE CMAKE_PREFIX_PATH CMAKE_INSTALL_PREFIX \ + CMAKE_GENERATOR CMAKE_BUILD_PARALLEL_LEVEL; do + echo " $var=${!var:- (unset)}" + done +} -# UDBM -PREFIX="$CMAKE_PREFIX_PATH/UDBM" -if [ ! -d "$PREFIX" ]; then - wget -nv -N https://github.com/UPPAALModelChecker/UDBM/archive/refs/tags/v2.0.11.tar.gz - tar -xf v2.0.11.tar.gz - SRC_DIR="${LIBS_SOURCES}/UDBM-2.0.11" - BLD_DIR="$SRC_DIR/build" - cmake $CMAKE_ARGS -DCMAKE_INSTALL_PREFIX="$PREFIX" "$SRC_DIR" -B "$BLD_DIR" - cmake --build "$BLD_DIR" --config Release - cmake --install "$BLD_DIR" --config Release -else - echo "$PREFIX already exists, skipping" -fi +for target in $targets ; do + echo "GETLIBS for $target" + BUILD_TARGET=$target + SOURCES="$PROJECT_DIR/local/sources" + mkdir -p "$SOURCES" + PREFIX="$PROJECT_DIR/local/${BUILD_TARGET}" + # export CMAKE_PREFIX_PATH="$PREFIX" + export CMAKE_INSTALL_PREFIX="$PREFIX" + if [ -z "${TOOLCHAIN_FILE+x}" ] && [ -r "$PROJECT_DIR/cmake/toolchain/${target}.cmake" ] ; then + export CMAKE_TOOLCHAIN_FILE="$PROJECT_DIR/cmake/toolchain/${target}.cmake" + fi + + ## DOCTEST + NAME=doctest + VERSION=2.4.11 + LIBRARY="${NAME}-${VERSION}" + ARCHIVE="$LIBRARY.tgz" + SHA256=632ed2c05a7f53fa961381497bf8069093f0d6628c5f26286161fbd32a560186 + SOURCE="${SOURCES}/$LIBRARY" + BUILD="${PREFIX}/build-$LIBRARY" + if [ -r "${CMAKE_INSTALL_PREFIX}/include/doctest/doctest.h" ]; then + echo "$LIBRARY is already installed in $CMAKE_INSTALL_PREFIX" + else + pushd "${SOURCES}" + [ -r "${ARCHIVE}" ] || curl -sL "https://github.com/doctest/doctest/archive/refs/tags/v$VERSION.tar.gz" -o "${ARCHIVE}" + if [ -n "$(command -v sha256sum)" ]; then echo "$SHA256 $ARCHIVE" | sha256sum --check ; fi + [ -d "${SOURCE}" ] || tar xf "${ARCHIVE}" + popd + echo "Building $LIBRARY in $BUILD from $SOURCE" + show_cmake_vars + cmake -S "$SOURCE" -B "$BUILD" -DDOCTEST_WITH_TESTS=OFF -DDOCTEST_WITH_MAIN_IN_STATIC_LIB=ON + cmake --build "$BUILD" --config $CMAKE_BUILD_TYPE + cmake --install "$BUILD" --config $CMAKE_BUILD_TYPE --prefix "${CMAKE_INSTALL_PREFIX}" + rm -Rf "$BUILD" + rm -Rf "$SOURCE" + fi + + ## XXHASH (in src/kernel.c) + NAME=xxHash + VERSION=0.8.3 + LIBRARY="${NAME}-${VERSION}" + ARCHIVE="$LIBRARY.tgz" + SHA256=aae608dfe8213dfd05d909a57718ef82f30722c392344583d3f39050c7f29a80 + SOURCE="${SOURCES}/$LIBRARY" + BUILD="${PREFIX}/build-$LIBRARY" + if [ -r "${CMAKE_INSTALL_PREFIX}/include/xxhash.h" ]; then + echo "$LIBRARY is already installed in $CMAKE_INSTALL_PREFIX" + else + pushd "$SOURCES" + [ -r "${ARCHIVE}" ] || curl -sL "https://github.com/Cyan4973/xxHash/archive/refs/tags/v$VERSION.tar.gz" -o "${ARCHIVE}" + if [ -n "$(command -v sha256sum)" ]; then echo "$SHA256 $ARCHIVE" | sha256sum --check ; fi + [ -d "$SOURCE" ] || tar xf "${ARCHIVE}" + popd + echo "Building $LIBRARY in $BUILD from $SOURCE" + show_cmake_vars + cmake -S "$SOURCE/cmake_unofficial" -B "$BUILD" -DBUILD_SHARED_LIBS=OFF + cmake --build "$BUILD" --config $CMAKE_BUILD_TYPE + cmake --install "$BUILD" --config $CMAKE_BUILD_TYPE --prefix "${CMAKE_INSTALL_PREFIX}" + rm -Rf "$BUILD" + rm -Rf "$SOURCE" + fi + + ## BOOST for UUtils + NAME=boost + VERSION=1.88.0 + LIBRARY="${NAME}-${VERSION}" + ARCHIVE="${LIBRARY}-cmake.tar.xz" + SHA256=f48b48390380cfb94a629872346e3a81370dc498896f16019ade727ab72eb1ec + SOURCE="${SOURCES}/${LIBRARY}" + BUILD="${PREFIX}/build-${LIBRARY}" + if [ -r "${CMAKE_INSTALL_PREFIX}/include/boost/math/distributions/arcsine.hpp" ] ; then + echo "$LIBRARY is already installed in $CMAKE_INSTALL_PREFIX" + else + pushd "$SOURCES" + [ -r "${ARCHIVE}" ] || curl -sL "https://github.com/boostorg/boost/releases/download/${LIBRARY}/${ARCHIVE}" -o "${ARCHIVE}" + if [ -n "$(command -v shasum)" ]; then + echo "$SHA256 $ARCHIVE" | shasum -a256 --check - + fi + [ -d "${SOURCE}" ] || tar xf "${ARCHIVE}" + popd + echo "Building $LIBRARY in $BUILD from $SOURCE" + show_cmake_vars + cmake -S "$SOURCE" -B "$BUILD" -DBUILD_SHARED_LIBS=OFF \ + -DBOOST_INCLUDE_LIBRARIES="headers;math" -DBOOST_ENABLE_MPI=OFF -DBOOST_ENABLE_PYTHON=OFF \ + -DBOOST_RUNTIME_LINK=static -DBUILD_TESTING=OFF -DBOOST_INSTALL_LAYOUT=system + cmake --build "$BUILD" --config $CMAKE_BUILD_TYPE + cmake --install "$BUILD" --config $CMAKE_BUILD_TYPE --prefix "${CMAKE_INSTALL_PREFIX}" + rm -Rf "$BUILD" + rm -Rf "$SOURCE" + fi + + # UUtils various low level Uppaal utilities + NAME=UUtils + VERSION=2.0.7 + LIBRARY="${NAME}-${VERSION}" + ARCHIVE="${LIBRARY}.tar.gz" + SHA256=52a823768398707eee42392182c320141662e74e6bd8eaac1a0eca22d8a27bcd + SOURCE="${SOURCES}/${LIBRARY}" + BUILD="${PREFIX}/build-${LIBRARY}" + if [ -r "$PREFIX/include/base/Enumerator.h" ]; then + echo "$LIBRARY is already installed in $PREFIX" + else + pushd "$SOURCES" + #git clone -b dev-branch --single-branch --depth 1 https://github.com/UPPAALModelChecker/UUtils.git "$LIBRARY" + [ -r "$ARCHIVE" ] || curl -sL "https://github.com/UPPAALModelChecker/UUtils/archive/refs/tags/v${VERSION}.tar.gz" -o "$ARCHIVE" + if [ -n "$(command -v sha256sum)" ]; then echo "$SHA256 $ARCHIVE" | sha256sum --check ; fi + [ -d "$SOURCE" ] || tar -xf "$ARCHIVE" + popd + echo "Building $LIBRARY in $BUILD" + show_cmake_vars + cmake -S "$SOURCE" -B "$BUILD" -DUUtils_WITH_TESTS=OFF -DUUtils_WITH_BENCHMARKS=OFF + cmake --build "$BUILD" --config $CMAKE_BUILD_TYPE + cmake --install "$BUILD" --config $CMAKE_BUILD_TYPE --prefix="$CMAKE_INSTALL_PREFIX" + rm -Rf "$BUILD" + rm -Rf "$SOURCE" + fi + + # UDBM Uppaal Difference Bound Matrix library + NAME=UDBM + VERSION=2.0.15 + LIBRARY="${NAME}-${VERSION}" + ARCHIVE="${LIBRARY}.tar.gz" + SHA256=56a630731f05ef8c2c7122ca2ca225f7608e1ff1efb4b980f0ee6bdcc388efa5 + SOURCE="${SOURCES}/${LIBRARY}" + BUILD="${PREFIX}/build-${LIBRARY}" + if [ -r "$PREFIX/include/dbm/config.h" ]; then + echo "$LIBRARY is already installed in $PREFIX" + else + pushd "$SOURCES" + #git clone -b dev-branch --single-branch --depth 1 https://github.com/UPPAALModelChecker/UDBM.git "$LIBRARY" + [ -r "$ARCHIVE" ] || curl -sL "https://github.com/UPPAALModelChecker/UDBM/archive/refs/tags/v${VERSION}.tar.gz" -o "$ARCHIVE" + if [ -n "$(command -v sha256sum)" ]; then echo "$SHA256 $ARCHIVE" | sha256sum --check ; fi + [ -d "$SOURCE" ] || tar -xf "$ARCHIVE" + popd + echo "Building $LIBRARY in $BUILD" + show_cmake_vars + cmake -S "$SOURCE" -B "$BUILD" -DUDBM_WITH_TESTS=OFF -DUDBM_CLANG_TIDY=OFF + cmake --build "$BUILD" --config $CMAKE_BUILD_TYPE + cmake --install "$BUILD" --config $CMAKE_BUILD_TYPE --prefix="$CMAKE_INSTALL_PREFIX" + rm -Rf "$BUILD" + rm -Rf "$SOURCE" + fi + echo "GETLIBS $target success!" +done diff --git a/include/cdd/cdd.h b/include/cdd/cdd.h index 48f2dc8..4e133c6 100644 --- a/include/cdd/cdd.h +++ b/include/cdd/cdd.h @@ -226,12 +226,12 @@ typedef struct int32_t diff; /**< Encoding of clock1 - clock2 */ } LevelInfo; -#define cdd_difference_count(n) (((n) * ((n)-1)) >> 1) +#define cdd_difference_count(n) (((n) * ((n) - 1)) >> 1) #define cdd_difference(c, d) (cdd_difference_count(c) + (d)) -//#define CDD_DIFF(c,d) ((c) << 10 | (d)) -//#define CDD_CLOCK1(t) ((t) >> 10) -//#define CDD_CLOCK2(t) ((t) & 0x3FF) -//#define CDD_ISVALIDDIFF(t) (CDD_CLOCK1(t) < CDD_CLOCK2(t)) +// #define CDD_DIFF(c,d) ((c) << 10 | (d)) +// #define CDD_CLOCK1(t) ((t) >> 10) +// #define CDD_CLOCK2(t) ((t) & 0x3FF) +// #define CDD_ISVALIDDIFF(t) (CDD_CLOCK1(t) < CDD_CLOCK2(t)) /** * @name Initialisation and Information @@ -1167,7 +1167,7 @@ inline int32_t cdd_eval_false(const cdd& cdd) { return cdd_eval_false(cdd.root); #define cdd_interval cdd_intervalpp #define cdd_bddvar cdd_bddvarpp #define cdd_bddnvar cdd_bddnvarpp -//#define cdd_nodecount cdd_nodecountpp +// #define cdd_nodecount cdd_nodecountpp /** @} */ diff --git a/include/cdd/kernel.h b/include/cdd/kernel.h index 17a2f30..d389226 100644 --- a/include/cdd/kernel.h +++ b/include/cdd/kernel.h @@ -30,12 +30,12 @@ extern "C" { #define bnd_upper(limit, strict) (((limit) << 1) | ((strict) ? 0 : 1)) #define bnd_lower(limit, strict) (((limit) << 1) | ((strict) ? 1 : 0)) #define bnd_get_limit(b) ((b) >> 1) -#define bnd_is_upper_strict(b) (!((b)&0x1)) -#define bnd_is_lower_strict(b) ((b)&0x1) -#define bnd_add(a, b) (((a) == INF || (b) == INF) ? INF : (((((a) & ~(0x1)) + ((b) & ~(0x1)))) | ((a) & (b)&0x1))) -#define bnd_l2u(b) ((b) == -INF ? INF : ((-((b) & ~(0x1))) | ((b)&0x1)) ^ 0x1) -#define bnd_u2l(b) ((b) == INF ? -INF : ((-((b) & ~(0x1))) | ((b)&0x1)) ^ 0x1) -#define bnd_flip_strict(b) ((b) == ((-((b) & ~(0x1))) | ((b)&0x1)) ^ 0x1) +#define bnd_is_upper_strict(b) (!((b) & 0x1)) +#define bnd_is_lower_strict(b) ((b) & 0x1) +#define bnd_add(a, b) (((a) == INF || (b) == INF) ? INF : (((((a) & ~(0x1)) + ((b) & ~(0x1)))) | ((a) & (b) & 0x1))) +#define bnd_l2u(b) ((b) == -INF ? INF : ((-((b) & ~(0x1))) | ((b) & 0x1)) ^ 0x1) +#define bnd_u2l(b) ((b) == INF ? -INF : ((-((b) & ~(0x1))) | ((b) & 0x1)) ^ 0x1) +#define bnd_flip_strict(b) ((b) == ((-((b) & ~(0x1))) | ((b) & 0x1)) ^ 0x1) /////////////////////////////////////////////////////////////////////////// /// @defgroup kernel Internal interfaces diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ce4848..711957a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,14 @@ file(GLOB cdd_source "*.c" "*.cpp" "*.h") -add_library(UCDD STATIC) +add_library(UCDD STATIC ${cdd_source}) +target_link_libraries(UCDD PUBLIC UDBM xxHash) +add_library(UCDD::UCDD ALIAS UCDD) -target_sources(UCDD PRIVATE ${cdd_source}) -target_link_libraries(UCDD UDBM) +target_include_directories(UCDD + PUBLIC + $ # cdd/config.h + $ + $ +) + +install(TARGETS UCDD xxHash EXPORT UCDDConfig FILE_SET xxhash_headers) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/cdd DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/cddop.c b/src/cddop.c index 95d1a1f..01abaf4 100644 --- a/src/cddop.c +++ b/src/cddop.c @@ -36,7 +36,7 @@ #define P2 4256249 #define COMPLHASH(r, op) (cdd_pair((uintptr_t)(r), (op))) -//#define APPLYHASH(l,r,op) (cdd_triple((unsigned int)(l), (unsigned int)(r),(op))) +// #define APPLYHASH(l,r,op) (cdd_triple((unsigned int)(l), (unsigned int)(r),(op))) #define APPLYHASH(l, r, op) ((((uintptr_t)(op) + (uintptr_t)(l)) * P1 + (uintptr_t)(r)) * P2) #define EXISTHASH(l) ((uintptr_t)(l)) #define REPLACEHASH(r) ((uintptr_t)r) diff --git a/src/kernel.c b/src/kernel.c index 10077df..07b808a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -136,7 +136,7 @@ static void cdd_rehash(NodeManager*, SubTable*); /** * Hash function used to pair two DD nodes. */ -#define bddHash(f, g) ((uint32_t)(((uint32_t)(f)*DD_P1 + (uint32_t)(g)) * DD_P2)) +#define bddHash(f, g) ((uint32_t)(((uint32_t)(f) * DD_P1 + (uint32_t)(g)) * DD_P2)) /** * Hash function over an array of \a len Elem elements. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 66794b1..f66d4fd 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,15 +1,6 @@ -# cdd tests... - set(libs UCDD UDBM UUtils::udebug UUtils::hash UUtils::base) -find_package(doctest 2.4.8 REQUIRED PATHS ${PROJECT_SOURCE_DIR}/libs/doctest) - -file(GLOB test_sources "test_*.c" "test_*.cpp") - -foreach(source ${test_sources}) - get_filename_component(test_target ${source} NAME_WE) - add_executable(${test_target} ${source}) - target_link_libraries(${test_target} PRIVATE ${libs} doctest::doctest) - add_test(NAME ${test_target} COMMAND ${test_target}) - set_tests_properties(${test_target} PROPERTIES TIMEOUT 180) # "10": 102s on Linux32, 97s on Win32, 27s on Win64 -endforeach() +add_executable(test_cdd test_cdd.cpp) +target_link_libraries(test_cdd PRIVATE ${libs} doctest_with_main) +add_test(NAME test_cdd COMMAND test_cdd) +set_tests_properties(test_cdd PROPERTIES TIMEOUT 180) # "10": 102s on Linux32, 97s on Win32, 27s on Win64 diff --git a/test/test_cdd.cpp b/test/test_cdd.cpp index dac696d..547954f 100644 --- a/test/test_cdd.cpp +++ b/test/test_cdd.cpp @@ -12,24 +12,24 @@ * Test for CDD module. */ -#include "dbm/dbm.h" -#include "dbm/gen.h" #include "cdd/cdd.h" #include "cdd/debug.h" #include "cdd/kernel.h" -#include "base/Timer.h" -#include "base/random.h" -#include "debug/macros.h" -#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include +#include +#include + +#include +#include +#include + #include #include #include #include -#include - using std::endl; using std::cerr; using std::cout; diff --git a/winepath-for b/winepath-for new file mode 100755 index 0000000..5a0fac5 --- /dev/null +++ b/winepath-for @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -e + +if [ $# -eq 0 ]; then + echo "Script $0 prints WINEPATH to include MINGW and GCC runtime environments," + echo "so that libwinpthread-1.dll, libgcc_s_seh-1.dll etc are available everywhere." + echo "Takes the toolchain as an argument. For example:" + echo " x86_64-w64-mingw32 - for 64bit Windows binaries" + echo " i686-w64-mingw32 - for 32bit Windows binaries" + exit 1 +else + toolchain="$1" +fi + +CXX="${toolchain}-g++" + +if [ -z "$(command -v $CXX)" ]; then + echo "Failed to find a cross-compiler $CXX" + case $toolchain in + x86_64-w64-mingw32) + echo "Please install mingw-w64-x86-64-dev" + ;; + i686-w64-mingw32) + echo "Please install mingw-w64-i686-dev" + ;; + esac + exit 1 +fi + +if [ -z "$(command -v winepath)" ]; then + echo "Failed to find a winepath" + echo "Please install wine with winepath" + exit 1 +fi + +GCC_S_FILE=$($CXX --print-file-name libgcc_s.a) +GCC_S_FILE=$(realpath "$GCC_S_FILE") +GCC_RUNTIME_PATH=$(dirname "$GCC_S_FILE") +GCC_RUNTIME_WINEPATH=$(winepath --windows "$GCC_RUNTIME_PATH") + +WINPTHREAD_FILE=$($CXX --print-file-name libwinpthread-1.dll) +WINPTHREAD_FILE=$(realpath "$WINPTHREAD_FILE") +MINGW_RUNTIME_PATH=$(dirname "$WINPTHREAD_FILE") +MINGW_RUNTIME_WINEPATH=$(winepath --windows "$MINGW_RUNTIME_PATH") + +echo "${GCC_RUNTIME_WINEPATH};${MINGW_RUNTIME_WINEPATH}"