Cmake: make conan optional (#999)

Co-authored-by: Drew Risinger <drewrisinger@users.noreply.github.com>
This commit is contained in:
Victor Villar 2020-11-04 15:51:04 +01:00 committed by GitHub
parent d3b927a01f
commit 721fcb4dbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 190 additions and 48 deletions

View File

@ -32,11 +32,20 @@ option(STATIC_LINKING "Specify if we want statically link the executable (for
redistribution mainly)" FALSE)
option(BUILD_TESTS "Specify whether we want to build tests or not" FALSE)
# Allow disabling conan for downstream package managers. Requires all libraries to be present in path
# Default is value of environment variable if defined or ON
if(DEFINED ENV{DISABLE_CONAN})
set(_DISABLE_CONAN_DEFAULT ENV{DISABLE_CONAN})
else()
set(_DISABLE_CONAN_DEFAULT OFF)
endif()
option(DISABLE_CONAN "Disable Conan package manager to find dependencies. If disabled, you must have all dependencies present on your system." ${_DISABLE_CONAN_DEFAULT})
include(CTest)
include(compiler_utils)
include(Linter)
include(findBLASInSpecificPath)
include(conan_utils)
include(dependency_utils)
# Get version information
get_version(${VERSION_NUM})
@ -124,29 +133,33 @@ endif()
#
# Looking for external libraries
#
setup_conan()
set(BACKEND_REDIST_DEPS "") # List of redistributable dependencies
setup_dependencies()
# If we do not set them with a space CMake fails afterwards if nothing is set for this vars!
set(AER_LINKER_FLAGS " ")
set(AER_COMPILER_FLAGS " ")
message(STATUS "Looking for OpenMP support...")
if(APPLE)
set(OPENMP_FOUND TRUE)
if(NOT SKBUILD)
set(AER_LIBRARIES ${AER_LIBRARIES} CONAN_PKG::llvm-openmp)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CONAN_CXX_FLAGS_LLVM-OPENMP}")
set(AER_SIMULATOR_CPP_EXTERNAL_LIBS ${AER_SIMULATOR_CPP_EXTERNAL_LIBS} ${CONAN_INCLUDE_DIRS_LLVM-OPENMP})
endif()
else()
if(NOT OPENMP_FOUND) # Could already be setup for macos with conan
message(STATUS "Looking for OpenMP support...")
find_package(OpenMP QUIET)
if(OPENMP_FOUND)
set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} ${OpenMP_CXX_FLAGS}")
set(AER_LINKER_FLAGS "${AER_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
if(APPLE)
set(AER_SIMULATOR_CPP_EXTERNAL_LIBS ${AER_SIMULATOR_CPP_EXTERNAL_LIBS} ${OpenMP_CXX_INCLUDE_DIRS})
# On Apple and clang, we do need to link against the library unless we are building
# the Terra Addon, see issue: https://github.com/Qiskit/qiskit-aer/issues/1
if(NOT SKBUILD)
set(AER_LIBRARIES "${AER_LIBRARIES}" "${OpenMP_${OpenMP_CXX_LIB_NAMES}_LIBRARY}")
message(STATUS "Adding Clang: ${OpenMP_${OpenMP_CXX_LIB_NAMES}_LIBRARY}")
else()
get_filename_component(OPENMP_LIB_TO_COPY ${OpenMP_${OpenMP_CXX_LIB_NAMES}_LIBRARY} REALPATH) #Needed to follow symlinks
set(BACKEND_REDIST_DEPS ${BACKEND_REDIST_DEPS} ${OPENMP_LIB_TO_COPY})
endif()
endif()
message(STATUS "OpenMP found!")
message(STATUS "OpenMP_CXX_FLAGS = ${OpenMP_CXX_FLAGS}")
message(STATUS "OpenMP_EXE_LINKER_FLAGS = ${OpenMP_EXE_LINKER_FLAGS}")
@ -184,7 +197,7 @@ else()
set(WIN_ARCH "win32")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E tar "xvfj" "${AER_SIMULATOR_CPP_SRC_DIR}/third-party/${WIN_ARCH}/lib/openblas.7z" WORKING_DIRECTORY "${AER_SIMULATOR_CPP_SRC_DIR}/third-party/${WIN_ARCH}/lib/")
set(OPENBLAS_DLLs "${AER_SIMULATOR_CPP_SRC_DIR}/third-party/${WIN_ARCH}/lib/libopenblas.dll")
set(BACKEND_REDIST_DEPS ${BACKEND_REDIST_DEPS} "${AER_SIMULATOR_CPP_SRC_DIR}/third-party/${WIN_ARCH}/lib/libopenblas.dll")
set(BLAS_LIBRARIES "${AER_SIMULATOR_CPP_SRC_DIR}/third-party/${WIN_ARCH}/lib/libopenblas.dll.a") # Seems CMake is unable to find it on its own
set(BLAS_FOUND True)
else()
@ -236,21 +249,19 @@ if(AER_THRUST_SUPPORTED)
endif()
endif()
set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA)
set(THRUST_DEPENDANT_LIBS "")
set(THRUST_DEPENDENT_LIBS "")
elseif(AER_THRUST_BACKEND STREQUAL "TBB")
message(STATUS "TBB Support found!")
set(AER_SIMULATOR_CPP_EXTERNAL_LIBS ${AER_SIMULATOR_CPP_EXTERNAL_LIBS} ${CONAN_INCLUDE_DIRS_THRUST})
set(THRUST_DEPENDANT_LIBS CONAN_PKG::tbb)
set(THRUST_DEPENDENT_LIBS AER_DEPENDENCY_PKG::tbb)
set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} AER_THRUST_CPU=TRUE)
elseif(AER_THRUST_BACKEND STREQUAL "OMP")
message(STATUS "Thrust library: Setting OMP backend")
if(NOT OPENMP_FOUND)
message(FATAL_ERROR "There's no OMP support. We cannot set Thrust backend to OMP!!")
endif()
set(AER_SIMULATOR_CPP_EXTERNAL_LIBS ${AER_SIMULATOR_CPP_EXTERNAL_LIBS} ${CONAN_INCLUDE_DIRS_THRUST})
set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} AER_THRUST_CPU=TRUE)
# We don't need to add OMP because it's already an AER dependency
set(THRUST_DEPENDANT_LIBS "")
set(THRUST_DEPENDENT_LIBS "")
else()
message(STATUS "No Thrust supported backend")
set(AER_THRUST_SUPPORTED FALSE)
@ -268,16 +279,16 @@ endif()
set(AER_LIBRARIES
${AER_LIBRARIES}
${BLAS_LIBRARIES}
CONAN_PKG::nlohmann_json
AER_DEPENDENCY_PKG::nlohmann_json
AER_DEPENDENCY_PKG::spdlog
Threads::Threads
CONAN_PKG::spdlog
${DL_LIB}
${THRUST_DEPENDANT_LIBS})
${THRUST_DEPENDENT_LIBS})
set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} ${CONAN_DEFINES})
# Cython build is only enabled if building through scikit-build.
if(SKBUILD) # Terra Addon build
set(AER_LIBRARIES ${AER_LIBRARIES} CONAN_PKG::muparserx)
set(AER_LIBRARIES ${AER_LIBRARIES} AER_DEPENDENCY_PKG::muparserx)
add_subdirectory(qiskit/providers/aer/pulse/qutip_extra_lite/cy)
add_subdirectory(qiskit/providers/aer/backends/wrappers)
add_subdirectory(src/open_pulse)
@ -320,9 +331,9 @@ else() # Standalone build
PRIVATE ${AER_COMPILER_DEFINITIONS})
if(WIN32 AND NOT BLAS_LIB_PATH)
add_custom_command(TARGET qasm_simulator POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different
${OPENBLAS_DLLs}
${BACKEND_REDIST_DEPS}
$<TARGET_FILE_DIR:qasm_simulator>)
install(FILES ${OPENBLAS_DLLs} DESTINATION bin)
install(FILES ${BACKEND_REDIST_DEPS} DESTINATION bin)
endif()
install(TARGETS qasm_simulator DESTINATION bin)

