Skip to content

Commit

Permalink
(#7334) armadillo/10.7.0
Browse files Browse the repository at this point in the history
* Add recipe for armadillo 10.6.1

* Add recipe for armadillo to reflect as closely as possible the
  intended usage of the library. This includes the ability to use system
  libraries as backends if manually configured. Default behaviour will
  be to use OpenBLAS as a backend with the wrapper disabled, though this
  can be manually modified.
* Add test program using example code provided by the armadillo project
* Patch armadillo CMakeLists.txt to enable switching between system
  libraries and conan dependencies.

Closes #6754.

* [armadillo] Improve comments wrt fortran requirements

* [armadillo] Add Macos compatability

* Add ARMA_USE_ACCELERATE option, which is set as the default option on
  Macos systems. This removes the dependency on a fortran compiler as this
  provides a BLAS and LAPACK implementation.
* Move opt_dependencies to use a dictionary ordered by the operating
  system. This allows optional dependencies unique to each operating
  system to be managed.
* Ensure that OpenBLAS can only be used when ALLOW_OPENBLAS_MACOS is set
  on Macos
* Ensure that system LAPACK and BLAS libraries can only be used when
  ALLOW_BLAS_LAPACK_MACOS is set on Macos.

* [armadillo] Set ARMA_USE_ACCELERATE to false instead of deleting

* Set ARMA_USE_ACCELERATE to False instead of deleting it when the
  operating system is not Macos. This facilitates proper option
  dependency testing.

* [armadillo] Build without lapack support by default

* Remove default LAPACK support. This will allow armadillo to be made
  available on CCI without waiting for gfortran to be made available as
  a compiler on CI runners.
* Remove version ranges from openblas and hdf5 dependencies.
* Add define guards around logic in example.cpp that requires lapack, so
  those tests aren't run when ARMA_USE_LAPACK isn't defined.

* [armadillo] Build with lapack by default on macos

* Build with lapack by default on macos. Macos ships with the accelerate
  framework which has an implementation of LAPACK, and thus doesn't
  require a fortran compiler to build. This should be used by default
  where available.

* [armadillo] Add MSVC shared library compatability

* Add MSVC shared library compatability by exporting all symbols. This
  enables the creation of a static import library that can be used with
  the resulting .dll.

* Apply suggestions from code review

* Configure test_package to use targets

Co-authored-by: Javier G. Sogo <[email protected]>

* [armadillo] Simplify validation logic

* Condense multiple mutually exclusive options with complex validation
  logic to multiple values for a single option where appropriate. This
  enforces mutual exclusivity by virtue of the fact that an option can
  only have a single value. This will make interpreting valid option
  combinations easier to understand.
* Convert options to lowercase for consistency with other recipes in the
  conan center index.

* Update recipes/armadillo/all/test_package/CMakeLists.txt

* Force C++ language standard to be C++11 to address the insufficient default language standard present with apple-clang

Co-authored-by: Uilian Ries <[email protected]>

* Apply suggestions from code review

* Make co_dependencies protected to avoid name clashes with conan
* Add TODO statements to optional dependencies

Co-authored-by: Uilian Ries <[email protected]>

* [armadillo] Move source modifications to patch file

* Move source modifications from using replace_in_file to using a patch
  file. This will make the recipe more maintainable.
* Remove openblas and hdf5 variable assignment to use the string
  directly when requiring these libraries.
* Move patching process to build() function to preserve downloaded
  source code.

* [armadillo] Add support for versions 10.6.2 and 10.7.0

* Add download links and hashes for versions 10.6.2 and 10.7.0.
* Add patch modification for CMakeLists.txt for version 10.7.0. This
  patch is essentially the same as what's provided for 10.6.x, however
  v10.7.0 introduced a number of additional lines at the beginning of
  this file which cannot be parsed by the patching library used,
  patch_ng.py. This is documented in
  conan-io/python-patch-ng#19.

* [armadillo] Export all symbols on windows

* Export all symbols on shared windows builds so that a static library
  can be generated.
* Remove system_openblas and system_hdf as options to force the conan
  counterparts to be used.

* [armadillo] Remove references to system_openblas and system_hdf5

* Remove lingering references to system_openblas and system_hdf5 as they
  have been removed as options and break the build.

* [armadillo] Remove old versions and clean up

* Remove old versions of armadillo from the recipe
* Move CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS definition to the CMake wrapper
  to avoid polluting library sources
* Add deprecation notice for system library usage
* Remove statements that manually modify the shared option of upstream
  dependencies. This will mean upstream dependencies will always be
  static libraries unless manually specified as shared libraries.
* Clean up CMakeLists patch to remove references to system openblas and
  system hdf5 after removal of these options.

* [armadillo] Update required version for CMake in CMake wrapper

* Update required CMake version from 2.8.11 to 3.4 for CMakeLists
  wrapper. This is a requirement of CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.

* [armadillo] Add dummy intel_mkl option to be overridden by consumer

* Add intel_mkl option to allow intel-mkl requirement to be overridden
  with a user specified recipe. This addresses the issue where CCI won't
  package closed source libraries.

* [armadillo] Remove system_mkl as an option

* Remove system_mkl as an option as intel_mkl has been added and users
  now have an ability to add their own recipes for closed source
  projects.

* Add validation logic for cppstd

* Only conduct cppstd validation logic if passed as a conan setting

Co-authored-by: Uilian Ries <[email protected]>

Co-authored-by: Javier G. Sogo <[email protected]>
Co-authored-by: Uilian Ries <[email protected]>
  • Loading branch information
3 people authored Oct 25, 2021
1 parent b22c0a5 commit 8e7b69a
Show file tree
Hide file tree
Showing 8 changed files with 663 additions and 0 deletions.
8 changes: 8 additions & 0 deletions recipes/armadillo/all/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.4)
project(cmake_wrapper)

