diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6756b8a2..2fd34d23 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,7 +56,7 @@ repos: # Python linting using ruff - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.3 + rev: v0.6.4 hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -97,14 +97,15 @@ repos: rev: v1.11.2 hooks: - id: mypy - files: ^(src/mqt|test/python) + files: ^(src/mqt|test/python|noxfile.py) additional_dependencies: + - nox - numpy - pytest # Check for spelling - repo: https://github.com/crate-ci/typos - rev: v1.24.1 + rev: v1.24.5 hooks: - id: typos diff --git a/CMakeLists.txt b/CMakeLists.txt index a7999d15..25dcca56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,12 @@ # set required cmake version -cmake_minimum_required(VERSION 3.19...3.28) +cmake_minimum_required(VERSION 3.19...3.30) project( mqt-ddsim LANGUAGES CXX DESCRIPTION "MQT DDSIM - A quantum circuit simulator based on decision diagrams") -option(BUILD_MQT_DDSIM_TESTS "Also build tests for the MQT DDSIM project" ON) option(BUILD_MQT_DDSIM_BINDINGS "Build the MQT DDSIM Python bindings" OFF) -option(BUILD_MQT_DDSIM_CLI "Build the MQT DDSIM command line interface" ON) - if(BUILD_MQT_DDSIM_BINDINGS) # ensure that the BINDINGS option is set set(BINDINGS @@ -38,6 +35,17 @@ if(BUILD_MQT_DDSIM_BINDINGS) OPTIONAL_COMPONENTS Development.SABIModule) endif() +# check if this is the master project or used via add_subdirectory +if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + set(MQT_DDSIM_MASTER_PROJECT ON) +else() + set(MQT_DDSIM_MASTER_PROJECT OFF) +endif() + +option(BUILD_MQT_DDSIM_TESTS "Also build tests for the MQT DDSIM project" + ${MQT_DDSIM_MASTER_PROJECT}) +option(BUILD_MQT_DDSIM_CLI "Build the MQT DDSIM command line interface" ${MQT_DDSIM_MASTER_PROJECT}) + include(cmake/ExternalDependencies.cmake) # set the include directory for the build tree @@ -54,3 +62,16 @@ endif() if(BUILD_MQT_DDSIM_CLI) add_subdirectory(apps) endif() + +if(MQT_DDSIM_MASTER_PROJECT) + if(NOT TARGET mqt-ddsim-uninstall) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY) + add_custom_target(mqt-ddsim-uninstall COMMAND ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + endif() +else() + set(mqt-ddsim_FOUND + TRUE + CACHE INTERNAL "True if mqt-ddsim is found on the system") +endif() diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in new file mode 100644 index 00000000..1e5d2bb8 --- /dev/null +++ b/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,23 @@ +# Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake + +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS + "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif() + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif() +endforeach() diff --git a/noxfile.py b/noxfile.py index c83057e0..ab86f27e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -16,7 +16,7 @@ nox.needs_version = ">=2024.3.2" nox.options.default_venv_backend = "uv|virtualenv" -nox.options.sessions = ["lint", "tests"] +nox.options.sessions = ["lint", "tests", "minimums"] PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] @@ -38,12 +38,11 @@ @nox.session(reuse_venv=True) def lint(session: nox.Session) -> None: - """Lint the Python part of the codebase using pre-commit. + """Run the linter.""" + if shutil.which("pre-commit") is None: + session.install("pre-commit") - Simply execute `nox -rs lint` to run all configured hooks. - """ - session.install("pre-commit") - session.run("pre-commit", "run", "--all-files", *session.posargs) + session.run("pre-commit", "run", "--all-files", *session.posargs, external=True) def _run_tests( @@ -54,8 +53,7 @@ def _run_tests( extras: Sequence[str] = (), ) -> None: posargs = list(session.posargs) - env = {"PIP_DISABLE_PIP_VERSION_CHECK": "1"} - + env = {} if os.environ.get("CI", None) and sys.platform == "win32": env["SKBUILD_CMAKE_ARGS"] = "-T ClangCL" diff --git a/pyproject.toml b/pyproject.toml index 3bcc0837..2f2ec0a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -169,7 +169,7 @@ report.exclude_also = [ [tool.mypy] -files = ["src/mqt", "test/python"] +files = ["src/mqt", "test/python", "noxfile.py"] mypy_path = ["$MYPY_CONFIG_FILE_DIR/src"] python_version = "3.8" warn_unused_configs = true diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cf5623c4..5470f799 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,44 +1,32 @@ set(MQT_DDSIM_TARGET_NAME mqt-ddsim) -add_library( - ${MQT_DDSIM_TARGET_NAME} - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/Simulator.hpp - Simulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/CircuitSimulator.hpp - CircuitSimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/GroverSimulator.hpp - GroverSimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/ShorSimulator.hpp - ShorSimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/ShorFastSimulator.hpp - ShorFastSimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/StochasticNoiseSimulator.hpp - StochasticNoiseSimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/DeterministicNoiseSimulator.hpp - DeterministicNoiseSimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/HybridSchrodingerFeynmanSimulator.hpp - HybridSchrodingerFeynmanSimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/UnitarySimulator.hpp - UnitarySimulator.cpp - ${MQT_DDSIM_INCLUDE_BUILD_DIR}/PathSimulator.hpp - PathSimulator.cpp) +if(NOT TARGET MQT::DDSim) + # collect headers and source files + file(GLOB_RECURSE MQT_DDSIM_HEADERS ${MQT_DDSIM_INCLUDE_BUILD_DIR}/*.hpp) + file(GLOB_RECURSE MQT_DDSIM_SOURCES **.cpp) + list(FILTER MQT_DDSIM_SOURCES EXCLUDE REGEX ".*/python/.*$") -# set include directories -target_include_directories(${MQT_DDSIM_TARGET_NAME} - PUBLIC $) + # add DDSim Package library + add_library(${MQT_DDSIM_TARGET_NAME} ${MQT_DDSIM_HEADERS} ${MQT_DDSIM_SOURCES}) -# link to the MQT::Core and Taskflow libraries -target_link_libraries( - ${MQT_DDSIM_TARGET_NAME} - PUBLIC MQT::CoreDD MQT::CoreCircuitOptimizer Taskflow - PRIVATE MQT::ProjectWarnings MQT::ProjectOptions) + # set include directories + target_include_directories(${MQT_DDSIM_TARGET_NAME} + PUBLIC $) -# the following sets the SYSTEM flag for the include dirs of the taskflow libs -set_target_properties(Taskflow PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES - $) + # link to the MQT::Core and Taskflow libraries + target_link_libraries( + ${MQT_DDSIM_TARGET_NAME} + PUBLIC MQT::CoreDD MQT::CoreCircuitOptimizer Taskflow + PRIVATE MQT::ProjectWarnings MQT::ProjectOptions) -# add MQT alias -add_library(MQT::DDSim ALIAS ${MQT_DDSIM_TARGET_NAME}) + # the following sets the SYSTEM flag for the include dirs of the taskflow libs + set_target_properties( + Taskflow PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + $) + + # add MQT alias + add_library(MQT::DDSim ALIAS ${MQT_DDSIM_TARGET_NAME}) +endif() if(BUILD_MQT_DDSIM_BINDINGS) add_subdirectory(python)