View File

@ -249,7 +249,7 @@ window
$ git clone https://github.com/Qiskit/qiskit-aer
```
- Next, install the platform-specific dependencies for your operating system [Linux](#linux-dependencies) | [macOS](#mac-dependencies) | [Windows](#win-dependencies).
- Next, install the platform-specific dependencies for your operating system [Linux](#linux-dependencies) | [macOS](#mac-dependencies) | [Windows](#win-dependencies).
- The common dependencies can then be installed via *pip*, using the
`requirements-dev.txt` file, e.g.:
@ -258,11 +258,14 @@ window
$ pip install -r requirements-dev.txt
```
This will also install [**Conan**](https://conan.io/), a C/C++ package manager written in Python. This tool will handle
most of the dependencies needed by the C++ source code. Internet connection may be needed for the first build or
when dependencies are added/updated, in order to download the required packages if they are not in your **Conan** local
This will also install [**Conan**](https://conan.io/), a C/C++ package manager written in Python. This tool will handle
most of the dependencies needed by the C++ source code. Internet connection may be needed for the first build or
when dependencies are added/updated, in order to download the required packages if they are not in your **Conan** local
repository.
> Note: Conan use can be disabled with the flag or environment variable ``DISABLE_CONAN=ON`` .
This is useful for building from source offline, or to reuse the installed package dependencies.
If we are only building the standalone version and do not want to install all Python requirements you can just install
**Conan**:
@ -607,7 +610,7 @@ For example,
qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA
If we want to specify the CUDA® architecture instead of letting the build system
If we want to specify the CUDA® architecture instead of letting the build system
auto detect it, we can use the AER_CUDA_ARCH flag (can also be set as an ENV variable
with the same name, although the flag takes precedence). For example:
@ -661,7 +664,7 @@ These are the flags:
Tells CMake the directory to look for the BLAS library instead of the usual paths.
If no BLAS library is found under that directory, CMake will raise an error and stop.
It can also be set as an ENV variable with the same name, although the flag takes precedence.
Values: An absolute path.
@ -700,11 +703,29 @@ These are the flags:
This flag allows us we to specify the CUDA architecture instead of letting the build system auto detect it.
It can also be set as an ENV variable with the same name, although the flag takes precedence.
Values: Auto | Common | All | List of valid CUDA architecture(s).
Default: Auto
Example: ``python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -DAER_CUDA_ARCH="5.2; 5.3"``
* DISABLE_CONAN
This flag allows disabling the Conan package manager. This will force CMake to look for
the libraries in use on your system path, relying on FindPackage CMake mechanism and
the appropriate configuration of libraries in order to use it.
If a specific version is not found, the build system will look for any version available,
although this may produce build errors or incorrect behaviour.
__WARNING__: This is not the official procedure to build AER. Thus, the user is responsible
of providing all needed libraries and corresponding files to make them findable to CMake.
This is also available as the environment variable ``DISABLE_CONAN``, which overrides
the CMake flag of the same name.
Values: ON | OFF
Default: OFF
Example: ``python ./setup.py bdist_wheel -- -DDISABLE_CONAN=ON``
## Tests
Code contribution are expected to include tests that provide coverage for the

View File

@ -1,13 +1,20 @@
include(conan)
macro(_rename_conan_lib package)
add_library(AER_DEPENDENCY_PKG::${package} INTERFACE IMPORTED)
target_link_libraries(AER_DEPENDENCY_PKG::${package} PUBLIC INTERFACE CONAN_PKG::${package})
endmacro()
macro(setup_conan)
# Right now every dependency shall be static
set(CONAN_OPTIONS ${CONAN_OPTIONS} "*:shared=False")
set(REQUIREMENTS nlohmann_json/3.1.1 spdlog/1.5.0)
list(APPEND AER_CONAN_LIBS nlohmann_json spdlog)
if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/8.0.1)
list(APPEND AER_CONAN_LIBS llvm-openmp)
if(SKBUILD)
set(CONAN_OPTIONS ${CONAN_OPTIONS} "llvm-openmp:shared=True")
endif()
@ -15,6 +22,7 @@ macro(setup_conan)
if(SKBUILD)
set(REQUIREMENTS ${REQUIREMENTS} muparserx/4.0.8)
list(APPEND AER_CONAN_LIBS muparserx)
if(NOT MSVC)
set(CONAN_OPTIONS ${CONAN_OPTIONS} "muparserx:fPIC=True")
endif()
@ -22,12 +30,17 @@ macro(setup_conan)
if(AER_THRUST_BACKEND AND NOT AER_THRUST_BACKEND STREQUAL "CUDA")
set(REQUIREMENTS ${REQUIREMENTS} thrust/1.9.5)
list(APPEND AER_CONAN_LIBS thrust)
string(TOLOWER ${AER_THRUST_BACKEND} THRUST_BACKEND)
set(CONAN_OPTIONS ${CONAN_OPTIONS} "thrust:device_system=${THRUST_BACKEND}")
if(THRUST_BACKEND MATCHES "tbb")
list(APPEND AER_CONAN_LIBS tbb)
endif()
endif()
if(BUILD_TESTS)
set(REQUIREMENTS ${REQUIREMENTS} catch2/2.12.1)
list(APPEND AER_CONAN_LIBS catch2)
endif()
# Add Appleclang-12 until officially supported by Conan
@ -40,4 +53,25 @@ macro(setup_conan)
CMAKE_TARGETS
KEEP_RPATHS
BUILD missing)
# Headers includes
if(AER_THRUST_BACKEND AND NOT AER_THRUST_BACKEND STREQUAL "CUDA")
set(AER_SIMULATOR_CPP_EXTERNAL_LIBS ${AER_SIMULATOR_CPP_EXTERNAL_LIBS} ${CONAN_INCLUDE_DIRS_THRUST})
endif()
# Reassign targets from CONAN_PKG to AER_DEPENDENCY_PKG
foreach(CONAN_LIB ${AER_CONAN_LIBS})
_rename_conan_lib(${CONAN_LIB})
endforeach()
if(APPLE)
set(OPENMP_FOUND TRUE)
if(NOT SKBUILD)
set(AER_LIBRARIES ${AER_LIBRARIES} AER_DEPENDENCY_PKG::llvm-openmp)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CONAN_CXX_FLAGS_LLVM-OPENMP}")
set(AER_SIMULATOR_CPP_EXTERNAL_LIBS ${AER_SIMULATOR_CPP_EXTERNAL_LIBS} ${CONAN_INCLUDE_DIRS_LLVM-OPENMP})
set(BACKEND_REDIST_DEPS ${BACKEND_REDIST_DEPS} "${CONAN_LIB_DIRS_LLVM-OPENMP}/libomp.dylib")
endif()
endif()
endmacro()