include(conanbuildinfo.cmake)
conan_basic_setup()
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on)

add_subdirectory("source_subfolder")
9 changes: 9 additions & 0 deletions recipes/armadillo/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sources:
"10.7.0":
url: "http://sourceforge.net/projects/arma/files/armadillo-10.7.0.tar.xz"
sha256: "9bf60db6fd237721908747a0e56797b97b7ceae3603f2cca0b012a3b88265d3f"

patches:
"10.7.0":
- patch_file: "patches/0001-Guard-dependency-discovery-10.7.x.patch"
base_path: "source_subfolder"
321 changes: 321 additions & 0 deletions recipes/armadillo/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
from conans import ConanFile, CMake, tools
from conans.errors import ConanInvalidConfiguration
import os


class ArmadilloConan(ConanFile):
name = "armadillo"
license = "Apache-2.0"
url = "https://github.com/conan-io/conan-center-index"
homepage = "http://arma.sourceforge.net"
description = "Armadillo is a high quality C++ library for linear algebra and scientific computing, aiming towards a good balance between speed and ease of use."
topics = (
"linear algebra",
"scientific computing",
"matrix",
"vector",
"math",
"blas",
"lapack",
"mkl",
"hdf5",
)
settings = "os", "compiler", "build_type", "arch"
options = {
"shared": [True, False],
"fPIC": [True, False],
"use_blas": [
False,
"openblas",
"intel_mkl",
"system_blas",
"system_flexiblas",
"framework_accelerate",
],
"use_lapack": [
False,
"openblas",
"intel_mkl",
"system_lapack",
"system_atlas",
"framework_accelerate",
],
"use_hdf5": [True, False],
"use_superlu": [False, "system_superlu"],
"use_extern_rng": [True, False],
"use_arpack": [False, "system_arpack"],
"use_wrapper": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"use_blas": "openblas",
"use_lapack": False,
"use_hdf5": True,
"use_superlu": False,
"use_extern_rng": False,
"use_arpack": False,
"use_wrapper": False,
}
# Values that must be set for multiple options to be valid
_co_dependencies = {
"intel_mkl": [
"use_blas",
"use_lapack",
],
"framework_accelerate": [
"use_blas",
"use_lapack",
],
}
exports_sources = ["CMakeLists.txt", "patches/*"]
generators = (
"cmake",
"cmake_find_package",
)
_cmake = None

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _build_subfolder(self):
return "build_subfolder"

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
if self.settings.os == "Macos":
# Macos will default to Accelerate framework
self.options.use_blas = "framework_accelerate"
self.options.use_lapack = "framework_accelerate"

def configure(self):
if self.options.shared:
del self.options.fPIC

def validate(self):
if self.settings.compiler.cppstd:
tools.check_min_cppstd(self, "11")

