Skip to content

Commit

Permalink
⬆️ update mqt-core (#357)
Browse files Browse the repository at this point in the history
## Description

This PR updates the mqt-core submodule and brings in some further
advancements from #355.
Specifically, it switches to using `FetchContent` for obtaining
`mqt-core`.
Per default, it is pointed to the vendored submodule via an overridable
CMake variable.

## Checklist:

<!---
This checklist serves as a reminder of a couple of things that ensure
your pull request will be merged swiftly.
-->

- [x] The pull request only contains commits that are related to it.
- [x] I have added appropriate tests and documentation.
- [x] I have made sure that all CI jobs on GitHub pass.
- [x] The pull request introduces no new warnings and follows the
project's style guidelines.

---------

Signed-off-by: burgholzer <[email protected]>
  • Loading branch information
burgholzer authored Jan 29, 2024
1 parent f6cc523 commit 9870cce
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 150 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ repos:
hooks:
- id: cmake-format
additional_dependencies: [pyyaml]
- id: cmake-lint
additional_dependencies: [pyyaml]
types: [file]
files: (\.cmake|CMakeLists.txt)(.in)?$

# Clang-format the C++ part of the code base automatically
- repo: https://github.com/pre-commit/mirrors-clang-format
Expand All @@ -95,7 +95,7 @@ repos:
hooks:
- id: mypy
files: ^(src/mqt|test/python)
args: ["--enable-incomplete-feature=Unpack"]
args: []
additional_dependencies:
- importlib_resources
- numpy
Expand Down
31 changes: 14 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,31 @@
cmake_minimum_required(VERSION 3.19...3.28)

project(
qcec
mqt-qcec
LANGUAGES CXX
DESCRIPTION "MQT QCEC - A tool for Quantum Circuit Equivalence Checking")

# check whether `modulename` is correctly cloned in the `extern` directory.
macro(CHECK_SUBMODULE_PRESENT modulename)
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/${modulename}/CMakeLists.txt")
message(
FATAL_ERROR
"${modulename} submodule not cloned properly. \
Please run `git submodule update --init --recursive` \
from the main project directory")
endif()
endmacro()

check_submodule_present(mqt-core)

option(BUILD_MQT_QCEC_TESTS "Also build tests for the MQT QCEC project" ON)
option(BUILD_MQT_QCEC_BINDINGS "Build the MQT QCEC Python bindings" OFF)

if(BUILD_MQT_QCEC_BINDINGS)
# ensure that the BINDINGS option is set
set(BINDINGS
ON
CACHE BOOL "Enable settings related to Python bindings" FORCE)
# cmake-lint: disable=C0103
CACHE INTERNAL "Enable settings related to Python bindings")
# Some common settings for finding Python
set(Python_FIND_VIRTUALENV
FIRST
CACHE STRING "Give precedence to virtualenvs when searching for Python")
# cmake-lint: disable=C0103
set(Python_FIND_FRAMEWORK
LAST
CACHE STRING "Prefer Brew/Conda to Apple framework Python")
set(Python_ARTIFACTS_INTERACTIVE
ON
CACHE
BOOL
"Prevent multiple searches for Python and instead cache the results.")