View File

@ -0,0 +1,64 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
macro(setup_dependencies)
# Defines AER_DEPENDENCY_PKG alias which refers to either conan-provided or system libraries.
if(DISABLE_CONAN)
_use_system_libraries()
else()
include(conan_utils)
setup_conan()
endif()
endmacro()
macro(_use_system_libraries)
# Use system libraries
_import_aer_system_dependency(nlohmann_json 3.1.1)
_import_aer_system_dependency(spdlog 1.5.0)
if(SKBUILD)
_import_aer_system_dependency(muparserx 4.0.8)
endif()
if(AER_THRUST_BACKEND AND NOT AER_THRUST_BACKEND STREQUAL "CUDA")
string(TOLOWER ${AER_THRUST_BACKEND} THRUST_BACKEND)
_import_aer_system_dependency(Thrust 1.9.5)
endif()
if(BUILD_TESTS)
_import_aer_system_dependency(Catch2 2.12.1)
endif()
if(APPLE)
# Fix linking. See https://stackoverflow.com/questions/54068035
link_directories(/usr/local/lib) #brew
link_directories(/opt/local/lib) #ports
endif()
endmacro()
macro(_import_aer_system_dependency package version)
# Arguments:
# package: name of package to search for using find_package()
# version: version of package to search for
find_package(${package} ${version} EXACT QUIET)
if(NOT ${package}_FOUND)
message(STATUS "${package} ${version} NOT found! Looking for any other version available.")
find_package(${package} REQUIRED)
message(STATUS "${package} version found: ${${package}_VERSION}. WARNING: This version may not work!!!")
endif()
string(TOLOWER ${package} PACKAGE_LOWER) # Conan use lowercase for every lib
add_library(AER_DEPENDENCY_PKG::${PACKAGE_LOWER} INTERFACE IMPORTED)
target_link_libraries(AER_DEPENDENCY_PKG::${PACKAGE_LOWER} PUBLIC INTERFACE ${package})
message(STATUS "Using system-provided ${PACKAGE_LOWER} library")
endmacro()