if self.settings.os != "Macos" and (
self.options.use_blas == "framework_accelerate"
or self.options.use_lapack == "framework_accelerate"
):
raise ConanInvalidConfiguration(
"framework_accelerate can only be used on Macos"
)

for value, options in self._co_dependencies.items():
options_without_value = [
x for x in options if getattr(self.options, x) != value
]
if options_without_value and (len(options) != len(options_without_value)):
raise ConanInvalidConfiguration(
"Options {} must all be set to '{}' to use this feature. To fix this, set option {} to '{}'.".format(
", ".join(options),
value,
", ".join(options_without_value),
value,
)
)

if (
self.options.use_lapack == "openblas"
and self.options.use_blas != "openblas"
):
raise ConanInvalidConfiguration(
"OpenBLAS can only provide LAPACK functionality when also providing BLAS functionality. Set use_blas=openblas and try again."
)

deprecated_opts = list(
set(
[
opt
for opt in [
str(self.options.use_blas),
str(self.options.use_lapack),
]
if "system" in opt
]
)
)

for opt in deprecated_opts:
self.output.warn(
f"DEPRECATION NOTICE: Value {opt} uses armadillo's default dependency search and will be replaced when this package becomes available in ConanCenter"
)

def requirements(self):
# Optional requirements
# TODO: "atlas/3.10.3" # Pending https://github.com/conan-io/conan-center-index/issues/6757
# TODO: "superlu/5.2.2" # Pending https://github.com/conan-io/conan-center-index/issues/6756
# TODO: "arpack/1.0" # Pending https://github.com/conan-io/conan-center-index/issues/6755
# TODO: "flexiblas/3.0.4" # Pending https://github.com/conan-io/conan-center-index/issues/6827

if self.options.use_hdf5:
# Use the conan dependency if the system lib isn't being used
self.requires("hdf5/1.12.0")

if self.options.use_blas == "openblas":
self.requires("openblas/0.3.15")
# Note that if you're relying on this to build LAPACK, you _must_ have
# a fortran compiler installed. If you don't, OpenBLAS will build successfully but
# without LAPACK support, which isn't obvious.
# This can be achieved by setting the FC environment variable in your conan profile
self.options["openblas"].build_lapack = (
self.options.use_lapack == "openblas"
)
if (
self.options.use_blas == "intel_mkl"
and self.options.use_lapack == "intel_mkl"
):
# Consumers can override this requirement with their own by using
# self.requires("intel-mkl/version@user/channel, override=True) in their consumer
# conanfile.py
if (
self.options.use_blas == "intel_mkl"
or self.options.use_lapack == "intel_mkl"
):
self.output.warn(
"The intel-mkl package does not exist in CCI. To use an Intel MKL package, override this requirement with your own recipe."
)
self.requires("intel-mkl/2021.4")

def _configure_cmake(self):
if self._cmake:
return self._cmake
self._cmake = CMake(self)
self._cmake.definitions["ARMA_USE_LAPACK"] = self.options.use_lapack
self._cmake.definitions["ARMA_USE_BLAS"] = self.options.use_blas
self._cmake.definitions["ARMA_USE_ATLAS"] = (
self.options.use_lapack == "system_atlas"
)
self._cmake.definitions["ARMA_USE_HDF5"] = self.options.use_hdf5
self._cmake.definitions["ARMA_USE_ARPACK"] = self.options.use_arpack
self._cmake.definitions["ARMA_USE_EXTERN_RNG"] = self.options.use_extern_rng
self._cmake.definitions["ARMA_USE_SUPERLU"] = self.options.use_superlu
self._cmake.definitions["ARMA_USE_WRAPPER"] = self.options.use_wrapper
self._cmake.definitions["ARMA_USE_ACCELERATE"] = (
self.options.use_blas == "framework_accelerate"
or self.options.use_lapack == "framework_accelerate"
) and self.settings.os == "Macos"
self._cmake.definitions["DETECT_HDF5"] = self.options.use_hdf5
self._cmake.definitions["USE_OPENBLAS"] = self.options.use_blas == "openblas"
self._cmake.definitions["USE_MKL"] = (
self.options.use_blas == "intel_mkl"
and self.options.use_lapack == "intel_mkl"
)
self._cmake.definitions["USE_SYSTEM_LAPACK"] = (
self.options.use_lapack == "system_lapack"
)
self._cmake.definitions["USE_SYSTEM_BLAS"] = (
self.options.use_blas == "system_blas"
)
self._cmake.definitions["USE_SYSTEM_ATLAS"] = (
self.options.use_lapack == "system_atlas"
)
self._cmake.definitions["USE_SYSTEM_HDF5"] = False
self._cmake.definitions["USE_SYSTEM_ARPACK"] = self.options.use_arpack
self._cmake.definitions["USE_SYSTEM_SUPERLU"] = self.options.use_superlu
self._cmake.definitions["USE_SYSTEM_OPENBLAS"] = False
self._cmake.definitions["USE_SYSTEM_FLEXIBLAS"] = (
self.options.use_blas == "system_flexiblas"
)
self._cmake.definitions["ALLOW_FLEXIBLAS_LINUX"] = (
self.options.use_blas == "system_flexiblas" and self.settings.os == "Linux"
)
self._cmake.definitions["ALLOW_OPENBLAS_MACOS"] = (
self.options.use_blas == "openblas"
) and self.settings.os == "Macos"
self._cmake.definitions["ALLOW_BLAS_LAPACK_MACOS"] = (
self.options.use_blas != "framework_accelerate"
)
self._cmake.definitions["BUILD_SHARED_LIBS"] = self.options.shared
self._cmake.configure(build_folder=self._build_subfolder)
return self._cmake

