diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..219f9a2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,187 @@ +name: Build + +on: + push: + pull_request: + workflow_dispatch: + inputs: + publish_artifacts: + description: 'Publish artifacts' + required: true + default: false + +env: + SCCACHE_DIR: ${{ github.workspace }}/.cache/sccache + +jobs: + mac-os: + strategy: + fail-fast: false + matrix: + xcode: ['13', '14'] + build_type: [Debug, Release] + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache dependencies + uses: actions/cache@v3 + env: + cache-name: cache-deps + with: + path: .cache/deps + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/ThirdPartyDeps.cmake') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Cache build + uses: actions/cache@v3 + env: + cache-name: cache-build + with: + path: .cache/sccache + key: ${{ runner.os }}-build-${{ env.cache-name }} + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: ${{ matrix.xcode }} + - name: Install sccache + run: brew install sccache + - name: CMake configure + run: cmake -B build + + - working-directory: build/ + run: cmake --build . --config ${{ matrix.build_type }} + + - working-directory: build/ + run: ctest --config ${{ matrix.build_type }} --output-on-failure + + linux: + strategy: + fail-fast: false + matrix: + compiler: + - g++-9 + - g++-10 + - clang++-10 + - clang++-11 + build_type: [ Debug, Release ] + runs-on: ubuntu-20.04 + env: + CXX: ${{ matrix.compiler }} + steps: + - uses: actions/checkout@v3 + - name: Cache dependencies + uses: actions/cache@v3 + env: + cache-name: cache-deps + with: + path: .cache/deps + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/ThirdPartyDeps.cmake') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Cache build + uses: actions/cache@v3 + env: + cache-name: cache-build + with: + path: .cache/sccache + key: ${{ runner.os }}-build-${{ env.cache-name }} + - name: Install sccache + run: | + curl -SL https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xvz --strip-components=1 --wildcards "*/sccache" + chmod +x sccache + - run: cmake -E make_directory build + - working-directory: build/ + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + - working-directory: build/ + run: cmake --build . + - working-directory: build/ + run: ctest --output-on-failure + + windows: + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + runs-on: windows-2019 + env: + CXX: ${{ matrix.compiler }} + steps: + - uses: actions/checkout@v3 + - name: Cache dependencies + uses: actions/cache@v3 + env: + cache-name: cache-deps + with: + path: .cache/deps + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/ThirdPartyDeps.cmake') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Cache build + uses: actions/cache@v3 + env: + cache-name: cache-build + with: + path: .cache/sccache + key: ${{ runner.os }}-build-${{ env.cache-name }} + - name: Install sccache + run: choco install sccache + - run: cmake -E make_directory build + - shell: bash + working-directory: build/ + run: cmake $GITHUB_WORKSPACE + - working-directory: build/ + run: cmake --build . --config ${{ matrix.build_type }} + - working-directory: build/ + run: ctest -C ${{ matrix.build_type }} --output-on-failure + + wheels: + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') + needs: [mac-os, linux, windows] + strategy: + fail-fast: false + matrix: + platform: [ 'windows-2019', 'ubuntu-latest', 'macos-latest' ] + python-version: [ '3.9', '3.10', '3.11' ] + runs-on: ${{ matrix.platform }} + env: + CIBW_BUILD: "cp${{ matrix.python-version }}-manylinux_x86_64 cp${{ matrix.python-version }}-macosx_x86_64 cp${{ matrix.python-version }}-win_amd64" + CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 + CIBW_DEPENDENCY_VERSIONS: latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + cache: 'pip' + - name: Install dependencies + run: pip install build twine cibuildwheel==2.14.1 + - name: Build wheels + run: python -m cibuildwheel --output-dir ./dist + - name: Run twine check + run: twine check --strict dist/* + - uses: actions/upload-artifact@v3 + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') || github.event.inputs.publish_artifacts == 'true' + name: Upload artifact (wheels) + with: + name: wheels + path: ./dist/*.whl + + publish: + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') + needs: [wheels] + runs-on: ubuntu-latest + environment: pypi + steps: + - uses: actions/download-artifact@v3 + with: + name: wheels + path: ./dist/ + - uses: pypa/gh-action-pypi-publish@v1.5.2 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml new file mode 100644 index 0000000..10e32f2 --- /dev/null +++ b/.github/workflows/sanitizer.yml @@ -0,0 +1,57 @@ +name: Sanitizer + +on: [push, pull_request] + +env: + SCCACHE_DIR: ${{ github.workspace }}/.cache/sccache + +jobs: + sanitizer: + strategy: + fail-fast: false + matrix: + cxx: [g++, clang++] + sanitizer: [address, undefined] + + runs-on: ubuntu-20.04 + + env: + CXX: ${{ matrix.cxx }} + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Cache dependencies + uses: actions/cache@v2 + env: + cache-name: cache-deps + with: + path: .cache/deps + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/ThirdPartyDeps.cmake') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Cache build + uses: actions/cache@v2 + env: + cache-name: cache-build + with: + path: .cache/sccache + key: ${{ runner.os }}-build-${{ env.cache-name }} + - name: Install sccache + run: | + curl -SL https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xvz --strip-components=1 --wildcards "*/sccache" + chmod +x sccache + - run: cmake -E make_directory build + + - working-directory: build/ + run: cmake $GITHUB_WORKSPACE -DBUILD_EXAMPLES=OFF -DCMAKE_CXX_FLAGS="-fsanitize=${{ matrix.sanitizer }}" + + - working-directory: build/ + run: cmake --build . + + - working-directory: build/ + run: ctest --output-on-failure diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..1ee74cf --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,46 @@ +name: Static Analysis + +on: [push, pull_request] + +env: + SCCACHE_DIR: ${{ github.workspace }}/.cache/sccache + +jobs: + static-analysis: + runs-on: ubuntu-20.04 + env: + CC: clang-10 + CXX: clang++-10 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Cache dependencies + uses: actions/cache@v2 + env: + cache-name: cache-deps + with: + path: .cache/deps + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/ThirdPartyDeps.cmake') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Cache build + uses: actions/cache@v2 + env: + cache-name: cache-build + with: + path: .cache/sccache + key: ${{ runner.os }}-build-${{ env.cache-name }} + - name: Install sccache + run: | + curl -SL https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xvz --strip-components=1 --wildcards "*/sccache" + chmod +x sccache + - name: Install install static analyzers + run: sudo apt install clang-tidy iwyu + - name: CMake configure + run: cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=OFF -DENABLE_TESTING=OFF -DENABLE_STATIC_ANALYSIS=ON + - name: CMake build + run: cmake --build build --config Debug -j --clean-first diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..0a74c64 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,49 @@ +name: Run Unit Tests + +on: [push, pull_request] + +env: + SCCACHE_DIR: ${{ github.workspace }}/.cache/sccache + +jobs: + tests: + runs-on: ubuntu-20.04 + env: + CC: gcc-9 + CXX: g++-9 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Cache dependencies + uses: actions/cache@v2 + env: + cache-name: cache-deps + with: + path: .cache/deps + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/ThirdPartyDeps.cmake') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Cache build + uses: actions/cache@v2 + env: + cache-name: cache-build + with: + path: .cache/sccache + key: ${{ runner.os }}-build-${{ env.cache-name }} + - name: Install sccache + run: | + curl -SL https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xvz --strip-components=1 --wildcards "*/sccache" + chmod +x sccache + - name: CMake configure + run: cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON -DENABLE_TESTING=ON + - name: CMake build + run: cmake --build build --config Debug -j --clean-first + - name: CTest + working-directory: build/ + run: ctest --output-on-failure + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ae016f..7c014af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ include(CMakePrintHelpers) include(GNUInstallDirs) include(CMakePackageConfigHelpers) include(CTest) +include(StaticAnalyzers) # Options option(SIGNALTL_TEST "Build signaltl test suite?" ${SIGNALTL_MASTER_PROJECT}) @@ -29,6 +30,7 @@ option(SIGNALTL_EXAMPLES "Build the examples?" ${SIGNALTL_MASTER_PROJECT}) option(SIGNALTL_INSTALL "Install the library and header files?" ${SIGNALTL_MASTER_PROJECT}) option(SIGNALTL_PYTHON_BINDINGS "Build the Python extension?" ON) +option(ENABLE_STATIC_ANALYSIS "Enable clang-tidy and include-what-you-use" OFF) set(_SIGNALTL_BUILD_THE_TESTS OFF @@ -64,6 +66,9 @@ target_compile_features(signaltl PUBLIC cxx_std_17) target_link_libraries(signaltl PRIVATE mono_wedge::mono_wedge) target_link_libraries(signaltl PUBLIC fmt::fmt) set_target_properties(signaltl PROPERTIES POSITION_INDEPENDENT_CODE ON) +enable_clang_tidy(signaltl) +enable_include_what_you_use(signaltl) + if(MSVC) target_compile_options(signaltl PRIVATE /W4 /WX /utf-8) else() diff --git a/MANIFEST.in b/MANIFEST.in index 8db74b7..df65ab7 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -13,3 +13,5 @@ graft third_party graft signal_tl graft src +prune .cache +prune .github \ No newline at end of file diff --git a/README.md b/README.md index fadf86e..05987ef 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![pypi](https://badge.fury.io/py/signal-temporal-logic.svg)](https://badge.fury.io/py/signal-temporal-logic) +[![pypi](https://badge.fury.io/py/mvx-stl.svg)](https://badge.fury.io/py/mvx-stl) # mvx-stl diff --git a/ci/compiler-tests.yml b/ci/compiler-tests.yml deleted file mode 100644 index 7bcf1f3..0000000 --- a/ci/compiler-tests.yml +++ /dev/null @@ -1,38 +0,0 @@ -stages: - - stage: compiler_tests - displayName: "Test build the library on multiple compilers" - dependsOn: [] - jobs: - - job: build - strategy: - matrix: - ubuntu-clang-9: - VM_IMAGE: ubuntu-latest - CC: clang-9 - CXX: clang++-9 - ubuntu-gcc: - VM_IMAGE: ubuntu-latest - CC: gcc - CXX: g++ - macos-xcode-latest: - VM_IMAGE: macos-latest - windows-msvc-latest: - VM_IMAGE: windows-latest - pool: - vmImage: '$(VM_IMAGE)' - steps: - - checkout: self - submodules: true - - bash: | - export CC=$(CC) - export CXX=$(CXX) - condition: eq( variables['Agent.OS'], 'Linux' ) - displayName: "Set CC and CXX for Linux" - - task: run-cmake@0 - displayName: "Run CMake" - inputs: - cmakeListsOrSettingsJson: 'CMakeListsTxtBasic' - cmakeListsTxtPath: '$(Build.SourcesDirectory)/CMakeLists.txt' - buildDirectory: '$(Build.SourcesDirectory)/build' - cmakeBuildType: 'Release' - diff --git a/ci/install-deps.yml b/ci/install-deps.yml deleted file mode 100644 index e7e2591..0000000 --- a/ci/install-deps.yml +++ /dev/null @@ -1,5 +0,0 @@ -steps: - - checkout: self - submodules: recursive - - script: python -m pip install --upgrade pip setuptools wheel cibuildwheel - displayName: Install Python pip tools diff --git a/ci/macos-win-wheels-job.yml b/ci/macos-win-wheels-job.yml deleted file mode 100644 index 7f7f2e4..0000000 --- a/ci/macos-win-wheels-job.yml +++ /dev/null @@ -1,46 +0,0 @@ -jobs: - - job: build_wheels - strategy: - matrix: - macos-latest-py38: - VM_IMAGE: macos-latest - PYTHON_VERSION: 3.8 - macos-latest-py39: - VM_IMAGE: macos-latest - PYTHON_VERSION: 3.9 - macos-latest-py310: - VM_IMAGE: macos-latest - PYTHON_VERSION: 3.10 - macos-latest-py311: - VM_IMAGE: macos-latest - PYTHON_VERSION: 3.11 - windows-latest-py38: - VM_IMAGE: windows-latest - PYTHON_VERSION: 3.8 - windows-latest-py39: - VM_IMAGE: windows-latest - PYTHON_VERSION: 3.9 - windows-latest-py310: - VM_IMAGE: windows-latest - PYTHON_VERSION: 3.10 - windows-latest-py311: - VM_IMAGE: windows-latest - PYTHON_VERSION: 3.11 - continueOnError: true - pool: - vmImage: '$(VM_IMAGE)' - steps: - - checkout: self - submodules: recursive - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - - script: python -m pip install --upgrade pip setuptools wheel cibuildwheel - displayName: Install Python pip tools - - script: python -m pip wheel -w wheelhouse . - displayName: Build wheel - - task: PublishBuildArtifacts@1 - inputs: - pathtoPublish: 'wheelhouse' - artifactName: 'Wheels' - diff --git a/ci/manylinux-wheels-job.yml b/ci/manylinux-wheels-job.yml deleted file mode 100644 index ec2de73..0000000 --- a/ci/manylinux-wheels-job.yml +++ /dev/null @@ -1,22 +0,0 @@ -jobs: - - job: build_wheels_manylinux - pool: - vmImage: ubuntu-latest - variables: - CIBW_BUILD: "cp3{8,9,10,11}-manylinux* pp3{8,9,10,11}-manylinux*" - CIBW_SKIP: "*-win32 *-macosx_x86_64" - CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 - CIBW_DEPENDENCY_VERSIONS: latest - steps: - - checkout: self - submodules: recursive - - task: UsePythonVersion@0 - - script: python -m pip install --upgrade pip setuptools wheel cibuildwheel - displayName: Install Python pip tools - - script: python -m cibuildwheel --output-dir wheelhouse . - displayName: Build wheel - - task: PublishBuildArtifacts@1 - inputs: - pathtoPublish: 'wheelhouse' - artifactName: 'Wheels' - diff --git a/ci/unit-tests.yml b/ci/unit-tests.yml deleted file mode 100644 index 5b39c6a..0000000 --- a/ci/unit-tests.yml +++ /dev/null @@ -1,31 +0,0 @@ -stages: - - stage: unit_tests - displayName: "Run unit tests" - dependsOn: [] - jobs: - - job: catch_test - pool: - vmImage: ubuntu-latest - steps: - - checkout: self - submodules: true - - task: CMake@1 - displayName: "CMake configure for testing/coverage" - inputs: - workingDirectory: '$(Build.SourcesDirectory)/build' - cmakeArgs: '.. -DCMAKE_BUILD_TYPE=Debug -DSIGNALTL_COVERAGE=ON' - - task: CMake@1 - displayName: "CMake build" - inputs: - workingDirectory: '$(Build.SourcesDirectory)/build' - cmakeArgs: '--build . --config Debug' - - script: ctest -no-compress-output -T Test - displayName: "Run CTest" - workingDirectory: '$(Build.SourcesDirectory)/build' - - task: PublishTestResults@2 - inputs: - testResultsFormat: 'cTest' - testResultsFiles: '**/Test*.xml' - searchFolder: '$(Build.SourcesDirectory)/build' - configuration: Debug - diff --git a/cmake/StaticAnalyzers.cmake b/cmake/StaticAnalyzers.cmake new file mode 100644 index 0000000..5a22e38 --- /dev/null +++ b/cmake/StaticAnalyzers.cmake @@ -0,0 +1,62 @@ +option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" + ${ENABLE_STATIC_ANALYSIS} +) +option(ENABLE_INCLUDE_WHAT_YOU_USE + "Enable static analysis with include-what-you-use" + ${ENABLE_STATIC_ANALYSIS} +) + +include(CMakeParseArguments) + +if(ENABLE_CLANG_TIDY) + message(CHECK_START "Finding clang-tidy") + find_program(CLANGTIDY clang-tidy) + if(CLANGTIDY) + message(CHECK_PASS "found: ${CLANGTIDY}") + set(CLANG_TIDY_CMD + ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option + CACHE INTERNAL "Command for clang-tidy" + ) + else() + message(CHECK_FAIL "not found") + message(SEND_ERROR "clang-tidy requested but executable not found") + endif() +endif() + +function(enable_clang_tidy target) + message(STATUS "Enabling clang-tidy checks for ${target}") + + if(ENABLE_CLANG_TIDY) + set_target_properties( + ${target} PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_CMD}" + ) + endif() +endfunction() + +if(ENABLE_INCLUDE_WHAT_YOU_USE) + message(CHECK_START "Finding include-what-you-use") + find_program(INCLUDE_WHAT_YOU_USE include-what-you-use) + if(INCLUDE_WHAT_YOU_USE) + message(CHECK_PASS "found: ${INCLUDE_WHAT_YOU_USE}") + set(INCLUDE_WHAT_YOU_USE_CMD + ${INCLUDE_WHAT_YOU_USE} + CACHE INTERNAL "Command for include-what-you-use" + ) + else() + message(CHECK_FAIL "not found") + message( + SEND_ERROR "include-what-you-use requested but executable not found" + ) + endif() +endif() + +function(enable_include_what_you_use target) + message(STATUS "Enabling include-what-you-use checks for ${target}") + + if(ENABLE_INCLUDE_WHAT_YOU_USE) + set_target_properties( + ${target} PROPERTIES CXX_INCLUDE_WHAT_YOU_USE + "${INCLUDE_WHAT_YOU_USE_CMD}" + ) + endif() +endfunction() diff --git a/cmake/ThirdPartyLibs.cmake b/cmake/ThirdPartyLibs.cmake index 4def355..50851cd 100644 --- a/cmake/ThirdPartyLibs.cmake +++ b/cmake/ThirdPartyLibs.cmake @@ -19,14 +19,16 @@ function(git_submodule) endif() message(VERBOSE "Trying to update submodule in ${GitSubmodule_PATH}") - execute_process( - COMMAND ${GIT_EXECUTABLE} submodule update --init -- ${GitSubmodule_PATH} - WORKING_DIRECTORY ${GitSubmodule_WORKING_DIRECTORY} - RESULT_VARIABLE GIT_SUBMOD_RESULT) - if(NOT GIT_SUBMOD_RESULT EQUAL "0") - message( - FATAL_ERROR - "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules" - ) + if (NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${GitSubmodule_PATH}/CMakeLists.txt") + execute_process( + COMMAND ${GIT_EXECUTABLE} submodule update --init -- ${GitSubmodule_PATH} + WORKING_DIRECTORY ${GitSubmodule_WORKING_DIRECTORY} + RESULT_VARIABLE GIT_SUBMOD_RESULT) + if(NOT GIT_SUBMOD_RESULT EQUAL "0") + message( + FATAL_ERROR + "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules" + ) + endif () endif() endfunction() diff --git a/setup.cfg b/setup.cfg index 7deef65..67c1653 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,7 +10,7 @@ author = Anand Balakrishnan author_email = anandbala1597@gmail.com maintainer = Hee Jong Park maintainer_email = hee.jong.park@dnv.com -url = +url = https://github.com/davidhjp01/signal-temporal-logic classifiers = Programming Language :: Python :: 3 :: Only diff --git a/setup.py b/setup.py index ae6aaf2..89f8baf 100644 --- a/setup.py +++ b/setup.py @@ -7,8 +7,9 @@ import sys from distutils.version import LooseVersion -from setuptools import Extension, setup +from setuptools import Extension, setup, find_packages from setuptools.command.build_ext import build_ext +from setuptools.command.sdist import sdist class CMakeExtension(Extension): @@ -94,7 +95,15 @@ def build_extension(self, ext): ) +class SdistBuild(sdist): + def run(self) -> None: + print("Git submodule update..") + subprocess.check_call(["git", "submodule", "update", "--init"]) + super().run() + + setup( ext_modules=[CMakeExtension("signal_tl._cext")], - cmdclass=dict(build_ext=CMakeBuild), + packages=find_packages(), + cmdclass=dict(build_ext=CMakeBuild, sdist=SdistBuild) )