# top-level call to find Python
find_package(
Python 3.8 REQUIRED
Expand All @@ -55,3 +45,10 @@ if(BUILD_MQT_QCEC_TESTS)
include(GoogleTest)
add_subdirectory(test)
endif()

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY)
add_custom_target(
uninstall COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
142 changes: 75 additions & 67 deletions cmake/ExternalDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,80 +3,88 @@
include(FetchContent)
set(FETCH_PACKAGES "")

# A macro to declare a dependency that takes into account the different CMake
# versions and the features that they make available. In particular: - CMake
# 3.24 introduced the `FIND_PACKAGE_ARGS` option to `FetchContent` which allows
# to combine `FetchContent_Declare` and `find_package` in a single call. - CMake
# 3.25 introduced the `SYSTEM` option to `FetchContent_Declare` which marks the
# dependency as a system dependency. This is useful to avoid compiler warnings
# from external header only libraries. - CMake 3.28 introduced the
# `EXCLUDE_FROM_ALL` option to `FetchContent_Declare` which allows to exclude
# all targets from the dependency from the `all` target.
macro(DECLARE_DEPENDENCY)
cmake_parse_arguments(DEPENDENCY "SYSTEM;EXCLUDE_FROM_ALL"
"NAME;URL;MD5;MIN_VERSION;ALT_NAME" "" ${ARGN})
set(ADDITIONAL_OPTIONS "")
if(DEPENDENCY_SYSTEM AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.25)
list(APPEND ADDITIONAL_OPTIONS SYSTEM)
endif()
if(DEPENDENCY_EXCLUDE_FROM_ALL AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.28)
list(APPEND ADDITIONAL_OPTIONS EXCLUDE_FROM_ALL)
if(BUILD_MQT_QCEC_BINDINGS)
if(NOT SKBUILD)
# Manually detect the installed pybind11 package.
execute_process(
COMMAND "${Python_EXECUTABLE}" -m pybind11 --cmakedir
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE pybind11_DIR)

# Add the detected directory to the CMake prefix path.
list(APPEND CMAKE_PREFIX_PATH "${pybind11_DIR}")
endif()
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28)
FetchContent_Declare(
${DEPENDENCY_NAME}
URL ${DEPENDENCY_URL}
URL_MD5 ${DEPENDENCY_MD5}
${ADDITIONAL_OPTIONS} FIND_PACKAGE_ARGS ${DEPENDENCY_MIN_VERSION} NAMES
${DEPENDENCY_ALT_NAME})
list(APPEND FETCH_PACKAGES ${DEPENDENCY_NAME})
elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.25)
FetchContent_Declare(
${DEPENDENCY_NAME}
URL ${DEPENDENCY_URL}
URL_MD5 ${DEPENDENCY_MD5}
${ADDITIONAL_OPTIONS} FIND_PACKAGE_ARGS ${DEPENDENCY_MIN_VERSION} NAMES
${DEPENDENCY_ALT_NAME})
list(APPEND FETCH_PACKAGES ${DEPENDENCY_NAME})
elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)

# add pybind11 library
find_package(pybind11 CONFIG REQUIRED)
endif()

set(FETCHCONTENT_SOURCE_DIR_MQT-CORE
${PROJECT_SOURCE_DIR}/extern/mqt-core
CACHE
PATH
"Path to the source directory of the mqt-core library. This variable is used by FetchContent to download the library if it is not already available."
)
set(MQT_CORE_VERSION
2.2.2
CACHE STRING "MQT Core version")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
FetchContent_Declare(
mqt-core
GIT_REPOSITORY https://github.com/cda-tum/mqt-core.git
GIT_TAG v${MQT_CORE_VERSION}
FIND_PACKAGE_ARGS ${MQT_CORE_VERSION})
list(APPEND FETCH_PACKAGES mqt-core)
else()
find_package(mqt-core ${MQT_CORE_VERSION} QUIET)
if(NOT mqt-core_FOUND)
FetchContent_Declare(
${DEPENDENCY_NAME}
URL ${DEPENDENCY_URL}
URL_MD5 ${DEPENDENCY_MD5}
${ADDITIONAL_OPTIONS} FIND_PACKAGE_ARGS ${DEPENDENCY_MIN_VERSION} NAMES
${DEPENDENCY_ALT_NAME})
list(APPEND FETCH_PACKAGES ${DEPENDENCY_NAME})
else()
# try to get the system installed version
find_package(${DEPENDENCY_NAME} ${DEPENDENCY_MIN_VERSION} QUIET NAMES
${DEPENDENCY_ALT_NAME})
if(NOT ${DEPENDENCY_NAME}_FOUND)
FetchContent_Declare(
${DEPENDENCY_NAME}
URL ${DEPENDENCY_URL}
URL_MD5 ${DEPENDENCY_MD5})
list(APPEND FETCH_PACKAGES ${DEPENDENCY_NAME})
endif()
mqt-core
GIT_REPOSITORY https://github.com/cda-tum/mqt-core.git
GIT_TAG v${MQT_CORE_VERSION})
list(APPEND FETCH_PACKAGES mqt-core)
endif()
endmacro()
endif()