View File

@ -33,8 +33,4 @@ target_compile_definitions(controller_wrappers PRIVATE ${AER_COMPILER_DEFINITION
install(TARGETS controller_wrappers LIBRARY DESTINATION qiskit/providers/aer/backends)
# Install redistributable dependencies
if(APPLE)
install(FILES "${CONAN_LIB_DIRS_LLVM-OPENMP}/libomp.dylib" DESTINATION qiskit/providers/aer/backends)
elseif(WIN32 AND NOT BLAS_LIB_PATH)
install(FILES ${OPENBLAS_DLLs} DESTINATION qiskit/providers/aer/backends)
endif()
install(FILES ${BACKEND_REDIST_DEPS} DESTINATION qiskit/providers/aer/backends)

View File

@ -0,0 +1,9 @@
---
features:
- |
Add the CMake flag ``DISABLE_CONAN`` (default=``OFF``)s. When installing from source,
setting this to ``ON`` allows bypassing the Conan package manager to find libraries
that are already installed on your system. This is also available as an environment
variable ``DISABLE_CONAN``, which takes precedence over the CMake flag.
This is not the official procedure to build AER. Thus, the user is responsible
of providing all needed libraries and corresponding files to make them findable to CMake.

View File

@ -3,13 +3,17 @@
"""
Main setup file for qiskit-aer
"""
import distutils.util
import importlib
import inspect
import os
import setuptools
import subprocess
import sys
import inspect
PACKAGE_NAME = os.getenv('QISKIT_AER_PACKAGE_NAME', 'qiskit-aer')
_DISABLE_CONAN = distutils.util.strtobool(os.getenv("DISABLE_CONAN", "OFF").lower())
try:
from Cython.Build import cythonize
@ -18,11 +22,12 @@ except ImportError:
subprocess.call([sys.executable, '-m', 'pip', 'install', 'Cython>=0.27.1'])
from Cython.Build import cythonize
try:
from conans import client
except ImportError:
subprocess.call([sys.executable, '-m', 'pip', 'install', 'conan'])
from conans import client
if not _DISABLE_CONAN:
try:
from conans import client
except ImportError:
subprocess.call([sys.executable, '-m', 'pip', 'install', 'conan'])
from conans import client
try:
from skbuild import setup
@ -34,7 +39,8 @@ try:
except ImportError:
subprocess.call([sys.executable, '-m', 'pip', 'install', 'pybind11>=2.4'])
import setuptools
from skbuild import setup
# These are requirements that are both runtime/install dependencies and
# also build time/setup requirements and will be added to both lists
@ -52,8 +58,9 @@ common_requirements = [
setup_requirements = common_requirements + [
'scikit-build',
'cmake!=3.17,!=3.17.0',
'conan>=1.22.2'
]
if not _DISABLE_CONAN:
setup_requirements.append('conan>=1.22.2')
requirements = common_requirements + ['qiskit-terra>=0.12.0']

View File

@ -22,7 +22,7 @@
/**
* DISCLAIMER: We want to compile this code in isolation of the rest of the
*codebase, because it contains AVX specific instructions, so is very CPU arch
*dependant. We will detect CPU features at runtime and derive the execution
*dependent. We will detect CPU features at runtime and derive the execution
*path over here if AVX is supported, if it's not supported the QubitVector
*normal class will be used instead (so no SIMD whatsoever). Because of this, we
*don't want to depend on any other library, otherwise the linker could take AVX

View File

@ -8,7 +8,7 @@ macro(add_test_executable target_name)
PRIVATE ${AER_SIMULATOR_CPP_SRC_DIR}
PRIVATE ${AER_SIMULATOR_CPP_EXTERNAL_LIBS})
target_link_libraries(${target_name}
PRIVATE CONAN_PKG::catch2
PRIVATE AER_DEPENDENCY_PKG::catch2
PRIVATE ${AER_LIBRARIES})
add_test(${target_name} ${target_name})
endmacro()