Skip to content

Commit

Permalink
Cmake: make conan optional (#999)
Browse files Browse the repository at this point in the history
Co-authored-by: Drew Risinger <[email protected]>
  • Loading branch information
vvilpas and drewrisinger authored Nov 4, 2020
1 parent d3b927a commit 721fcb4
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 48 deletions.
61 changes: 36 additions & 25 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down Expand Up @@ -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}")
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
35 changes: 28 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.:
Expand All @@ -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**:

Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
34 changes: 34 additions & 0 deletions cmake/conan_utils.cmake
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
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()
endif()

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()
endif()

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
Expand All @@ -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()
64 changes: 64 additions & 0 deletions cmake/dependency_utils.cmake
Original file line number Diff line number Diff line change
@@ -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()
6 changes: 1 addition & 5 deletions qiskit/providers/aer/backends/wrappers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
9 changes: 9 additions & 0 deletions releasenotes/notes/cmake-optional-conan-bc99a895fc4345e1.yaml
Original file line number Diff line number Diff line change
@@ -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.
Loading

0 comments on commit 721fcb4

Please sign in to comment.