if(BUILD_MQT_QCEC_TESTS)
set(gtest_force_shared_crt # cmake-lint: disable=C0103
set(gtest_force_shared_crt
ON
CACHE BOOL "" FORCE)
declare_dependency(
NAME
googletest
URL
https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz
MD5
c8340a482851ef6a3fe618a082304cfc
MIN_VERSION
1.14.0
ALT_NAME
GTest
SYSTEM
EXCLUDE_FROM_ALL)
set(GTEST_VERSION
1.14.0
CACHE STRING "Google Test version")
set(GTEST_URL
https://github.com/google/googletest/archive/refs/tags/v${GTEST_VERSION}.tar.gz
)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
FetchContent_Declare(googletest URL ${GTEST_URL} FIND_PACKAGE_ARGS
${GTEST_VERSION} NAMES GTest)
list(APPEND FETCH_PACKAGES googletest)
else()
find_package(googletest ${GTEST_VERSION} QUIET NAMES GTest)
if(NOT googletest_FOUND)
FetchContent_Declare(googletest URL ${GTEST_URL})
list(APPEND FETCH_PACKAGES googletest)
endif()
endif()
endif()

if(BUILD_MQT_QCEC_BINDINGS)
# add pybind11_json library
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
FetchContent_Declare(
pybind11_json
GIT_REPOSITORY https://github.com/pybind/pybind11_json
FIND_PACKAGE_ARGS)
list(APPEND FETCH_PACKAGES pybind11_json)
else()
find_package(pybind11_json QUIET)
if(NOT pybind11_json_FOUND)
FetchContent_Declare(
pybind11_json GIT_REPOSITORY https://github.com/pybind/pybind11_json)
list(APPEND FETCH_PACKAGES pybind11_json)
endif()
endif()
endif()

# Make all declared dependencies available.
Expand Down
26 changes: 26 additions & 0 deletions cmake/cmake_uninstall.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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()
2 changes: 1 addition & 1 deletion extern/mqt-core
Submodule mqt-core updated 113 files
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
if TYPE_CHECKING:
from collections.abc import Sequence

nox.options.sessions = ["lint", "pylint", "tests"]
nox.options.sessions = ["lint", "tests"]

PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12"]

Expand Down
18 changes: 8 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ Discussions = "https://github.com/cda-tum/mqt-qcec/discussions"
# Protect the configuration against future changes in scikit-build-core
minimum-version = "0.6.1"

# Set the target to build
cmake.targets = ["pyqcec"]
# Set the wheel install directory
wheel.install-dir = "mqt/qcec"

# Set required CMake and Ninja versions
cmake.minimum-version = "3.19"
Expand All @@ -82,9 +82,6 @@ ninja.minimum-version = "1.10"
# Setuptools-style build caching in a local directory
build-dir = "build/{wheel_tag}"

# Build stable ABI wheels for CPython 3.12+
wheel.py-api = "cp312"

# Explicitly set the package directory
wheel.packages = ["src/mqt"]

Expand Down Expand Up @@ -141,19 +138,21 @@ run.omit = ["src/mqt/qcec/types.py"]
report.exclude_also = [
'\.\.\.',
'if TYPE_CHECKING:',
'raise AssertionError',
'raise NotImplementedError',
]


[tool.mypy]
files = ["src/mqt", "test/python"]
mypy_path = ["$MYPY_CONFIG_FILE_DIR/src"]
python_version = "3.8"
strict = true
show_error_codes = true
warn_unused_configs = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true
strict = true
disallow_untyped_defs = false
explicit_package_bases = true
pretty = true
warn_unreachable = true

[[tool.mypy.overrides]]
module = ["qiskit.*"]
Expand Down Expand Up @@ -240,7 +239,6 @@ build = "cp3*"
skip = "*-musllinux_*"
archs = "auto64"
test-command = "python -c \"from mqt import qcec\""
test-skip = "cp312-*" # Qiskit Terra does not support Python 3.12 yet
build-frontend = "build"

[tool.cibuildwheel.linux]
Expand Down
11 changes: 3 additions & 8 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
# add MQT::Core target
set(BUILD_MQT_CORE_TESTS
OFF
CACHE BOOL "Build MQT Core tests")
add_subdirectory("${PROJECT_SOURCE_DIR}/extern/mqt-core" "extern/mqt-core"
EXCLUDE_FROM_ALL)

add_library(
${PROJECT_NAME}
${PROJECT_SOURCE_DIR}/include/checker
Expand All @@ -28,9 +21,11 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include

# link to the MQT::Core libraries
target_link_libraries(${PROJECT_NAME} PUBLIC MQT::CoreDD MQT::CoreZX)
target_link_libraries(${PROJECT_NAME} PRIVATE MQT::ProjectWarnings
MQT::ProjectOptions)

# add MQT alias
add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
add_library(MQT::QCEC ALIAS ${PROJECT_NAME})

if(BUILD_MQT_QCEC_BINDINGS)
add_subdirectory(python)
Expand Down
Loading

0 comments on commit 9870cce

Please sign in to comment.