def source(self):
tools.get(
**self.conan_data["sources"][self.version],
strip_root=True,
destination=self._source_subfolder,
filename="{name}-{version}.tar.xz".format(
name=self.name, version=self.version
),
)

def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)

def build(self):
self._patch_sources()
cmake = self._configure_cmake()
cmake.build()

def package(self):
self.copy("LICENSE.txt", dst="licenses", src=self._source_subfolder)
self.copy("NOTICE.txt", dst="licenses", src=self._source_subfolder)
cmake = self._configure_cmake()
cmake.install()
tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
tools.rmdir(os.path.join(self.package_folder, "share"))

def package_info(self):
self.cpp_info.libs = ["armadillo"]
self.cpp_info.names["pkg_config"] = "armadillo"

if self.settings.build_type == "Release":
self.cpp_info.defines.append("ARMA_NO_DEBUG")

# The wrapper library links everything together. If disabled, system libs must be
# linked manually
if not self.options.use_wrapper:
self.cpp_info.defines.append("ARMA_DONT_USE_WRAPPER")
if self.options.use_blas == "framework_accelerate":
self.cpp_info.frameworks.append("Accelerate")

if self.options.use_hdf5:
self.cpp_info.defines.append("ARMA_USE_HDF5")
else:
self.cpp_info.defines.append("ARMA_DONT_USE_HDF5")

if self.options.use_blas:
self.cpp_info.defines.append("ARMA_USE_BLAS")
if self.options.use_blas == "system_blas" and not self.options.use_wrapper:
self.cpp_info.system_libs.extend(["blas"])
else:
self.cpp_info.defines.append("ARMA_DONT_USE_BLAS")

if self.options.use_lapack:
self.cpp_info.defines.append("ARMA_USE_LAPACK")
if (
self.options.use_lapack == "system_lapack"
and not self.options.use_wrapper
):
self.cpp_info.system_libs.extend(["lapack"])
else:
self.cpp_info.defines.append("ARMA_DONT_USE_LAPACK")

if self.options.use_arpack:
self.cpp_info.defines.append("ARMA_USE_ARPACK")
if not self.options.use_wrapper:
self.cpp_info.system_libs.extend(["arpack"])
else:
self.cpp_info.defines.append("ARMA_DONT_USE_ARPACK")

if self.options.use_superlu:
self.cpp_info.defines.append("ARMA_USE_SUPERLU")
if not self.options.use_wrapper:
self.cpp_info.system_libs.extend(["superlu"])
else:
self.cpp_info.defines.append("ARMA_DONT_USE_SUPERLU")

if self.options.use_lapack == "system_atlas":
self.cpp_info.defines.append("ARMA_USE_ATLAS")
if not self.options.use_wrapper:
self.cpp_info.system_libs.extend(["atlas"])
else:
self.cpp_info.defines.append("ARMA_DONT_USE_ATLAS")
Loading

0 comments on commit 8e7b69a

Please sign in to comment.