From 621bd19d43b3a6b0baeb49cf80c29ec36e4d3204 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 9 Apr 2022 01:26:32 +0200 Subject: [PATCH 01/48] Enable to get dependencies through conan. Update cmake to 3.15 and modern python3 modules --- CMakeLists.txt | 39 +- cmake/FindEigen3.cmake | 107 ----- cmake/FindNumPy.cmake | 72 ---- cmake/conan.cmake | 909 +++++++++++++++++++++++++++++++++++++++++ python/CMakeLists.txt | 8 +- tests/CMakeLists.txt | 1 + 6 files changed, 946 insertions(+), 190 deletions(-) delete mode 100644 cmake/FindEigen3.cmake delete mode 100644 cmake/FindNumPy.cmake create mode 100644 cmake/conan.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a38212b..6bd6d374 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.1) +cmake_minimum_required (VERSION 3.15) project (libcmaes VERSION 0.10 LANGUAGES C CXX) @@ -24,6 +24,7 @@ option (LIBCMAES_BUILD_TESTS "build tests" OFF) option (LIBCMAES_BUILD_EXAMPLES "build examples" ${LIBCMAES_TOP_LEVEL}) option (LIBCMAES_USE_OPENMP "Use OpenMP for multithreading" ON) option (LIBCMAES_ENABLE_SURROG "support for surrogates" ON) +option (LIBCMAES_USE_CONAN "Use conan to get the dependencies" OFF) # Offer the user the choice of overriding the installation directories set (INSTALL_LIB_DIR lib${LIB_SUFFIX} @@ -63,6 +64,32 @@ check_include_file (sys/types.h HAVE_SYS_TYPES_H) check_include_file (sys/stat.h HAVE_SYS_STAT_H) # ---------- dependencies ---------- + +if(LIBCMAES_USE_CONAN) + include(conan) + set(ConanPkgList eigen/3.4.0) + if(LIBCMAES_BUILD_PYTHON) + set(ConanPkgList ${ConanPkgList} + boost/1.78.0 + ) + endif(LIBCMAES_BUILD_PYTHON) + + if(LIBCMAES_BUILD_TESTS) + set(ConanPkgList ${ConanPkgList} gflags/2.2.2) + endif(LIBCMAES_BUILD_TESTS) + + conan_cmake_configure(REQUIRES ${ConanPkgList} + GENERATORS cmake_find_package) + + + conan_cmake_autodetect(settings) + + conan_cmake_install(PATH_OR_REFERENCE . + BUILD missing + REMOTE conancenter + SETTINGS ${settings}) +endif() + find_package (Eigen3 3.0.0 REQUIRED) if (LIBCMAES_USE_OPENMP) @@ -79,8 +106,7 @@ if (LIBCMAES_USE_OPENMP) endif () if (LIBCMAES_BUILD_PYTHON) - find_package (PythonInterp) - find_package (PythonLibs) + find_package (Python3 COMPONENTS Interpreter Development NumPy) if (NOT TARGET Python::Module AND PYTHONLIBS_FOUND) add_library (Python::Module SHARED IMPORTED) set_target_properties ( @@ -89,7 +115,7 @@ if (LIBCMAES_BUILD_PYTHON) INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS}) endif () - find_package (NumPy) + #find_package (NumPy) # python site dir if (PYTHON_EXECUTABLE AND NOT DEFINED PYTHON_SITE_PACKAGES) @@ -163,11 +189,11 @@ if (LIBCMAES_BUILD_EXAMPLES) add_subdirectory (examples) endif () if (LIBCMAES_BUILD_TESTS) - enable_testing () + include(CTest) add_subdirectory (tests) endif () -if (Boost_FOUND AND NumPy_FOUND) +if (Boost_FOUND AND Python3_NumPy_FOUND) add_subdirectory (python) endif () @@ -192,5 +218,4 @@ configure_file (libcmaesConfig.cmake.in libcmaesConfig.cmake @ONLY) install ( FILES "${CMAKE_CURRENT_BINARY_DIR}/libcmaesConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/libcmaesConfigVersion.cmake" - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindEigen3.cmake" DESTINATION ${RELATIVE_INSTALL_CMAKE_DIR}) diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake deleted file mode 100644 index 2dbed583..00000000 --- a/cmake/FindEigen3.cmake +++ /dev/null @@ -1,107 +0,0 @@ -# - Try to find Eigen3 lib -# -# This module supports requiring a minimum version, e.g. you can do -# find_package(Eigen3 3.1.2) -# to require version 3.1.2 or newer of Eigen3. -# -# Once done this will define -# -# EIGEN3_FOUND - system has eigen lib with correct version -# EIGEN3_INCLUDE_DIR - the eigen include directory -# EIGEN3_VERSION - eigen version -# -# and the following imported target: -# -# Eigen3::Eigen - The header-only Eigen library -# -# This module reads hints about search locations from -# the following environment variables: -# -# EIGEN3_ROOT -# EIGEN3_ROOT_DIR - -# Copyright (c) 2006, 2007 Montel Laurent, -# Copyright (c) 2008, 2009 Gael Guennebaud, -# Copyright (c) 2009 Benoit Jacob -# Redistribution and use is allowed according to the terms of the 2-clause BSD license. - -if(NOT Eigen3_FIND_VERSION) - if(NOT Eigen3_FIND_VERSION_MAJOR) - set(Eigen3_FIND_VERSION_MAJOR 2) - endif() - if(NOT Eigen3_FIND_VERSION_MINOR) - set(Eigen3_FIND_VERSION_MINOR 91) - endif() - if(NOT Eigen3_FIND_VERSION_PATCH) - set(Eigen3_FIND_VERSION_PATCH 0) - endif() - - set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") -endif() - -macro(_eigen3_check_version) - file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) - - string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") - set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") - set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") - set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") - - set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) - if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - set(EIGEN3_VERSION_OK FALSE) - else() - set(EIGEN3_VERSION_OK TRUE) - endif() - - if(NOT EIGEN3_VERSION_OK) - - message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " - "but at least version ${Eigen3_FIND_VERSION} is required") - endif() -endmacro() - -if (EIGEN3_INCLUDE_DIR) - - # in cache already - _eigen3_check_version() - set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) - set(Eigen3_FOUND ${EIGEN3_VERSION_OK}) - -else () - - # search first if an Eigen3Config.cmake is available in the system, - # if successful this would set EIGEN3_INCLUDE_DIR and the rest of - # the script will work as usual - find_package(Eigen3 ${Eigen3_FIND_VERSION} NO_MODULE QUIET) - - if(NOT EIGEN3_INCLUDE_DIR) - find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library - HINTS - ENV EIGEN3_ROOT - ENV EIGEN3_ROOT_DIR - PATHS - ${CMAKE_INSTALL_PREFIX}/include - ${KDE4_INCLUDE_DIR} - PATH_SUFFIXES eigen3 eigen - ) - endif() - - if(EIGEN3_INCLUDE_DIR) - _eigen3_check_version() - endif() - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) - - mark_as_advanced(EIGEN3_INCLUDE_DIR) - -endif() - -if(EIGEN3_FOUND AND NOT TARGET Eigen3::Eigen) - add_library(Eigen3::Eigen INTERFACE IMPORTED) - set_target_properties(Eigen3::Eigen PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${EIGEN3_INCLUDE_DIR}") -endif() diff --git a/cmake/FindNumPy.cmake b/cmake/FindNumPy.cmake deleted file mode 100644 index d25d1f34..00000000 --- a/cmake/FindNumPy.cmake +++ /dev/null @@ -1,72 +0,0 @@ -# This module finds NumPy if it is installed, and sets the following variables -# indicating where it is. -# -# * NUMPY_FOUND - was NumPy found -# * NUMPY_VERSION - the version of NumPy found as a string -# * NUMPY_INCLUDE_DIRS - path to the NumPy include files -# -# Additionally the imported target -# -# * Python::NumPy -# -# is defined. - -# Finding NumPy involves calling the Python interpreter -if (NumPy_FIND_REQUIRED) - find_package (PythonInterp REQUIRED) -else () - find_package (PythonInterp ${NumPy_FIND_REQUIRED}) -endif () - -if (PYTHONINTERP_FOUND) - execute_process ( - COMMAND ${PYTHON_EXECUTABLE} -c "import numpy as n; print(n.__version__)" - RESULT_VARIABLE NumPy_VERSION_ERROR - OUTPUT_VARIABLE NumPy_VERSION_STRING - ERROR_VARIABLE NumPy_VERSION_ERROR_OUTPUT - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - execute_process ( - COMMAND ${PYTHON_EXECUTABLE} -c "import numpy as n; print(n.get_include())" - RESULT_VARIABLE NumPy_INCLUDE_ERROR - OUTPUT_VARIABLE NumPy_INCLUDE_DIRS - ERROR_VARIABLE NumPy_INCLUDE_ERROR_OUTPUT - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - if (NOT NumPy_VERSION_ERROR) - string (REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" NumPy_VERSION - ${NumPy_VERSION_STRING} - ) - if ("${NumPy_VERSION}" STREQUAL "") - set (NumPy_VERSION_ERROR YES) - endif () - endif () - - if (NOT NumPy_INCLUDE_ERROR) # canonicalize paths - get_filename_component (NumPy_INCLUDE_DIRS ${NumPy_INCLUDE_DIRS} ABSOLUTE) - endif () - - if (NOT NumPy_VERSION_ERROR AND NOT NumPy_INCLUDE_ERROR) - set (NumPy_FIND_SUCCESS TRUE) - endif () -endif () - -include (FindPackageHandleStandardArgs) -find_package_handle_standard_args ( - NumPy - FOUND_VAR - NumPy_FOUND - REQUIRED_VARS - NumPy_INCLUDE_DIRS - NumPy_FIND_SUCCESS - VERSION_VAR - NumPy_VERSION -) - -if (NumPy_FOUND AND NOT TARGET Python::NumPy) - add_library (Python::NumPy INTERFACE IMPORTED) - set_target_properties (Python::NumPy PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - ${NumPy_INCLUDE_DIRS}) -endif () diff --git a/cmake/conan.cmake b/cmake/conan.cmake new file mode 100644 index 00000000..208ce248 --- /dev/null +++ b/cmake/conan.cmake @@ -0,0 +1,909 @@ +# The MIT License (MIT) + +# Copyright (c) 2018 JFrog + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + + +# This file comes from: https://github.com/conan-io/cmake-conan. Please refer +# to this repository for issues and documentation. + +# Its purpose is to wrap and launch Conan C/C++ Package Manager when cmake is called. +# It will take CMake current settings (os, compiler, compiler version, architecture) +# and translate them to conan settings for installing and retrieving dependencies. + +# It is intended to facilitate developers building projects that have conan dependencies, +# but it is only necessary on the end-user side. It is not necessary to create conan +# packages, in fact it shouldn't be use for that. Check the project documentation. + +# version: 0.18.0-dev + +include(CMakeParseArguments) + +function(_get_msvc_ide_version result) + set(${result} "" PARENT_SCOPE) + if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500) + set(${result} 8 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600) + set(${result} 9 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700) + set(${result} 10 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800) + set(${result} 11 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900) + set(${result} 12 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 1910) + set(${result} 14 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1910 AND MSVC_VERSION VERSION_LESS 1920) + set(${result} 15 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) + set(${result} 16 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940) + set(${result} 17 PARENT_SCOPE) + else() + message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") + endif() +endfunction() + +macro(_conan_detect_build_type) + conan_parse_arguments(${ARGV}) + + if(ARGUMENTS_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${ARGUMENTS_BUILD_TYPE}) + elseif(CMAKE_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${CMAKE_BUILD_TYPE}) + else() + message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") + endif() + + string(TOUPPER ${_CONAN_SETTING_BUILD_TYPE} _CONAN_SETTING_BUILD_TYPE_UPPER) + if (_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "DEBUG") + set(_CONAN_SETTING_BUILD_TYPE "Debug") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELEASE") + set(_CONAN_SETTING_BUILD_TYPE "Release") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELWITHDEBINFO") + set(_CONAN_SETTING_BUILD_TYPE "RelWithDebInfo") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "MINSIZEREL") + set(_CONAN_SETTING_BUILD_TYPE "MinSizeRel") + endif() +endmacro() + +macro(_conan_check_system_name) + #handle -s os setting + if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") + #use default conan os setting if CMAKE_SYSTEM_NAME is not defined + set(CONAN_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(CONAN_SYSTEM_NAME Macos) + endif() + if(${CMAKE_SYSTEM_NAME} STREQUAL "QNX") + set(CONAN_SYSTEM_NAME Neutrino) + endif() + set(CONAN_SUPPORTED_PLATFORMS Windows Linux Macos Android iOS FreeBSD WindowsStore WindowsCE watchOS tvOS FreeBSD SunOS AIX Arduino Emscripten Neutrino) + list (FIND CONAN_SUPPORTED_PLATFORMS "${CONAN_SYSTEM_NAME}" _index) + if (${_index} GREATER -1) + #check if the cmake system is a conan supported one + set(_CONAN_SETTING_OS ${CONAN_SYSTEM_NAME}) + else() + message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}") + endif() + endif() +endmacro() + +macro(_conan_check_language) + get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (";${_languages};" MATCHES ";CXX;") + set(LANGUAGE CXX) + set(USING_CXX 1) + elseif (";${_languages};" MATCHES ";C;") + set(LANGUAGE C) + set(USING_CXX 0) + else () + message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") + endif() +endmacro() + +macro(_conan_detect_compiler) + + conan_parse_arguments(${ARGV}) + + if(ARGUMENTS_ARCH) + set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH}) + endif() + + if(USING_CXX) + set(_CONAN_SETTING_COMPILER_CPPSTD ${CMAKE_CXX_STANDARD}) + endif() + + if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) + # using GCC + # TODO: Handle other params + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(COMPILER_VERSION ${MAJOR}.${MINOR}) + if(${MAJOR} GREATER 4) + set(COMPILER_VERSION ${MAJOR}) + endif() + set(_CONAN_SETTING_COMPILER gcc) + set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Intel) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(COMPILER_VERSION ${MAJOR}.${MINOR}) + set(_CONAN_SETTING_COMPILER intel) + set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) + # using AppleClang + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(_CONAN_SETTING_COMPILER apple-clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(_CONAN_SETTING_COMPILER clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + if(APPLE) + cmake_policy(GET CMP0025 APPLE_CLANG_POLICY) + if(NOT APPLE_CLANG_POLICY STREQUAL NEW) + message(STATUS "Conan: APPLE and Clang detected. Assuming apple-clang compiler. Set CMP0025 to avoid it") + set(_CONAN_SETTING_COMPILER apple-clang) + endif() + endif() + if(${_CONAN_SETTING_COMPILER} STREQUAL clang AND ${MAJOR} GREATER 7) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}) + endif() + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) + set(_VISUAL "Visual Studio") + _get_msvc_ide_version(_VISUAL_VERSION) + if("${_VISUAL_VERSION}" STREQUAL "") + message(FATAL_ERROR "Conan: Visual Studio not recognized") + else() + set(_CONAN_SETTING_COMPILER ${_VISUAL}) + set(_CONAN_SETTING_COMPILER_VERSION ${_VISUAL_VERSION}) + endif() + + if(NOT _CONAN_SETTING_ARCH) + if (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "64") + set(_CONAN_SETTING_ARCH x86_64) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "^ARM") + message(STATUS "Conan: Using default ARM architecture from MSVC") + set(_CONAN_SETTING_ARCH armv6) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "86") + set(_CONAN_SETTING_ARCH x86) + else () + message(FATAL_ERROR "Conan: Unknown MSVC architecture [${MSVC_${LANGUAGE}_ARCHITECTURE_ID}]") + endif() + endif() + + conan_cmake_detect_vs_runtime(_vs_runtime ${ARGV}) + message(STATUS "Conan: Detected VS runtime: ${_vs_runtime}") + set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime}) + + if (CMAKE_GENERATOR_TOOLSET) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + elseif(CMAKE_VS_PLATFORM_TOOLSET AND (CMAKE_GENERATOR STREQUAL "Ninja")) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + endif() + else() + message(FATAL_ERROR "Conan: compiler setup not recognized") + endif() + +endmacro() + +function(conan_cmake_settings result) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER}) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID}) + #message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION}) + #message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS}) + #message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE}) + #message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE}) + #message(STATUS "GENERATOR " ${CMAKE_GENERATOR}) + #message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64}) + + message(STATUS "Conan: Automatic detection of conan settings from cmake") + + conan_parse_arguments(${ARGV}) + + _conan_detect_build_type(${ARGV}) + + _conan_check_system_name() + + _conan_check_language() + + _conan_detect_compiler(${ARGV}) + + # If profile is defined it is used + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_DEBUG_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "Release" AND ARGUMENTS_RELEASE_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_RELEASE_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND ARGUMENTS_RELWITHDEBINFO_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_RELWITHDEBINFO_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" AND ARGUMENTS_MINSIZEREL_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_MINSIZEREL_PROFILE}) + elseif(ARGUMENTS_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_PROFILE}) + endif() + + foreach(ARG ${_APPLIED_PROFILES}) + set(_SETTINGS ${_SETTINGS} -pr=${ARG}) + endforeach() + foreach(ARG ${ARGUMENTS_PROFILE_BUILD}) + conan_check(VERSION 1.24.0 REQUIRED DETECT_QUIET) + set(_SETTINGS ${_SETTINGS} -pr:b=${ARG}) + endforeach() + + if(NOT _SETTINGS OR ARGUMENTS_PROFILE_AUTO STREQUAL "ALL") + set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version + compiler.runtime compiler.libcxx compiler.toolset) + endif() + + # remove any manually specified settings from the autodetected settings + foreach(ARG ${ARGUMENTS_SETTINGS}) + string(REGEX MATCH "[^=]*" MANUAL_SETTING "${ARG}") + message(STATUS "Conan: ${MANUAL_SETTING} was added as an argument. Not using the autodetected one.") + list(REMOVE_ITEM ARGUMENTS_PROFILE_AUTO "${MANUAL_SETTING}") + endforeach() + + # Automatic from CMake + foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) + string(TOUPPER ${ARG} _arg_name) + string(REPLACE "." "_" _arg_name ${_arg_name}) + if(_CONAN_SETTING_${_arg_name}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}=${_CONAN_SETTING_${_arg_name}}) + endif() + endforeach() + + foreach(ARG ${ARGUMENTS_SETTINGS}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}) + endforeach() + + message(STATUS "Conan: Settings= ${_SETTINGS}") + + set(${result} ${_SETTINGS} PARENT_SCOPE) +endfunction() + + +function(conan_cmake_detect_unix_libcxx result) + # Take into account any -stdlib in compile options + get_directory_property(compile_options DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS) + string(GENEX_STRIP "${compile_options}" compile_options) + + # Take into account any _GLIBCXX_USE_CXX11_ABI in compile definitions + get_directory_property(defines DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS) + string(GENEX_STRIP "${defines}" defines) + + foreach(define ${defines}) + if(define MATCHES "_GLIBCXX_USE_CXX11_ABI") + if(define MATCHES "^-D") + set(compile_options ${compile_options} "${define}") + else() + set(compile_options ${compile_options} "-D${define}") + endif() + endif() + endforeach() + + # add additional compiler options ala cmRulePlaceholderExpander::ExpandRuleVariable + set(EXPAND_CXX_COMPILER ${CMAKE_CXX_COMPILER}) + if(CMAKE_CXX_COMPILER_ARG1) + # CMake splits CXX="foo bar baz" into CMAKE_CXX_COMPILER="foo", CMAKE_CXX_COMPILER_ARG1="bar baz" + # without this, ccache, winegcc, or other wrappers might lose all their arguments + separate_arguments(SPLIT_CXX_COMPILER_ARG1 NATIVE_COMMAND ${CMAKE_CXX_COMPILER_ARG1}) + list(APPEND EXPAND_CXX_COMPILER ${SPLIT_CXX_COMPILER_ARG1}) + endif() + + if(CMAKE_CXX_COMPILE_OPTIONS_TARGET AND CMAKE_CXX_COMPILER_TARGET) + # without --target= we may be calling the wrong underlying GCC + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_TARGET}${CMAKE_CXX_COMPILER_TARGET}") + endif() + + if(CMAKE_CXX_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN AND CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN) + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN}${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}") + endif() + + if(CMAKE_CXX_COMPILE_OPTIONS_SYSROOT) + # without --sysroot= we may find the wrong #include + if(CMAKE_SYSROOT_COMPILE) + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_SYSROOT}${CMAKE_SYSROOT_COMPILE}") + elseif(CMAKE_SYSROOT) + list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_SYSROOT}${CMAKE_SYSROOT}") + endif() + endif() + + separate_arguments(SPLIT_CXX_FLAGS NATIVE_COMMAND ${CMAKE_CXX_FLAGS}) + + if(CMAKE_OSX_SYSROOT) + set(xcode_sysroot_option "--sysroot=${CMAKE_OSX_SYSROOT}") + endif() + + execute_process( + COMMAND ${CMAKE_COMMAND} -E echo "#include " + COMMAND ${EXPAND_CXX_COMPILER} ${SPLIT_CXX_FLAGS} -x c++ ${xcode_sysroot_option} ${compile_options} -E -dM - + OUTPUT_VARIABLE string_defines + ) + + if(string_defines MATCHES "#define __GLIBCXX__") + # Allow -D_GLIBCXX_USE_CXX11_ABI=ON/OFF as argument to cmake + if(DEFINED _GLIBCXX_USE_CXX11_ABI) + if(_GLIBCXX_USE_CXX11_ABI) + set(${result} libstdc++11 PARENT_SCOPE) + return() + else() + set(${result} libstdc++ PARENT_SCOPE) + return() + endif() + endif() + + if(string_defines MATCHES "#define _GLIBCXX_USE_CXX11_ABI 1\n") + set(${result} libstdc++11 PARENT_SCOPE) + else() + # Either the compiler is missing the define because it is old, and so + # it can't use the new abi, or the compiler was configured to use the + # old abi by the user or distro (e.g. devtoolset on RHEL/CentOS) + set(${result} libstdc++ PARENT_SCOPE) + endif() + else() + set(${result} libc++ PARENT_SCOPE) + endif() +endfunction() + +function(conan_cmake_detect_vs_runtime result) + + conan_parse_arguments(${ARGV}) + if(ARGUMENTS_BUILD_TYPE) + set(build_type "${ARGUMENTS_BUILD_TYPE}") + elseif(CMAKE_BUILD_TYPE) + set(build_type "${CMAKE_BUILD_TYPE}") + else() + message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") + endif() + + if(build_type) + string(TOUPPER "${build_type}" build_type) + endif() + set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS) + foreach(variable ${variables}) + if(NOT "${${variable}}" STREQUAL "") + string(REPLACE " " ";" flags "${${variable}}") + foreach (flag ${flags}) + if("${flag}" STREQUAL "/MD" OR "${flag}" STREQUAL "/MDd" OR "${flag}" STREQUAL "/MT" OR "${flag}" STREQUAL "/MTd") + string(SUBSTRING "${flag}" 1 -1 runtime) + set(${result} "${runtime}" PARENT_SCOPE) + return() + endif() + endforeach() + endif() + endforeach() + if("${build_type}" STREQUAL "DEBUG") + set(${result} "MDd" PARENT_SCOPE) + else() + set(${result} "MD" PARENT_SCOPE) + endif() +endfunction() + +function(_collect_settings result) + set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version + compiler.runtime compiler.libcxx compiler.toolset + compiler.cppstd) + foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) + string(TOUPPER ${ARG} _arg_name) + string(REPLACE "." "_" _arg_name ${_arg_name}) + if(_CONAN_SETTING_${_arg_name}) + set(detected_setings ${detected_setings} ${ARG}=${_CONAN_SETTING_${_arg_name}}) + endif() + endforeach() + set(${result} ${detected_setings} PARENT_SCOPE) +endfunction() + +function(conan_cmake_autodetect detected_settings) + _conan_detect_build_type(${ARGV}) + _conan_check_system_name() + _conan_check_language() + _conan_detect_compiler(${ARGV}) + _collect_settings(collected_settings) + set(${detected_settings} ${collected_settings} PARENT_SCOPE) +endfunction() + +macro(conan_parse_arguments) + set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_LOAD NO_OUTPUT_DIRS OUTPUT_QUIET NO_IMPORTS SKIP_STD) + set(oneValueArgs CONANFILE ARCH BUILD_TYPE INSTALL_FOLDER CONAN_COMMAND) + set(multiValueArgs DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE + PROFILE REQUIRES OPTIONS IMPORTS SETTINGS BUILD ENV GENERATORS PROFILE_AUTO + INSTALL_ARGS CONFIGURATION_TYPES PROFILE_BUILD BUILD_REQUIRES) + cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) +endmacro() + +function(old_conan_cmake_install) + # Calls "conan install" + # Argument BUILD is equivalant to --build={missing, PkgName,...} or + # --build when argument is 'BUILD all' (which builds all packages from source) + # Argument CONAN_COMMAND, to specify the conan path, e.g. in case of running from source + # cmake does not identify conan as command, even if it is +x and it is in the path + conan_parse_arguments(${ARGV}) + + if(CONAN_CMAKE_MULTI) + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake_multi) + else() + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake) + endif() + + set(CONAN_BUILD_POLICY "") + foreach(ARG ${ARGUMENTS_BUILD}) + if(${ARG} STREQUAL "all") + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build) + break() + else() + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build=${ARG}) + endif() + endforeach() + if(ARGUMENTS_CONAN_COMMAND) + set(CONAN_CMD ${ARGUMENTS_CONAN_COMMAND}) + else() + conan_check(REQUIRED) + endif() + set(CONAN_OPTIONS "") + if(ARGUMENTS_CONANFILE) + if(IS_ABSOLUTE ${ARGUMENTS_CONANFILE}) + set(CONANFILE ${ARGUMENTS_CONANFILE}) + else() + set(CONANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) + endif() + else() + set(CONANFILE ".") + endif() + foreach(ARG ${ARGUMENTS_OPTIONS}) + set(CONAN_OPTIONS ${CONAN_OPTIONS} -o=${ARG}) + endforeach() + if(ARGUMENTS_UPDATE) + set(CONAN_INSTALL_UPDATE --update) + endif() + if(ARGUMENTS_NO_IMPORTS) + set(CONAN_INSTALL_NO_IMPORTS --no-imports) + endif() + set(CONAN_INSTALL_FOLDER "") + if(ARGUMENTS_INSTALL_FOLDER) + set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER}) + endif() + foreach(ARG ${ARGUMENTS_GENERATORS}) + set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG}) + endforeach() + foreach(ARG ${ARGUMENTS_ENV}) + set(CONAN_ENV_VARS ${CONAN_ENV_VARS} -e=${ARG}) + endforeach() + set(conan_args install ${CONANFILE} ${settings} ${CONAN_ENV_VARS} ${CONAN_GENERATORS} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE} ${CONAN_INSTALL_NO_IMPORTS} ${CONAN_OPTIONS} ${CONAN_INSTALL_FOLDER} ${ARGUMENTS_INSTALL_ARGS}) + + string (REPLACE ";" " " _conan_args "${conan_args}") + message(STATUS "Conan executing: ${CONAN_CMD} ${_conan_args}") + + if(ARGUMENTS_OUTPUT_QUIET) + execute_process(COMMAND ${CONAN_CMD} ${conan_args} + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_output + ERROR_VARIABLE conan_output + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + else() + execute_process(COMMAND ${CONAN_CMD} ${conan_args} + RESULT_VARIABLE return_code + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + +endfunction() + +function(conan_cmake_install) + if(DEFINED CONAN_COMMAND) + set(CONAN_CMD ${CONAN_COMMAND}) + else() + conan_check(REQUIRED) + endif() + + set(installOptions UPDATE NO_IMPORTS OUTPUT_QUIET ERROR_QUIET) + set(installOneValueArgs PATH_OR_REFERENCE REFERENCE REMOTE LOCKFILE LOCKFILE_OUT LOCKFILE_NODE_ID INSTALL_FOLDER) + set(installMultiValueArgs GENERATOR BUILD ENV ENV_HOST ENV_BUILD OPTIONS_HOST OPTIONS OPTIONS_BUILD PROFILE + PROFILE_HOST PROFILE_BUILD SETTINGS SETTINGS_HOST SETTINGS_BUILD) + cmake_parse_arguments(ARGS "${installOptions}" "${installOneValueArgs}" "${installMultiValueArgs}" ${ARGN}) + foreach(arg ${installOptions}) + if(ARGS_${arg}) + set(${arg} ${${arg}} ${ARGS_${arg}}) + endif() + endforeach() + foreach(arg ${installOneValueArgs}) + if(DEFINED ARGS_${arg}) + if("${arg}" STREQUAL "REMOTE") + set(flag "--remote") + elseif("${arg}" STREQUAL "LOCKFILE") + set(flag "--lockfile") + elseif("${arg}" STREQUAL "LOCKFILE_OUT") + set(flag "--lockfile-out") + elseif("${arg}" STREQUAL "LOCKFILE_NODE_ID") + set(flag "--lockfile-node-id") + elseif("${arg}" STREQUAL "INSTALL_FOLDER") + set(flag "--install-folder") + endif() + set(${arg} ${${arg}} ${flag} ${ARGS_${arg}}) + endif() + endforeach() + foreach(arg ${installMultiValueArgs}) + if(DEFINED ARGS_${arg}) + if("${arg}" STREQUAL "GENERATOR") + set(flag "--generator") + elseif("${arg}" STREQUAL "BUILD") + set(flag "--build") + elseif("${arg}" STREQUAL "ENV") + set(flag "--env") + elseif("${arg}" STREQUAL "ENV_HOST") + set(flag "--env:host") + elseif("${arg}" STREQUAL "ENV_BUILD") + set(flag "--env:build") + elseif("${arg}" STREQUAL "OPTIONS") + set(flag "--options") + elseif("${arg}" STREQUAL "OPTIONS_HOST") + set(flag "--options:host") + elseif("${arg}" STREQUAL "OPTIONS_BUILD") + set(flag "--options:build") + elseif("${arg}" STREQUAL "PROFILE") + set(flag "--profile") + elseif("${arg}" STREQUAL "PROFILE_HOST") + set(flag "--profile:host") + elseif("${arg}" STREQUAL "PROFILE_BUILD") + set(flag "--profile:build") + elseif("${arg}" STREQUAL "SETTINGS") + set(flag "--settings") + elseif("${arg}" STREQUAL "SETTINGS_HOST") + set(flag "--settings:host") + elseif("${arg}" STREQUAL "SETTINGS_BUILD") + set(flag "--settings:build") + endif() + list(LENGTH ARGS_${arg} numargs) + foreach(item ${ARGS_${arg}}) + if(${item} STREQUAL "all" AND ${arg} STREQUAL "BUILD") + set(${arg} "--build") + break() + endif() + set(${arg} ${${arg}} ${flag} ${item}) + endforeach() + endif() + endforeach() + if(DEFINED UPDATE) + set(UPDATE --update) + endif() + if(DEFINED NO_IMPORTS) + set(NO_IMPORTS --no-imports) + endif() + set(install_args install ${PATH_OR_REFERENCE} ${REFERENCE} ${UPDATE} ${NO_IMPORTS} ${REMOTE} ${LOCKFILE} ${LOCKFILE_OUT} ${LOCKFILE_NODE_ID} ${INSTALL_FOLDER} + ${GENERATOR} ${BUILD} ${ENV} ${ENV_HOST} ${ENV_BUILD} ${OPTIONS} ${OPTIONS_HOST} ${OPTIONS_BUILD} + ${PROFILE} ${PROFILE_HOST} ${PROFILE_BUILD} ${SETTINGS} ${SETTINGS_HOST} ${SETTINGS_BUILD}) + + string(REPLACE ";" " " _install_args "${install_args}") + message(STATUS "Conan executing: ${CONAN_CMD} ${_install_args}") + + if(ARGS_OUTPUT_QUIET) + set(OUTPUT_OPT OUTPUT_QUIET) + endif() + if(ARGS_ERROR_QUIET) + set(ERROR_OPT ERROR_QUIET) + endif() + + execute_process(COMMAND ${CONAN_CMD} ${install_args} + RESULT_VARIABLE return_code + ${OUTPUT_OPT} + ${ERROR_OPT} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + if(NOT "${return_code}" STREQUAL "0") + if (ARGS_ERROR_QUIET) + message(WARNING "Conan install failed='${return_code}'") + else() + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + endif() + +endfunction() + +function(conan_cmake_setup_conanfile) + conan_parse_arguments(${ARGV}) + if(ARGUMENTS_CONANFILE) + get_filename_component(_CONANFILE_NAME ${ARGUMENTS_CONANFILE} NAME) + # configure_file will make sure cmake re-runs when conanfile is updated + configure_file(${ARGUMENTS_CONANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk COPYONLY) + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk) + else() + conan_cmake_generate_conanfile(ON ${ARGV}) + endif() +endfunction() + +function(conan_cmake_configure) + conan_cmake_generate_conanfile(OFF ${ARGV}) +endfunction() + +# Generate, writing in disk a conanfile.txt with the requires, options, and imports +# specified as arguments +# This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) +function(conan_cmake_generate_conanfile DEFAULT_GENERATOR) + + conan_parse_arguments(${ARGV}) + + set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") + file(WRITE ${_FN} "") + + if(DEFINED ARGUMENTS_REQUIRES) + file(APPEND ${_FN} "[requires]\n") + foreach(REQUIRE ${ARGUMENTS_REQUIRES}) + file(APPEND ${_FN} ${REQUIRE} "\n") + endforeach() + endif() + + if (DEFAULT_GENERATOR OR DEFINED ARGUMENTS_GENERATORS) + file(APPEND ${_FN} "[generators]\n") + if (DEFAULT_GENERATOR) + file(APPEND ${_FN} "cmake\n") + endif() + if (DEFINED ARGUMENTS_GENERATORS) + foreach(GENERATOR ${ARGUMENTS_GENERATORS}) + file(APPEND ${_FN} ${GENERATOR} "\n") + endforeach() + endif() + endif() + + if(DEFINED ARGUMENTS_BUILD_REQUIRES) + file(APPEND ${_FN} "[build_requires]\n") + foreach(BUILD_REQUIRE ${ARGUMENTS_BUILD_REQUIRES}) + file(APPEND ${_FN} ${BUILD_REQUIRE} "\n") + endforeach() + endif() + + if(DEFINED ARGUMENTS_IMPORTS) + file(APPEND ${_FN} "[imports]\n") + foreach(IMPORTS ${ARGUMENTS_IMPORTS}) + file(APPEND ${_FN} ${IMPORTS} "\n") + endforeach() + endif() + + if(DEFINED ARGUMENTS_OPTIONS) + file(APPEND ${_FN} "[options]\n") + foreach(OPTION ${ARGUMENTS_OPTIONS}) + file(APPEND ${_FN} ${OPTION} "\n") + endforeach() + endif() + +endfunction() + + +macro(conan_load_buildinfo) + if(CONAN_CMAKE_MULTI) + set(_CONANBUILDINFO conanbuildinfo_multi.cmake) + else() + set(_CONANBUILDINFO conanbuildinfo.cmake) + endif() + if(ARGUMENTS_INSTALL_FOLDER) + set(_CONANBUILDINFOFOLDER ${ARGUMENTS_INSTALL_FOLDER}) + else() + set(_CONANBUILDINFOFOLDER ${CMAKE_CURRENT_BINARY_DIR}) + endif() + # Checks for the existence of conanbuildinfo.cmake, and loads it + # important that it is macro, so variables defined at parent scope + if(EXISTS "${_CONANBUILDINFOFOLDER}/${_CONANBUILDINFO}") + message(STATUS "Conan: Loading ${_CONANBUILDINFO}") + include(${_CONANBUILDINFOFOLDER}/${_CONANBUILDINFO}) + else() + message(FATAL_ERROR "${_CONANBUILDINFO} doesn't exist in ${CMAKE_CURRENT_BINARY_DIR}") + endif() +endmacro() + + +macro(conan_cmake_run) + conan_parse_arguments(${ARGV}) + + if(ARGUMENTS_CONFIGURATION_TYPES AND NOT CMAKE_CONFIGURATION_TYPES) + message(WARNING "CONFIGURATION_TYPES should only be specified for multi-configuration generators") + elseif(ARGUMENTS_CONFIGURATION_TYPES AND ARGUMENTS_BUILD_TYPE) + message(WARNING "CONFIGURATION_TYPES and BUILD_TYPE arguments should not be defined at the same time.") + endif() + + if(CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE AND NOT CONAN_EXPORTED + AND NOT ARGUMENTS_BUILD_TYPE) + set(CONAN_CMAKE_MULTI ON) + if (NOT ARGUMENTS_CONFIGURATION_TYPES) + set(ARGUMENTS_CONFIGURATION_TYPES "Release;Debug") + endif() + message(STATUS "Conan: Using cmake-multi generator") + else() + set(CONAN_CMAKE_MULTI OFF) + endif() + + if(NOT CONAN_EXPORTED) + conan_cmake_setup_conanfile(${ARGV}) + if(CONAN_CMAKE_MULTI) + foreach(CMAKE_BUILD_TYPE ${ARGUMENTS_CONFIGURATION_TYPES}) + set(ENV{CONAN_IMPORT_PATH} ${CMAKE_BUILD_TYPE}) + conan_cmake_settings(settings ${ARGV}) + old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) + endforeach() + set(CMAKE_BUILD_TYPE) + else() + conan_cmake_settings(settings ${ARGV}) + old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) + endif() + endif() + + if (NOT ARGUMENTS_NO_LOAD) + conan_load_buildinfo() + endif() + + if(ARGUMENTS_BASIC_SETUP) + foreach(_option CMAKE_TARGETS KEEP_RPATHS NO_OUTPUT_DIRS SKIP_STD) + if(ARGUMENTS_${_option}) + if(${_option} STREQUAL "CMAKE_TARGETS") + list(APPEND _setup_options "TARGETS") + else() + list(APPEND _setup_options ${_option}) + endif() + endif() + endforeach() + conan_basic_setup(${_setup_options}) + endif() +endmacro() + +macro(conan_check) + # Checks conan availability in PATH + # Arguments REQUIRED, DETECT_QUIET and VERSION are optional + # Example usage: + # conan_check(VERSION 1.0.0 REQUIRED) + set(options REQUIRED DETECT_QUIET) + set(oneValueArgs VERSION) + cmake_parse_arguments(CONAN "${options}" "${oneValueArgs}" "" ${ARGN}) + if(NOT CONAN_DETECT_QUIET) + message(STATUS "Conan: checking conan executable") + endif() + + find_program(CONAN_CMD conan) + if(NOT CONAN_CMD AND CONAN_REQUIRED) + message(FATAL_ERROR "Conan executable not found! Please install conan.") + endif() + if(NOT CONAN_DETECT_QUIET) + message(STATUS "Conan: Found program ${CONAN_CMD}") + endif() + execute_process(COMMAND ${CONAN_CMD} --version + RESULT_VARIABLE return_code + OUTPUT_VARIABLE CONAN_VERSION_OUTPUT + ERROR_VARIABLE CONAN_VERSION_OUTPUT) + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan --version failed='${return_code}'") + endif() + + if(NOT CONAN_DETECT_QUIET) + string(STRIP "${CONAN_VERSION_OUTPUT}" _CONAN_VERSION_OUTPUT) + message(STATUS "Conan: Version found ${_CONAN_VERSION_OUTPUT}") + endif() + + if(DEFINED CONAN_VERSION) + string(REGEX MATCH ".*Conan version ([0-9]+\\.[0-9]+\\.[0-9]+)" FOO + "${CONAN_VERSION_OUTPUT}") + if(${CMAKE_MATCH_1} VERSION_LESS ${CONAN_VERSION}) + message(FATAL_ERROR "Conan outdated. Installed: ${CMAKE_MATCH_1}, \ + required: ${CONAN_VERSION}. Consider updating via 'pip \ + install conan==${CONAN_VERSION}'.") + endif() + endif() +endmacro() + +function(conan_add_remote) + # Adds a remote + # Arguments URL and NAME are required, INDEX, COMMAND and VERIFY_SSL are optional + # Example usage: + # conan_add_remote(NAME bincrafters INDEX 1 + # URL https://api.bintray.com/conan/bincrafters/public-conan + # VERIFY_SSL True) + set(oneValueArgs URL NAME INDEX COMMAND VERIFY_SSL) + cmake_parse_arguments(CONAN "" "${oneValueArgs}" "" ${ARGN}) + + if(DEFINED CONAN_INDEX) + set(CONAN_INDEX_ARG "-i ${CONAN_INDEX}") + endif() + if(DEFINED CONAN_COMMAND) + set(CONAN_CMD ${CONAN_COMMAND}) + else() + conan_check(REQUIRED DETECT_QUIET) + endif() + set(CONAN_VERIFY_SSL_ARG "True") + if(DEFINED CONAN_VERIFY_SSL) + set(CONAN_VERIFY_SSL_ARG ${CONAN_VERIFY_SSL}) + endif() + message(STATUS "Conan: Adding ${CONAN_NAME} remote repository (${CONAN_URL}) verify ssl (${CONAN_VERIFY_SSL_ARG})") + execute_process(COMMAND ${CONAN_CMD} remote add ${CONAN_NAME} ${CONAN_INDEX_ARG} -f ${CONAN_URL} ${CONAN_VERIFY_SSL_ARG} + RESULT_VARIABLE return_code) + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan remote failed='${return_code}'") + endif() +endfunction() + +macro(conan_config_install) + # install a full configuration from a local or remote zip file + # Argument ITEM is required, arguments TYPE, SOURCE, TARGET and VERIFY_SSL are optional + # Example usage: + # conan_config_install(ITEM https://github.com/conan-io/cmake-conan.git + # TYPE git SOURCE source-folder TARGET target-folder VERIFY_SSL false) + set(oneValueArgs ITEM TYPE SOURCE TARGET VERIFY_SSL) + set(multiValueArgs ARGS) + cmake_parse_arguments(CONAN "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + find_program(CONAN_CMD conan) + if(NOT CONAN_CMD AND CONAN_REQUIRED) + message(FATAL_ERROR "Conan executable not found!") + endif() + + if(DEFINED CONAN_VERIFY_SSL) + set(CONAN_VERIFY_SSL_ARG "--verify-ssl=${CONAN_VERIFY_SSL}") + endif() + + if(DEFINED CONAN_TYPE) + set(CONAN_TYPE_ARG "--type=${CONAN_TYPE}") + endif() + + if(DEFINED CONAN_ARGS) + set(CONAN_ARGS_ARGS "--args=\"${CONAN_ARGS}\"") + endif() + + if(DEFINED CONAN_SOURCE) + set(CONAN_SOURCE_ARGS "--source-folder=${CONAN_SOURCE}") + endif() + + if(DEFINED CONAN_TARGET) + set(CONAN_TARGET_ARGS "--target-folder=${CONAN_TARGET}") + endif() + + set (CONAN_CONFIG_INSTALL_ARGS ${CONAN_VERIFY_SSL_ARG} + ${CONAN_TYPE_ARG} + ${CONAN_ARGS_ARGS} + ${CONAN_SOURCE_ARGS} + ${CONAN_TARGET_ARGS}) + + message(STATUS "Conan: Installing config from ${CONAN_ITEM}") + execute_process(COMMAND ${CONAN_CMD} config install ${CONAN_ITEM} ${CONAN_CONFIG_INSTALL_ARGS} + RESULT_VARIABLE return_code) + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan config failed='${return_code}'") + endif() +endmacro() diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 79d1ae66..329a90ba 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,19 +1,19 @@ -python_add_module (lcmaes lcmaes.cc) +Python3_add_library (lcmaes lcmaes.cc) -target_link_libraries (lcmaes cmaes Python::Module Python::NumPy Boost::python) +target_link_libraries (lcmaes PUBLIC cmaes Python3::Module Python3::NumPy Boost::python) if (APPLE) set_target_properties (lcmaes PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") endif () -install (TARGETS lcmaes DESTINATION ${PYTHON_SITE_PACKAGES}) +#install (TARGETS lcmaes DESTINATION ${PYTHON_SITE_PACKAGES}) set (PYINSTALLCHECK_ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") if (LIBCMAES_BUILD_TESTS) macro (cmaes_add_pytest name) - add_test (NAME ${name} COMMAND ${PYTHON_EXECUTABLE} + add_test (NAME ${name} COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py) set_tests_properties (${name} PROPERTIES ENVIRONMENT "${PYINSTALLCHECK_ENVIRONMENT}") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9c179bb4..e5be9d9b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,4 @@ +find_package(gflags REQUIRED) macro (cmaes_add_test name) add_executable (t_${name} ${name}.cc) target_link_libraries (t_${name} cmaes gflags) From 97f19184c915dae6779afd2c5203f4bc75e80a21 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 9 Apr 2022 08:04:09 +0200 Subject: [PATCH 02/48] Fixed missed python cmake links --- CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bd6d374..91876755 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,22 +107,22 @@ endif () if (LIBCMAES_BUILD_PYTHON) find_package (Python3 COMPONENTS Interpreter Development NumPy) - if (NOT TARGET Python::Module AND PYTHONLIBS_FOUND) - add_library (Python::Module SHARED IMPORTED) + if (NOT TARGET Python3::Module AND Python3_Development_FOUND) + add_library (Python3::Module SHARED IMPORTED) set_target_properties ( - Python::Module - PROPERTIES IMPORTED_LOCATION ${PYTHON_LIBRARIES} - INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS}) + Python3::Module + PROPERTIES IMPORTED_LOCATION ${Python3_LIBRARIES} + INTERFACE_INCLUDE_DIRECTORIES ${Python3_INCLUDE_DIRS}) endif () #find_package (NumPy) # python site dir - if (PYTHON_EXECUTABLE AND NOT DEFINED PYTHON_SITE_PACKAGES) + if (Python3_EXECUTABLE AND NOT DEFINED PYTHON_SITE_PACKAGES) # $ENV{VIRTUAL_ENV} does not work because not exported by activate :/ execute_process ( COMMAND - ${PYTHON_EXECUTABLE} -c " + ${Python3_EXECUTABLE} -c " import sys; if 'real_prefix' in dir(sys): print(sys.prefix)" @@ -135,7 +135,7 @@ if 'real_prefix' in dir(sys): endif () execute_process ( COMMAND - ${PYTHON_EXECUTABLE} -c + ${Python3_EXECUTABLE} -c "from distutils import sysconfig; print(sysconfig.get_python_lib(plat_specific=True, prefix='${SITE_DIR_PREFIX}'))" OUTPUT_VARIABLE _ABS_PYTHON_SITE_PACKAGES RESULT_VARIABLE _exit_code @@ -148,7 +148,7 @@ if 'real_prefix' in dir(sys): ${_ABS_PYTHON_SITE_PACKAGES}) set (PYTHON_SITE_PACKAGES ${_REL_PYTHON_SITE_PACKAGES}) else () - message (SEND_ERROR "Could not run ${PYTHON_EXECUTABLE}") + message (SEND_ERROR "Could not run ${Python3_EXECUTABLE}") endif () endif () From 1aacd71509224d1d05b885e11f938b3c14090c5c Mon Sep 17 00:00:00 2001 From: Philipp B Date: Sun, 10 Apr 2022 13:41:05 +0200 Subject: [PATCH 03/48] Fixed windows compile problems --- CMakeLists.txt | 24 +++++++--- cmake/CompilerOptions.cmake | 90 +++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 cmake/CompilerOptions.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index dfaf0ae7..8d31ee8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,12 +6,10 @@ if (NOT DEFINED CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type") endif () -set(CMAKE_CXX_FLAGS "-Wall -Wextra") -set(CMAKE_CXX_FLAGS_DEBUG "-g") -set(CMAKE_CXX_FLAGS_RELEASE "-O3") - list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) +include(CompilerOptions) + set (LIBCMAES_TOP_LEVEL NO) if (${PROJECT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) set (LIBCMAES_TOP_LEVEL YES) @@ -64,6 +62,17 @@ check_include_file (sys/types.h HAVE_SYS_TYPES_H) check_include_file (sys/stat.h HAVE_SYS_STAT_H) # ---------- dependencies ---------- +if(LIBCMAES_BUILD_PYTHON) + find_package (Python3 COMPONENTS Interpreter Development NumPy) + if (NOT TARGET Python3::Module AND Python3_Development_FOUND) + add_library (Python3::Module SHARED IMPORTED) + set_target_properties ( + Python3::Module + PROPERTIES IMPORTED_LOCATION ${Python3_LIBRARIES} + INTERFACE_INCLUDE_DIRECTORIES ${Python3_INCLUDE_DIRS}) + endif () +endif() + if(LIBCMAES_USE_CONAN) list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) @@ -74,7 +83,10 @@ if(LIBCMAES_USE_CONAN) set(ConanPkgList ${ConanPkgList} boost/1.78.0 ) - set(ConanOptions ${ConanOptions} boost:without_python=False) + set(ConanOptions ${ConanOptions} + boost:without_python=False + boost:python_version=${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} + boost:python_executable=${Python3_EXECUTABLE}) endif(LIBCMAES_BUILD_PYTHON) if(LIBCMAES_BUILD_TESTS) @@ -119,8 +131,6 @@ if (LIBCMAES_BUILD_PYTHON) INTERFACE_INCLUDE_DIRECTORIES ${Python3_INCLUDE_DIRS}) endif () - #find_package (NumPy) - # python site dir if (Python3_EXECUTABLE AND NOT DEFINED PYTHON_SITE_PACKAGES) # $ENV{VIRTUAL_ENV} does not work because not exported by activate :/ diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake new file mode 100644 index 00000000..6f0ebec6 --- /dev/null +++ b/cmake/CompilerOptions.cmake @@ -0,0 +1,90 @@ +# SPDX-FileCopyrightText: 2021 Philipp Basler, Margarete Mühlleitner and Jonas Müller +# +# SPDX-License-Identifier: GPL-3.0-or-later + +set(CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG} -Wall" +) +set(CMAKE_CXX_FLAGS_RELEASE + "${CMAKE_CXX_FLAGS_RELEASE} -Wall ") + +if(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG} -Wextra") + set(CMAKE_CXX_FLAGS_RELEASE + "${CMAKE_CXX_FLAGS_RELEASE} -O3 -Wextra") +endif(CMAKE_COMPILER_IS_GNUCXX) + +if (MSVC) + set(CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG} /permissive- /bigobj /w44101") + + set(CMAKE_CXX_FLAGS_RELEASE + "${CMAKE_CXX_FLAGS_RELEASE} /permissive- /bigobj /w44101 /Ox") + + set(MSVC_DISABLED_WARNINGS_LIST + "C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not + # explicitly handled by a case label + # Disable this because it flags even when there is a default. + "C4068" + "C4100" # 'exarg' : unreferenced formal parameter + "C4127" # conditional expression is constant + "C4200" # nonstandard extension used : zero-sized array in + # struct/union. + "C4204" # nonstandard extension used: non-constant aggregate initializer + "C4221" # nonstandard extension used : 'identifier' : cannot be + # initialized using address of automatic variable + "C4242" # 'function' : conversion from 'int' to 'uint8_t', + # possible loss of data + "C4244" # 'function' : conversion from 'int' to 'uint8_t', + # possible loss of data + "C4245" # 'initializing' : conversion from 'long' to + # 'unsigned long', signed/unsigned mismatch + "C4267" # conversion from 'size_t' to 'int', possible loss of data + "C4355" + "C4371" # layout of class may have changed from a previous version of the + # compiler due to better packing of member '...' + "C4388" # signed/unsigned mismatch + "C4296" # '>=' : expression is always true + "C4350" # behavior change: 'std::_Wrap_alloc...' + "C4365" # '=' : conversion from 'size_t' to 'int', + # signed/unsigned mismatch + "C4389" # '!=' : signed/unsigned mismatch + "C4464" # relative include path contains '..' + "C4510" # 'argument' : default constructor could not be generated + "C4571" + "C4512" # 'argument' : assignment operator could not be generated + "C4514" # 'function': unreferenced inline function has been removed + "C4548" # expression before comma has no effect; expected expression with + # side-effect" caused by FD_* macros. + "C4610" # struct 'argument' can never be instantiated - user defined + # constructor required. + "C4619" + "C4623" # default constructor was implicitly defined as deleted + "C4625" # copy constructor could not be generated because a base class + # copy constructor is inaccessible or deleted + "C4626" # assignment operator could not be generated because a base class + # assignment operator is inaccessible or deleted + "C4643" + "C4668" # 'symbol' is not defined as a preprocessor macro, replacing with + # '0' for 'directives' + # Disable this because GTest uses it everywhere. + "C4706" # assignment within conditional expression + "C4710" # 'function': function not inlined + "C4711" # function 'function' selected for inline expansion + "C4800" # 'int' : forcing value to bool 'true' or 'false' + # (performance warning) + "C4820" # 'bytes' bytes padding added after construct 'member_name' + "C4868" + "C4996" + "C5026" # move constructor was implicitly defined as deleted + "C5027" # move assignment operator was implicitly defined as deleted + "C5031" + "C5039" + "C5045" + ) + string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR + ${MSVC_DISABLED_WARNINGS_LIST}) + + set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} ${MSVC_DISABLED_WARNINGS_STR}") + endif() From 7f5fa1b86ede94d77c204160443a4fd33ee97219 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 10 Apr 2022 14:34:33 +0200 Subject: [PATCH 04/48] cmake was not using the cmake files provided by conan, fixed it together with boost python --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91876755..dfaf0ae7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,12 +66,15 @@ check_include_file (sys/stat.h HAVE_SYS_STAT_H) # ---------- dependencies ---------- if(LIBCMAES_USE_CONAN) + list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) include(conan) set(ConanPkgList eigen/3.4.0) + set(ConanOptions "") if(LIBCMAES_BUILD_PYTHON) set(ConanPkgList ${ConanPkgList} boost/1.78.0 ) + set(ConanOptions ${ConanOptions} boost:without_python=False) endif(LIBCMAES_BUILD_PYTHON) if(LIBCMAES_BUILD_TESTS) @@ -79,7 +82,8 @@ if(LIBCMAES_USE_CONAN) endif(LIBCMAES_BUILD_TESTS) conan_cmake_configure(REQUIRES ${ConanPkgList} - GENERATORS cmake_find_package) + GENERATORS cmake_find_package + OPTIONS ${ConanOptions}) conan_cmake_autodetect(settings) From f083088a3a4e20bce8154c7630d8a7a60faae9ce Mon Sep 17 00:00:00 2001 From: Philipp B Date: Sun, 10 Apr 2022 16:27:58 +0200 Subject: [PATCH 05/48] Had to include scalar_normal_dist_op copy ctr for MVSC compiler and Math definition for MVSC --- cmake/CompilerOptions.cmake | 6 +++++- include/libcmaes/eigenmvn.h | 16 +++++++++++++++- python/CMakeLists.txt | 2 +- tests/CMakeLists.txt | 3 +++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 6f0ebec6..5ba9aaee 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -16,11 +16,13 @@ if(CMAKE_COMPILER_IS_GNUCXX) endif(CMAKE_COMPILER_IS_GNUCXX) if (MSVC) + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_USE_MATH_DEFINES" ) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /permissive- /bigobj /w44101") set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} /permissive- /bigobj /w44101 /Ox") + "${CMAKE_CXX_FLAGS_RELEASE} /permissive- /bigobj /Ox /w44101") set(MSVC_DISABLED_WARNINGS_LIST "C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not @@ -40,7 +42,9 @@ if (MSVC) # possible loss of data "C4245" # 'initializing' : conversion from 'long' to # 'unsigned long', signed/unsigned mismatch + "C4251" "C4267" # conversion from 'size_t' to 'int', possible loss of data + "C4275" "C4355" "C4371" # layout of class may have changed from a previous version of the # compiler due to better packing of member '...' diff --git a/include/libcmaes/eigenmvn.h b/include/libcmaes/eigenmvn.h index fb8b11d4..c1a4eed9 100644 --- a/include/libcmaes/eigenmvn.h +++ b/include/libcmaes/eigenmvn.h @@ -58,7 +58,21 @@ namespace Eigen { static std::mt19937 rng; // The uniform pseudo-random algorithm mutable std::normal_distribution norm; // gaussian combinator - EIGEN_EMPTY_STRUCT_CTOR(scalar_normal_dist_op) + //EIGEN_EMPTY_STRUCT_CTOR(scalar_normal_dist_op) + scalar_normal_dist_op() = default; + scalar_normal_dist_op(const scalar_normal_dist_op& other) + : norm{other.norm} + { + rng = other.rng; + }; + scalar_normal_dist_op &operator=(const scalar_normal_dist_op &other) { + if(this != &other) + { + scalar_normal_dist_op temp(other); + swap(temp); + } + return *this; + }; scalar_normal_dist_op &operator=(scalar_normal_dist_op &&other) { diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 329a90ba..4f5d75a1 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -7,7 +7,7 @@ if (APPLE) "-undefined dynamic_lookup") endif () -#install (TARGETS lcmaes DESTINATION ${PYTHON_SITE_PACKAGES}) +install (TARGETS lcmaes DESTINATION ${PYTHON_SITE_PACKAGES}) set (PYINSTALLCHECK_ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e5be9d9b..7a4ca30a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,6 +2,9 @@ find_package(gflags REQUIRED) macro (cmaes_add_test name) add_executable (t_${name} ${name}.cc) target_link_libraries (t_${name} cmaes gflags) + if(MSVC) + target_compile_definitions(t_${name} PUBLIC _USE_MATH_DEFINES) + endif() add_test (NAME ${name} COMMAND t_${name}) if (WIN32) set_tests_properties ( From f065ae550d06766049c1be89ce767758385c13d8 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Thu, 28 Apr 2022 06:30:06 +0200 Subject: [PATCH 06/48] Conan windows (#5) * added CI * Added gflags * Includ numpy and boost-python * Changed pip to pip3 * Extended PYTHONPATH * Extending pythonpath * Adjusted Pythonpath to use Config if available * Update windows_unit_tests.yml * Update windows_unit_tests.yml * Update windows_unit_tests.yml * Update windows_unit_tests.yml * Modified python path * Update CMakeLists.txt * Moved pythonpath to target generator expression * Add post_build/install of cmaes.dll to python location on MVSC * Adjusted workflows to only trigger on master Co-authored-by: Phil --- .github/workflows/test-mac.yml | 32 +++++++++++++++++++ .github/workflows/test.yml | 34 +++++++++++++++++++++ .github/workflows/windows_unit_tests.yml | 39 ++++++++++++++++++++++++ python/CMakeLists.txt | 15 ++++++--- 4 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/test-mac.yml create mode 100644 .github/workflows/test.yml create mode 100644 .github/workflows/windows_unit_tests.yml diff --git a/.github/workflows/test-mac.yml b/.github/workflows/test-mac.yml new file mode 100644 index 00000000..8ca0a90b --- /dev/null +++ b/.github/workflows/test-mac.yml @@ -0,0 +1,32 @@ +name: Mac unit tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + workflow_dispatch: + +jobs: + mac-tests: + runs-on: macos-latest + if: "!contains(github.event.head_commit.message, 'skip-ci')" + + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + - name : installPackages + run : brew install eigen boost boost-python3 libomp gflags + - name : install python packages + run: pip3 install numpy + - name: Get number of CPU cores + uses: SimenB/github-actions-cpu-cores@v1 + id: cpu-cores + - name: cmake + run: mkdir build && cd build && cmake .. -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On + - name: compile + run: cd build && cmake --build . -j${{ steps.cpu-cores.outputs.count }} + - name: Run ctest + run: cd build && ctest -j${{ steps.cpu-cores.outputs.count }} --output-on-failure + diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..59b0c572 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,34 @@ +name: Ubuntu unit tests + +on: + push: + branches: [ master] + pull_request: + branches: [ master, develop ] + workflow_dispatch: + + +jobs: + ubuntu-tests-fullSetup: + runs-on: ubuntu-20.04 + if: "!contains(github.event.head_commit.message, 'skip-ci')" + + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + - name : installPackages + run : sudo apt-get update && sudo apt-get install --no-install-recommends --yes libeigen3-dev libboost-all-dev libgflags-dev + - name : install python packages + run: pip3 install numpy + - name: Get number of CPU cores + uses: SimenB/github-actions-cpu-cores@v1 + id: cpu-cores + - name: cmake + run: mkdir build && cd build && cmake .. -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On + - name: compile + run: cd build && cmake --build . -j${{ steps.cpu-cores.outputs.count }} + - name: Run ctest + run: cd build && ctest -j${{ steps.cpu-cores.outputs.count }} --output-on-failure + + diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml new file mode 100644 index 00000000..d3a9c64d --- /dev/null +++ b/.github/workflows/windows_unit_tests.yml @@ -0,0 +1,39 @@ +name: Windows unit tests + +on: + push: + branches: [ master] + pull_request: + branches: [ master ] + workflow_dispatch: + + +jobs: + windows-tests-fullSetup: + runs-on: windows-2019 + if: "!contains(github.event.head_commit.message, 'skip-ci')" + + steps: + - uses: actions/checkout@v3 + with: + persist-credentials: false + - uses: actions/setup-python@v3 + with: + python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax + architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified + - name: Install conan + run: pip install conan numpy + - name: Refresh Shell + run: refreshenv + - name: Get number of CPU cores + uses: SimenB/github-actions-cpu-cores@v1 + id: cpu-cores + - name: cmake + run: cmake -S . -B build -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DLIBCMAES_USE_CONAN=On -DCMAKE_BUILD_TYPE=Release + - name: compile + run: cd build && cmake --build . -j${{ steps.cpu-cores.outputs.count }} --config Release + - name: Run ctest + run: cd build && ctest -j${{ steps.cpu-cores.outputs.count }} --output-on-failure -C Release + + + diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 4f5d75a1..a32c3ae5 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,6 +1,11 @@ -Python3_add_library (lcmaes lcmaes.cc) +Python3_add_library (lcmaes MODULE lcmaes.cc) -target_link_libraries (lcmaes PUBLIC cmaes Python3::Module Python3::NumPy Boost::python) +if(MSVC) + add_custom_command(TARGET lcmaes POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ ) +endif() + +target_link_libraries (lcmaes PRIVATE cmaes Python3::Module Python3::NumPy Boost::python) if (APPLE) set_target_properties (lcmaes PROPERTIES LINK_FLAGS @@ -8,15 +13,17 @@ if (APPLE) endif () install (TARGETS lcmaes DESTINATION ${PYTHON_SITE_PACKAGES}) +if(MSVC) +install(TARGETS cmaes DESTINATION ${PYTHON_SITE_PACKAGES}) +endif() -set (PYINSTALLCHECK_ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") if (LIBCMAES_BUILD_TESTS) macro (cmaes_add_pytest name) add_test (NAME ${name} COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py) set_tests_properties (${name} PROPERTIES ENVIRONMENT - "${PYINSTALLCHECK_ENVIRONMENT}") + "PYTHONPATH=$") endmacro () cmaes_add_pytest (ptest) From 55f2d398b797040c77bff98f14e0d7070cd83d31 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Thu, 28 Apr 2022 06:34:43 +0200 Subject: [PATCH 07/48] Add conan to readme --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 26434b80..e18326ea 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,13 @@ make -j2 make install ``` +Additionally, you can use [conan](https://conan.io/center/) to take care of the dependencies. For this you run cmake as +``` +cmake -S . -B build -DCMAKE_INSTALL_PREFIX=~/.local/ -DLIBCMAES_USE_CONAN=On +cmake --build build -j2 +cmake --build build -j2 -t install +``` + ### Run examples ``` cd tests From 1d3eca54af1724b7128e3b93d37a92123c57aeeb Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Wed, 4 May 2022 21:10:35 +0200 Subject: [PATCH 08/48] Fixed doc target if cmaes is included as a subdirectory --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 861acf93..12f4b39d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,7 +235,7 @@ install ( # ------------------------ Doxygen -------------------------------------------- find_package(Doxygen) -if(DOXYGEN_FOUND) +if(DOXYGEN_FOUND AND CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(DOXYGEN_USE_MATHJAX YES) set(DOXYGEN_STRIP_FROM_INC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include") @@ -252,6 +252,6 @@ if(DOXYGEN_FOUND) "${CMAKE_CURRENT_SOURCE_DIR}/src/" "${CMAKE_CURRENT_SOURCE_DIR}/README.md") -else (DOXYGEN_FOUND) +else () message("Doxygen need to be installed to generate the doxygen documentation") -endif(DOXYGEN_FOUND) +endif() From 7827c96c447132c36815b022d7e6aae52b8823bc Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Wed, 4 May 2022 21:14:45 +0200 Subject: [PATCH 09/48] Use the LIBCMAES_TOP_LEVEL variable instead --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12f4b39d..599bec3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,7 +235,7 @@ install ( # ------------------------ Doxygen -------------------------------------------- find_package(Doxygen) -if(DOXYGEN_FOUND AND CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) +if(DOXYGEN_FOUND AND LIBCMAES_TOP_LEVEL) set(DOXYGEN_USE_MATHJAX YES) set(DOXYGEN_STRIP_FROM_INC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include") From 0ecfc3b61b4a3cca061630a3089864ac27919245 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 7 May 2022 13:38:17 +0200 Subject: [PATCH 10/48] Update README.md Fixed wrong doxygen link to match the move of the project --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 66f0de7a..f7f42b84 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## libcmaes -[![Doxygen](https://img.shields.io/badge/Documentation-Doxygen-success)](https://beniz.github.io/libcmaes/doc/html/index.html) +[![Doxygen](https://img.shields.io/badge/Documentation-Doxygen-success)](https://cma-es.github.io/libcmaes/doc/html/index.html) libcmaes is a multithreaded C++11 implementation (with Python bindings) of algorithms of the CMA-ES family for optimization of nonlinear non-convex 'blackbox' functions. The implemented algorithms have a wide range of applications in various disciplines, ranging from pure function minimization, optimization in industrial and scientific applications, to the solving of reinforcement and machine learning problems. @@ -26,7 +26,7 @@ Current features include: Documentation: - Full documentation is available from https://github.com/beniz/libcmaes/wiki -- API documentation is available from http://beniz.github.io/libcmaes/doc/html/index.html +- API documentation is available from https://cma-es.github.io/libcmaes/doc/html/index.html Dependencies: From b43565ed3c4f6ebaccd50ba8860626e8a23a2b66 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 11 Sep 2022 01:32:56 +0200 Subject: [PATCH 11/48] Adding conanfile (#6) Add conanfile to generate conan package --- CMakeLists.txt | 25 ++++++++--- conanfile.py | 87 ++++++++++++++++++++++++++++++++++++ libcmaes-config.cmake.in | 14 ++++++ libcmaesConfig.cmake.in | 9 ---- test_package/CMakeLists.txt | 7 +++ test_package/conanfile.py | 30 +++++++++++++ test_package/src/example.cpp | 26 +++++++++++ 7 files changed, 182 insertions(+), 16 deletions(-) create mode 100644 conanfile.py create mode 100644 libcmaes-config.cmake.in delete mode 100644 libcmaesConfig.cmake.in create mode 100644 test_package/CMakeLists.txt create mode 100644 test_package/conanfile.py create mode 100644 test_package/src/example.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 599bec3c..57fdbd33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,9 @@ cmake_minimum_required (VERSION 3.15) +set(libcmaes_VERSION 0.10.1) + project (libcmaes - VERSION 0.10 + VERSION ${libcmaes_VERSION} LANGUAGES C CXX DESCRIPTION "A C++11 library for stochastic optimization with CMA-ES") @@ -9,6 +11,7 @@ if (NOT DEFINED CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type") endif () +list (APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) include(CompilerOptions) @@ -213,12 +216,21 @@ endif () add_library (libcmaes::cmaes ALIAS cmaes) include (CMakePackageConfigHelpers) -write_basic_package_version_file ( - libcmaesConfigVersion.cmake VERSION ${PACKAGE_VERSION} - COMPATIBILITY AnyNewerVersion) +write_basic_package_version_file( + libcmaes-config-version.cmake + VERSION ${PACKAGE_VERSION} + COMPATIBILITY AnyNewerVersion) + + + +configure_package_config_file( + libcmaes-config.cmake.in + libcmaes-config.cmake + INSTALL_DESTINATION ${RELATIVE_INSTALL_CMAKE_DIR}) # export target to build directory export (TARGETS cmaes NAMESPACE libcmaes:: FILE libcmaesTargets.cmake) + # export target on install install ( EXPORT libcmaesTargets @@ -226,10 +238,9 @@ install ( NAMESPACE libcmaes:: DESTINATION ${RELATIVE_INSTALL_CMAKE_DIR}) -configure_file (libcmaesConfig.cmake.in libcmaesConfig.cmake @ONLY) install ( - FILES "${CMAKE_CURRENT_BINARY_DIR}/libcmaesConfig.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/libcmaesConfigVersion.cmake" + FILES "${CMAKE_CURRENT_BINARY_DIR}/libcmaes-config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/libcmaes-config-version.cmake" DESTINATION ${RELATIVE_INSTALL_CMAKE_DIR}) # ------------------------ Doxygen -------------------------------------------- diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 00000000..3ff80dc7 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,87 @@ +import re, os, functools + +from conans import tools as tools +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout +from conans.tools import load + +class CmaesConan(ConanFile): + name = "libcmaes" + + generators = "CMakeDeps", "CMakeToolchain" + + # Optional metadata + license = "MIT" + author = " " + url = "https://github.com/CMA-ES/libcmaes" + description = "libcmaes is a multithreaded C++11 library with Python bindings for high performance blackbox stochastic optimization using the CMA-ES algorithm for Covariance Matrix Adaptation Evolution Strategy" + topics = ("", "", "") + + # Binary configuration + settings = "os", "compiler", "build_type", "arch" + options = { + "shared": [True, False], + "openmp": [True, False], + "surrog": [True, False] + } + default_options = { + "shared": True, + "openmp": True, + "surrog": True + } + + # Sources are located in the same place as this recipe, copy them to the recipe + exports_sources = "CMakeLists.txt", "cmake/*", "include/*", "libcmaes-config.cmake.in", "src/*", "libcmaes.pc.in" + + def build_requirements(self): + pass + + def requirements(self): + self.requires("eigen/3.4.0") + + + def set_version(self): + content = load(os.path.join(self.recipe_folder, "CMakeLists.txt")) + value=re.search(r"set\(libcmaes_VERSION (.*)\)", content) + print(value) + extracted_version = value.group(1).strip() + + git = tools.Git(folder=self.recipe_folder) + if (git.get_tag() != None): + # depending on your workflow you could also + # set a non-beta version when on main branch or + # on a certain release branch + self.version = extracted_version + else: + # if not tag -> pre-release version + commit_hash = git.get_commit()[:8] + branch_name = git.get_branch()[:9] + self.version = f"{extracted_version}-{branch_name}.{commit_hash}" + + def config_options(self): + pass + + def layout(self): + cmake_layout(self) + + def generate(self): + tc = CMakeToolchain(self) + tc.variables['LIBCMAES_BUILD_EXAMPLES']=False + tc.variables['LIBCMAES_BUILD_SHARED_LIBS']= self.options.shared + tc.variables['LIBCMAES_USE_OPENMP'] = self.options.openmp + tc.variables['LIBCMAES_ENABLE_SURROG'] = self.options.surrog + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + cmake = CMake(self) + cmake.install() + + def package_info(self): + self.cpp_info.libs = ["cmaes"] + self.cpp_info.set_property("cmake_target_aliases",["libcmaes::cmaes"]) + self.cpp_info.requires = ["eigen::eigen"] diff --git a/libcmaes-config.cmake.in b/libcmaes-config.cmake.in new file mode 100644 index 00000000..8fa61830 --- /dev/null +++ b/libcmaes-config.cmake.in @@ -0,0 +1,14 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +list (APPEND CMAKE_MODULE_PATH @CMAKE_CURRENT_SOURCE_DIR@/lib/cmake/libcmaes ${CMAKE_CURRENT_LIST_DIR}) + +find_dependency(Eigen3 @EIGEN3_VERSION@ REQUIRED) + + +if(@LIBCMAES_USE_OPENMP@) + find_dependency(OpenMP @OpenMP_CXX_VERSION@) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/libcmaesTargets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/libcmaesConfig.cmake.in b/libcmaesConfig.cmake.in deleted file mode 100644 index a17175f5..00000000 --- a/libcmaesConfig.cmake.in +++ /dev/null @@ -1,9 +0,0 @@ -include (CMakeFindDependencyMacro) -list (APPEND CMAKE_MODULE_PATH @CMAKE_CURRENT_SOURCE_DIR@/cmake ${CMAKE_CURRENT_LIST_DIR}) - -find_dependency (Eigen3 REQUIRED) -if (@LIBCMAES_USE_OPENMP@ AND @OpenMP_FOUND@) - find_dependency (OpenMP REQUIRED) -endif () - -include ("${CMAKE_CURRENT_LIST_DIR}/libcmaesTargets.cmake") diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt new file mode 100644 index 00000000..65a1c3af --- /dev/null +++ b/test_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.15) +project(PackageTest CXX) + +find_package(libcmaes CONFIG REQUIRED) + +add_executable(example src/example.cpp) +target_link_libraries(example libcmaes::cmaes) diff --git a/test_package/conanfile.py b/test_package/conanfile.py new file mode 100644 index 00000000..3b7b38de --- /dev/null +++ b/test_package/conanfile.py @@ -0,0 +1,30 @@ +import os + +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout +from conan.tools.build import cross_building + + +class CmaesTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + # VirtualBuildEnv and VirtualRunEnv can be avoided if "tools.env.virtualenv:auto_use" is defined + # (it will be defined in Conan 2.0) + generators = "CMakeDeps", "CMakeToolchain", "VirtualBuildEnv", "VirtualRunEnv" + apply_env = False + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def layout(self): + cmake_layout(self) + + def test(self): + if not cross_building(self): + cmd = os.path.join(self.cpp.build.bindirs[0], "example") + self.run(cmd, env="conanrun") diff --git a/test_package/src/example.cpp b/test_package/src/example.cpp new file mode 100644 index 00000000..8d7db546 --- /dev/null +++ b/test_package/src/example.cpp @@ -0,0 +1,26 @@ +#include +#include + +using namespace libcmaes; + +FitFunc fsphere = [](const double *x, const int N) +{ + double val = 0.0; + for (int i=0;i x0(dim,10.0); + double sigma = 0.1; + //int lambda = 100; // offsprings at each generation. + CMAParameters<> cmaparams(x0,sigma); + //cmaparams._algo = BIPOP_CMAES; + CMASolutions cmasols = cmaes<>(fsphere,cmaparams); + std::cout << "best solution: " << cmasols << std::endl; + std::cout << "optimization took " << cmasols.elapsed_time() / 1000.0 << " seconds\n"; + return EXIT_SUCCESS; +} \ No newline at end of file From 016f5cbc609741e29b8bbc19ca52574ebc64ae1e Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Wed, 22 Mar 2023 19:31:15 +0100 Subject: [PATCH 12/48] Change in conanfile to retrigger workflow --- conanfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 3ff80dc7..d98c36cd 100644 --- a/conanfile.py +++ b/conanfile.py @@ -8,7 +8,8 @@ class CmaesConan(ConanFile): name = "libcmaes" - generators = "CMakeDeps", "CMakeToolchain" + generators = "CMakeDeps" + #, "CMakeToolchain" # Optional metadata license = "MIT" From 25ee637aae331a47ac6fa4d286131be0db444e95 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:26:27 +0200 Subject: [PATCH 13/48] Update for conan 2 --- .gitignore | 8 ++++++++ conanfile.py | 34 +++++++++++++++++++--------------- test_package/conanfile.py | 15 ++++++--------- 3 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f8310a72 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +build/ +CMakeLists.txt.user +CMakeUserPresets.json +install/ +installFolder/ +conandummy/ +test_package/CMakeUserPresets.json +lib/ \ No newline at end of file diff --git a/conanfile.py b/conanfile.py index 3ff80dc7..72d32c2c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,14 +1,16 @@ import re, os, functools -from conans import tools as tools +from conan import ConanFile, tools from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout -from conans.tools import load +from conan.tools.files import load + +from conan.tools.scm import Git class CmaesConan(ConanFile): name = "libcmaes" - generators = "CMakeDeps", "CMakeToolchain" + generators = "CMakeDeps" # Optional metadata license = "MIT" @@ -37,26 +39,28 @@ def build_requirements(self): pass def requirements(self): - self.requires("eigen/3.4.0") + self.requires("eigen/3.4.0", transitive_headers=True) def set_version(self): - content = load(os.path.join(self.recipe_folder, "CMakeLists.txt")) + content = load(self, os.path.join(self.recipe_folder, "CMakeLists.txt")) value=re.search(r"set\(libcmaes_VERSION (.*)\)", content) - print(value) extracted_version = value.group(1).strip() - git = tools.Git(folder=self.recipe_folder) - if (git.get_tag() != None): - # depending on your workflow you could also - # set a non-beta version when on main branch or - # on a certain release branch + is_git_tag = False + git = Git(self,folder=self.recipe_folder) + try: + git.run("describe --exact-match --tags") + is_git_tag = True + except Exception: + is_git_tag=False + + if is_git_tag: self.version = extracted_version else: # if not tag -> pre-release version commit_hash = git.get_commit()[:8] - branch_name = git.get_branch()[:9] - self.version = f"{extracted_version}-{branch_name}.{commit_hash}" + self.version = f"{extracted_version}.{commit_hash}" def config_options(self): pass @@ -83,5 +87,5 @@ def package(self): def package_info(self): self.cpp_info.libs = ["cmaes"] - self.cpp_info.set_property("cmake_target_aliases",["libcmaes::cmaes"]) - self.cpp_info.requires = ["eigen::eigen"] + #self.cpp_info.set_property("cmake_target_aliases",["libcmaes::cmaes"]) + #self.cpp_info.requires = ["eigen::eigen"] diff --git a/test_package/conanfile.py b/test_package/conanfile.py index 3b7b38de..2037d777 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -2,16 +2,12 @@ from conan import ConanFile from conan.tools.cmake import CMake, cmake_layout -from conan.tools.build import cross_building +from conan.tools.build import can_run -class CmaesTestConan(ConanFile): +class helloTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" - # VirtualBuildEnv and VirtualRunEnv can be avoided if "tools.env.virtualenv:auto_use" is defined - # (it will be defined in Conan 2.0) - generators = "CMakeDeps", "CMakeToolchain", "VirtualBuildEnv", "VirtualRunEnv" - apply_env = False - test_type = "explicit" + generators = "CMakeDeps", "CMakeToolchain" def requirements(self): self.requires(self.tested_reference_str) @@ -25,6 +21,7 @@ def layout(self): cmake_layout(self) def test(self): - if not cross_building(self): - cmd = os.path.join(self.cpp.build.bindirs[0], "example") + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "example") self.run(cmd, env="conanrun") + From 3f6a5bd0b5c8725ee25477a4249ed3d428f36f4a Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:34:33 +0200 Subject: [PATCH 14/48] Fix cmake target name --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 72d32c2c..17b025da 100644 --- a/conanfile.py +++ b/conanfile.py @@ -87,5 +87,5 @@ def package(self): def package_info(self): self.cpp_info.libs = ["cmaes"] - #self.cpp_info.set_property("cmake_target_aliases",["libcmaes::cmaes"]) + self.cpp_info.set_property("cmake_target_name","libcmaes::cmaes") #self.cpp_info.requires = ["eigen::eigen"] From 7640f168f8537147cbff25a78d0ef553671faedf Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:40:12 +0200 Subject: [PATCH 15/48] Add workflow for conan create --- .github/workflows/conan.yml | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/conan.yml diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml new file mode 100644 index 00000000..726ca6fd --- /dev/null +++ b/.github/workflows/conan.yml @@ -0,0 +1,38 @@ +name: Run conan + +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + +jobs: + conan: + strategy: + matrix: + setup: [ {os: ubuntu-latest}, {os: windows-latest}, {os: macos-latest}] + runs-on: ${{matrix.setup.os}} + if: "!contains(github.event.head_commit.message, 'skip-ci')" + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: actions/setup-python@v5 + with: + python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax + architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified + - name: Install conan + run: pip install conan>2 + + - run: conan create . \ No newline at end of file From c9d653930ad0664f24c7517fb8efcce8e44542ce Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Sat, 1 Jun 2024 23:43:14 +0200 Subject: [PATCH 16/48] Update conan.yml --- .github/workflows/conan.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index 726ca6fd..4def4186 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -20,8 +20,8 @@ jobs: conan: strategy: matrix: - setup: [ {os: ubuntu-latest}, {os: windows-latest}, {os: macos-latest}] - runs-on: ${{matrix.setup.os}} + os: [ ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{matrix.os}} if: "!contains(github.event.head_commit.message, 'skip-ci')" steps: @@ -35,4 +35,4 @@ jobs: - name: Install conan run: pip install conan>2 - - run: conan create . \ No newline at end of file + - run: conan create . From bb4a8500f07cf44069d0e54d43bd80cb1edc33b1 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:44:20 +0200 Subject: [PATCH 17/48] test workflow --- .github/workflows/conan.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index 4def4186..5af8a776 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -5,6 +5,7 @@ on: branches: - master - main + - conan pull_request: branches: - master From c80bce9948b2124d866dde2a1e225dddc372164d Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:45:35 +0200 Subject: [PATCH 18/48] run detect --- .github/workflows/conan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index 5af8a776..f00c450e 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -35,5 +35,5 @@ jobs: architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - name: Install conan run: pip install conan>2 - + - run: conan profile detect - run: conan create . From d4b334f0e26b1d5222f2748f90f8093928fc02a4 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:49:20 +0200 Subject: [PATCH 19/48] remove test branch --- .github/workflows/conan.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index f00c450e..124529ea 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -5,7 +5,6 @@ on: branches: - master - main - - conan pull_request: branches: - master From 41b1bf8a1e5c26c43590c4bfb51003ff978868e6 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:49:44 +0200 Subject: [PATCH 20/48] format with black --- conanfile.py | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/conanfile.py b/conanfile.py index 17b025da..94539325 100644 --- a/conanfile.py +++ b/conanfile.py @@ -7,6 +7,7 @@ from conan.tools.scm import Git + class CmaesConan(ConanFile): name = "libcmaes" @@ -22,38 +23,40 @@ class CmaesConan(ConanFile): # Binary configuration settings = "os", "compiler", "build_type", "arch" options = { - "shared": [True, False], + "shared": [True, False], "openmp": [True, False], - "surrog": [True, False] - } - default_options = { - "shared": True, - "openmp": True, - "surrog": True - } + "surrog": [True, False], + } + default_options = {"shared": True, "openmp": True, "surrog": True} # Sources are located in the same place as this recipe, copy them to the recipe - exports_sources = "CMakeLists.txt", "cmake/*", "include/*", "libcmaes-config.cmake.in", "src/*", "libcmaes.pc.in" + exports_sources = ( + "CMakeLists.txt", + "cmake/*", + "include/*", + "libcmaes-config.cmake.in", + "src/*", + "libcmaes.pc.in", + ) def build_requirements(self): pass def requirements(self): self.requires("eigen/3.4.0", transitive_headers=True) - def set_version(self): content = load(self, os.path.join(self.recipe_folder, "CMakeLists.txt")) - value=re.search(r"set\(libcmaes_VERSION (.*)\)", content) - extracted_version = value.group(1).strip() - + value = re.search(r"set\(libcmaes_VERSION (.*)\)", content) + extracted_version = value.group(1).strip() + is_git_tag = False - git = Git(self,folder=self.recipe_folder) + git = Git(self, folder=self.recipe_folder) try: git.run("describe --exact-match --tags") is_git_tag = True except Exception: - is_git_tag=False + is_git_tag = False if is_git_tag: self.version = extracted_version @@ -70,10 +73,10 @@ def layout(self): def generate(self): tc = CMakeToolchain(self) - tc.variables['LIBCMAES_BUILD_EXAMPLES']=False - tc.variables['LIBCMAES_BUILD_SHARED_LIBS']= self.options.shared - tc.variables['LIBCMAES_USE_OPENMP'] = self.options.openmp - tc.variables['LIBCMAES_ENABLE_SURROG'] = self.options.surrog + tc.variables["LIBCMAES_BUILD_EXAMPLES"] = False + tc.variables["LIBCMAES_BUILD_SHARED_LIBS"] = self.options.shared + tc.variables["LIBCMAES_USE_OPENMP"] = self.options.openmp + tc.variables["LIBCMAES_ENABLE_SURROG"] = self.options.surrog tc.generate() def build(self): @@ -87,5 +90,5 @@ def package(self): def package_info(self): self.cpp_info.libs = ["cmaes"] - self.cpp_info.set_property("cmake_target_name","libcmaes::cmaes") - #self.cpp_info.requires = ["eigen::eigen"] + self.cpp_info.set_property("cmake_target_name", "libcmaes::cmaes") + # self.cpp_info.requires = ["eigen::eigen"] From 2e330a8ba30d409ad635599208134fbd73019c6d Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sat, 1 Jun 2024 23:56:05 +0200 Subject: [PATCH 21/48] remove refreshenv --- .github/workflows/windows_unit_tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index d3a9c64d..4e5a92ea 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -23,8 +23,6 @@ jobs: architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - name: Install conan run: pip install conan numpy - - name: Refresh Shell - run: refreshenv - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores From e9b461df398d038a38d95b2f75a664717a190944 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:11:18 +0200 Subject: [PATCH 22/48] Rename test name so that cmake finds it --- .github/workflows/test.yml | 2 +- tests/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 59b0c572..57019d40 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ on: jobs: ubuntu-tests-fullSetup: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'skip-ci')" steps: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 11f2e9f9..87dafdab 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,7 +5,7 @@ macro (cmaes_add_test name) if(MSVC) target_compile_definitions(${name} PUBLIC _USE_MATH_DEFINES) endif() - add_test (NAME ${name} COMMAND t_${name}) + add_test (NAME ${name} COMMAND ${name}) if (WIN32) set_tests_properties ( ${name} From 0850f7eafd7a7a3bc4c7181f558700e199af38a9 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:12:53 +0200 Subject: [PATCH 23/48] fix mac os pip install --- .github/workflows/test-mac.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-mac.yml b/.github/workflows/test-mac.yml index 8ca0a90b..1683cd94 100644 --- a/.github/workflows/test-mac.yml +++ b/.github/workflows/test-mac.yml @@ -19,7 +19,7 @@ jobs: - name : installPackages run : brew install eigen boost boost-python3 libomp gflags - name : install python packages - run: pip3 install numpy + run: pip3 install numpy --break-system-packages - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores From e05092a158f307cb8d195175566a46130bbdf906 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:18:04 +0200 Subject: [PATCH 24/48] try to fix workflows --- .github/workflows/test-mac.yml | 2 +- .github/workflows/windows_unit_tests.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-mac.yml b/.github/workflows/test-mac.yml index 1683cd94..58969b77 100644 --- a/.github/workflows/test-mac.yml +++ b/.github/workflows/test-mac.yml @@ -19,7 +19,7 @@ jobs: - name : installPackages run : brew install eigen boost boost-python3 libomp gflags - name : install python packages - run: pip3 install numpy --break-system-packages + run: pip3 install numpy setuptools --break-system-packages - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 4e5a92ea..d7294f57 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -23,6 +23,7 @@ jobs: architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - name: Install conan run: pip install conan numpy + - run: conan profile detect - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores From 23a3e4aa1a5d5c9ee790efb147b9681a123d8547 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:21:23 +0200 Subject: [PATCH 25/48] update windows runner --- .github/workflows/windows_unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index d7294f57..17145aeb 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -10,7 +10,7 @@ on: jobs: windows-tests-fullSetup: - runs-on: windows-2019 + runs-on: windows-latest if: "!contains(github.event.head_commit.message, 'skip-ci')" steps: From 091483656f9792324c41e63b745cda1331ef54ad Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:30:55 +0200 Subject: [PATCH 26/48] use new conan provider file --- .github/workflows/windows_unit_tests.yml | 2 +- CMakeLists.txt | 32 - cmake/conan.cmake | 909 ----------------------- cmake/conan_provider.cmake | 649 ++++++++++++++++ 4 files changed, 650 insertions(+), 942 deletions(-) delete mode 100644 cmake/conan.cmake create mode 100644 cmake/conan_provider.cmake diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 17145aeb..0320f7c7 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -28,7 +28,7 @@ jobs: uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores - name: cmake - run: cmake -S . -B build -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DLIBCMAES_USE_CONAN=On -DCMAKE_BUILD_TYPE=Release + run: cmake -S . -B build -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=cmake/conan_provider.cmake -DCMAKE_BUILD_TYPE=Release - name: compile run: cd build && cmake --build . -j${{ steps.cpu-cores.outputs.count }} --config Release - name: Run ctest diff --git a/CMakeLists.txt b/CMakeLists.txt index 57fdbd33..df9926a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,38 +80,6 @@ if(LIBCMAES_BUILD_PYTHON) endif() -if(LIBCMAES_USE_CONAN) - list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) - include(conan) - set(ConanPkgList eigen/3.4.0) - set(ConanOptions "") - if(LIBCMAES_BUILD_PYTHON) - set(ConanPkgList ${ConanPkgList} - boost/1.78.0 - ) - set(ConanOptions ${ConanOptions} - boost:without_python=False - boost:python_version=${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} - boost:python_executable=${Python3_EXECUTABLE}) - endif(LIBCMAES_BUILD_PYTHON) - - if(LIBCMAES_BUILD_TESTS) - set(ConanPkgList ${ConanPkgList} gflags/2.2.2) - endif(LIBCMAES_BUILD_TESTS) - - conan_cmake_configure(REQUIRES ${ConanPkgList} - GENERATORS cmake_find_package - OPTIONS ${ConanOptions}) - - - conan_cmake_autodetect(settings) - - conan_cmake_install(PATH_OR_REFERENCE . - BUILD missing - REMOTE conancenter - SETTINGS ${settings}) -endif() - find_package (Eigen3 3.0.0 REQUIRED) if (LIBCMAES_USE_OPENMP) diff --git a/cmake/conan.cmake b/cmake/conan.cmake deleted file mode 100644 index 208ce248..00000000 --- a/cmake/conan.cmake +++ /dev/null @@ -1,909 +0,0 @@ -# The MIT License (MIT) - -# Copyright (c) 2018 JFrog - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - - -# This file comes from: https://github.com/conan-io/cmake-conan. Please refer -# to this repository for issues and documentation. - -# Its purpose is to wrap and launch Conan C/C++ Package Manager when cmake is called. -# It will take CMake current settings (os, compiler, compiler version, architecture) -# and translate them to conan settings for installing and retrieving dependencies. - -# It is intended to facilitate developers building projects that have conan dependencies, -# but it is only necessary on the end-user side. It is not necessary to create conan -# packages, in fact it shouldn't be use for that. Check the project documentation. - -# version: 0.18.0-dev - -include(CMakeParseArguments) - -function(_get_msvc_ide_version result) - set(${result} "" PARENT_SCOPE) - if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500) - set(${result} 8 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600) - set(${result} 9 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700) - set(${result} 10 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800) - set(${result} 11 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900) - set(${result} 12 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 1910) - set(${result} 14 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1910 AND MSVC_VERSION VERSION_LESS 1920) - set(${result} 15 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) - set(${result} 16 PARENT_SCOPE) - elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940) - set(${result} 17 PARENT_SCOPE) - else() - message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") - endif() -endfunction() - -macro(_conan_detect_build_type) - conan_parse_arguments(${ARGV}) - - if(ARGUMENTS_BUILD_TYPE) - set(_CONAN_SETTING_BUILD_TYPE ${ARGUMENTS_BUILD_TYPE}) - elseif(CMAKE_BUILD_TYPE) - set(_CONAN_SETTING_BUILD_TYPE ${CMAKE_BUILD_TYPE}) - else() - message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") - endif() - - string(TOUPPER ${_CONAN_SETTING_BUILD_TYPE} _CONAN_SETTING_BUILD_TYPE_UPPER) - if (_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "DEBUG") - set(_CONAN_SETTING_BUILD_TYPE "Debug") - elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELEASE") - set(_CONAN_SETTING_BUILD_TYPE "Release") - elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELWITHDEBINFO") - set(_CONAN_SETTING_BUILD_TYPE "RelWithDebInfo") - elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "MINSIZEREL") - set(_CONAN_SETTING_BUILD_TYPE "MinSizeRel") - endif() -endmacro() - -macro(_conan_check_system_name) - #handle -s os setting - if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") - #use default conan os setting if CMAKE_SYSTEM_NAME is not defined - set(CONAN_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) - if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") - set(CONAN_SYSTEM_NAME Macos) - endif() - if(${CMAKE_SYSTEM_NAME} STREQUAL "QNX") - set(CONAN_SYSTEM_NAME Neutrino) - endif() - set(CONAN_SUPPORTED_PLATFORMS Windows Linux Macos Android iOS FreeBSD WindowsStore WindowsCE watchOS tvOS FreeBSD SunOS AIX Arduino Emscripten Neutrino) - list (FIND CONAN_SUPPORTED_PLATFORMS "${CONAN_SYSTEM_NAME}" _index) - if (${_index} GREATER -1) - #check if the cmake system is a conan supported one - set(_CONAN_SETTING_OS ${CONAN_SYSTEM_NAME}) - else() - message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}") - endif() - endif() -endmacro() - -macro(_conan_check_language) - get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) - if (";${_languages};" MATCHES ";CXX;") - set(LANGUAGE CXX) - set(USING_CXX 1) - elseif (";${_languages};" MATCHES ";C;") - set(LANGUAGE C) - set(USING_CXX 0) - else () - message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") - endif() -endmacro() - -macro(_conan_detect_compiler) - - conan_parse_arguments(${ARGV}) - - if(ARGUMENTS_ARCH) - set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH}) - endif() - - if(USING_CXX) - set(_CONAN_SETTING_COMPILER_CPPSTD ${CMAKE_CXX_STANDARD}) - endif() - - if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) - # using GCC - # TODO: Handle other params - string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) - list(GET VERSION_LIST 0 MAJOR) - list(GET VERSION_LIST 1 MINOR) - set(COMPILER_VERSION ${MAJOR}.${MINOR}) - if(${MAJOR} GREATER 4) - set(COMPILER_VERSION ${MAJOR}) - endif() - set(_CONAN_SETTING_COMPILER gcc) - set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) - if (USING_CXX) - conan_cmake_detect_unix_libcxx(_LIBCXX) - set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) - endif () - elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Intel) - string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) - list(GET VERSION_LIST 0 MAJOR) - list(GET VERSION_LIST 1 MINOR) - set(COMPILER_VERSION ${MAJOR}.${MINOR}) - set(_CONAN_SETTING_COMPILER intel) - set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) - if (USING_CXX) - conan_cmake_detect_unix_libcxx(_LIBCXX) - set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) - endif () - elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) - # using AppleClang - string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) - list(GET VERSION_LIST 0 MAJOR) - list(GET VERSION_LIST 1 MINOR) - set(_CONAN_SETTING_COMPILER apple-clang) - set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) - if (USING_CXX) - conan_cmake_detect_unix_libcxx(_LIBCXX) - set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) - endif () - elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) - string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) - list(GET VERSION_LIST 0 MAJOR) - list(GET VERSION_LIST 1 MINOR) - set(_CONAN_SETTING_COMPILER clang) - set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) - if(APPLE) - cmake_policy(GET CMP0025 APPLE_CLANG_POLICY) - if(NOT APPLE_CLANG_POLICY STREQUAL NEW) - message(STATUS "Conan: APPLE and Clang detected. Assuming apple-clang compiler. Set CMP0025 to avoid it") - set(_CONAN_SETTING_COMPILER apple-clang) - endif() - endif() - if(${_CONAN_SETTING_COMPILER} STREQUAL clang AND ${MAJOR} GREATER 7) - set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}) - endif() - if (USING_CXX) - conan_cmake_detect_unix_libcxx(_LIBCXX) - set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) - endif () - elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) - set(_VISUAL "Visual Studio") - _get_msvc_ide_version(_VISUAL_VERSION) - if("${_VISUAL_VERSION}" STREQUAL "") - message(FATAL_ERROR "Conan: Visual Studio not recognized") - else() - set(_CONAN_SETTING_COMPILER ${_VISUAL}) - set(_CONAN_SETTING_COMPILER_VERSION ${_VISUAL_VERSION}) - endif() - - if(NOT _CONAN_SETTING_ARCH) - if (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "64") - set(_CONAN_SETTING_ARCH x86_64) - elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "^ARM") - message(STATUS "Conan: Using default ARM architecture from MSVC") - set(_CONAN_SETTING_ARCH armv6) - elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "86") - set(_CONAN_SETTING_ARCH x86) - else () - message(FATAL_ERROR "Conan: Unknown MSVC architecture [${MSVC_${LANGUAGE}_ARCHITECTURE_ID}]") - endif() - endif() - - conan_cmake_detect_vs_runtime(_vs_runtime ${ARGV}) - message(STATUS "Conan: Detected VS runtime: ${_vs_runtime}") - set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime}) - - if (CMAKE_GENERATOR_TOOLSET) - set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) - elseif(CMAKE_VS_PLATFORM_TOOLSET AND (CMAKE_GENERATOR STREQUAL "Ninja")) - set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) - endif() - else() - message(FATAL_ERROR "Conan: compiler setup not recognized") - endif() - -endmacro() - -function(conan_cmake_settings result) - #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER}) - #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID}) - #message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION}) - #message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS}) - #message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE}) - #message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE}) - #message(STATUS "GENERATOR " ${CMAKE_GENERATOR}) - #message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64}) - - message(STATUS "Conan: Automatic detection of conan settings from cmake") - - conan_parse_arguments(${ARGV}) - - _conan_detect_build_type(${ARGV}) - - _conan_check_system_name() - - _conan_check_language() - - _conan_detect_compiler(${ARGV}) - - # If profile is defined it is used - if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) - set(_APPLIED_PROFILES ${ARGUMENTS_DEBUG_PROFILE}) - elseif(CMAKE_BUILD_TYPE STREQUAL "Release" AND ARGUMENTS_RELEASE_PROFILE) - set(_APPLIED_PROFILES ${ARGUMENTS_RELEASE_PROFILE}) - elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND ARGUMENTS_RELWITHDEBINFO_PROFILE) - set(_APPLIED_PROFILES ${ARGUMENTS_RELWITHDEBINFO_PROFILE}) - elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" AND ARGUMENTS_MINSIZEREL_PROFILE) - set(_APPLIED_PROFILES ${ARGUMENTS_MINSIZEREL_PROFILE}) - elseif(ARGUMENTS_PROFILE) - set(_APPLIED_PROFILES ${ARGUMENTS_PROFILE}) - endif() - - foreach(ARG ${_APPLIED_PROFILES}) - set(_SETTINGS ${_SETTINGS} -pr=${ARG}) - endforeach() - foreach(ARG ${ARGUMENTS_PROFILE_BUILD}) - conan_check(VERSION 1.24.0 REQUIRED DETECT_QUIET) - set(_SETTINGS ${_SETTINGS} -pr:b=${ARG}) - endforeach() - - if(NOT _SETTINGS OR ARGUMENTS_PROFILE_AUTO STREQUAL "ALL") - set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version - compiler.runtime compiler.libcxx compiler.toolset) - endif() - - # remove any manually specified settings from the autodetected settings - foreach(ARG ${ARGUMENTS_SETTINGS}) - string(REGEX MATCH "[^=]*" MANUAL_SETTING "${ARG}") - message(STATUS "Conan: ${MANUAL_SETTING} was added as an argument. Not using the autodetected one.") - list(REMOVE_ITEM ARGUMENTS_PROFILE_AUTO "${MANUAL_SETTING}") - endforeach() - - # Automatic from CMake - foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) - string(TOUPPER ${ARG} _arg_name) - string(REPLACE "." "_" _arg_name ${_arg_name}) - if(_CONAN_SETTING_${_arg_name}) - set(_SETTINGS ${_SETTINGS} -s ${ARG}=${_CONAN_SETTING_${_arg_name}}) - endif() - endforeach() - - foreach(ARG ${ARGUMENTS_SETTINGS}) - set(_SETTINGS ${_SETTINGS} -s ${ARG}) - endforeach() - - message(STATUS "Conan: Settings= ${_SETTINGS}") - - set(${result} ${_SETTINGS} PARENT_SCOPE) -endfunction() - - -function(conan_cmake_detect_unix_libcxx result) - # Take into account any -stdlib in compile options - get_directory_property(compile_options DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS) - string(GENEX_STRIP "${compile_options}" compile_options) - - # Take into account any _GLIBCXX_USE_CXX11_ABI in compile definitions - get_directory_property(defines DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS) - string(GENEX_STRIP "${defines}" defines) - - foreach(define ${defines}) - if(define MATCHES "_GLIBCXX_USE_CXX11_ABI") - if(define MATCHES "^-D") - set(compile_options ${compile_options} "${define}") - else() - set(compile_options ${compile_options} "-D${define}") - endif() - endif() - endforeach() - - # add additional compiler options ala cmRulePlaceholderExpander::ExpandRuleVariable - set(EXPAND_CXX_COMPILER ${CMAKE_CXX_COMPILER}) - if(CMAKE_CXX_COMPILER_ARG1) - # CMake splits CXX="foo bar baz" into CMAKE_CXX_COMPILER="foo", CMAKE_CXX_COMPILER_ARG1="bar baz" - # without this, ccache, winegcc, or other wrappers might lose all their arguments - separate_arguments(SPLIT_CXX_COMPILER_ARG1 NATIVE_COMMAND ${CMAKE_CXX_COMPILER_ARG1}) - list(APPEND EXPAND_CXX_COMPILER ${SPLIT_CXX_COMPILER_ARG1}) - endif() - - if(CMAKE_CXX_COMPILE_OPTIONS_TARGET AND CMAKE_CXX_COMPILER_TARGET) - # without --target= we may be calling the wrong underlying GCC - list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_TARGET}${CMAKE_CXX_COMPILER_TARGET}") - endif() - - if(CMAKE_CXX_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN AND CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN) - list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN}${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}") - endif() - - if(CMAKE_CXX_COMPILE_OPTIONS_SYSROOT) - # without --sysroot= we may find the wrong #include - if(CMAKE_SYSROOT_COMPILE) - list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_SYSROOT}${CMAKE_SYSROOT_COMPILE}") - elseif(CMAKE_SYSROOT) - list(APPEND EXPAND_CXX_COMPILER "${CMAKE_CXX_COMPILE_OPTIONS_SYSROOT}${CMAKE_SYSROOT}") - endif() - endif() - - separate_arguments(SPLIT_CXX_FLAGS NATIVE_COMMAND ${CMAKE_CXX_FLAGS}) - - if(CMAKE_OSX_SYSROOT) - set(xcode_sysroot_option "--sysroot=${CMAKE_OSX_SYSROOT}") - endif() - - execute_process( - COMMAND ${CMAKE_COMMAND} -E echo "#include " - COMMAND ${EXPAND_CXX_COMPILER} ${SPLIT_CXX_FLAGS} -x c++ ${xcode_sysroot_option} ${compile_options} -E -dM - - OUTPUT_VARIABLE string_defines - ) - - if(string_defines MATCHES "#define __GLIBCXX__") - # Allow -D_GLIBCXX_USE_CXX11_ABI=ON/OFF as argument to cmake - if(DEFINED _GLIBCXX_USE_CXX11_ABI) - if(_GLIBCXX_USE_CXX11_ABI) - set(${result} libstdc++11 PARENT_SCOPE) - return() - else() - set(${result} libstdc++ PARENT_SCOPE) - return() - endif() - endif() - - if(string_defines MATCHES "#define _GLIBCXX_USE_CXX11_ABI 1\n") - set(${result} libstdc++11 PARENT_SCOPE) - else() - # Either the compiler is missing the define because it is old, and so - # it can't use the new abi, or the compiler was configured to use the - # old abi by the user or distro (e.g. devtoolset on RHEL/CentOS) - set(${result} libstdc++ PARENT_SCOPE) - endif() - else() - set(${result} libc++ PARENT_SCOPE) - endif() -endfunction() - -function(conan_cmake_detect_vs_runtime result) - - conan_parse_arguments(${ARGV}) - if(ARGUMENTS_BUILD_TYPE) - set(build_type "${ARGUMENTS_BUILD_TYPE}") - elseif(CMAKE_BUILD_TYPE) - set(build_type "${CMAKE_BUILD_TYPE}") - else() - message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") - endif() - - if(build_type) - string(TOUPPER "${build_type}" build_type) - endif() - set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS) - foreach(variable ${variables}) - if(NOT "${${variable}}" STREQUAL "") - string(REPLACE " " ";" flags "${${variable}}") - foreach (flag ${flags}) - if("${flag}" STREQUAL "/MD" OR "${flag}" STREQUAL "/MDd" OR "${flag}" STREQUAL "/MT" OR "${flag}" STREQUAL "/MTd") - string(SUBSTRING "${flag}" 1 -1 runtime) - set(${result} "${runtime}" PARENT_SCOPE) - return() - endif() - endforeach() - endif() - endforeach() - if("${build_type}" STREQUAL "DEBUG") - set(${result} "MDd" PARENT_SCOPE) - else() - set(${result} "MD" PARENT_SCOPE) - endif() -endfunction() - -function(_collect_settings result) - set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version - compiler.runtime compiler.libcxx compiler.toolset - compiler.cppstd) - foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) - string(TOUPPER ${ARG} _arg_name) - string(REPLACE "." "_" _arg_name ${_arg_name}) - if(_CONAN_SETTING_${_arg_name}) - set(detected_setings ${detected_setings} ${ARG}=${_CONAN_SETTING_${_arg_name}}) - endif() - endforeach() - set(${result} ${detected_setings} PARENT_SCOPE) -endfunction() - -function(conan_cmake_autodetect detected_settings) - _conan_detect_build_type(${ARGV}) - _conan_check_system_name() - _conan_check_language() - _conan_detect_compiler(${ARGV}) - _collect_settings(collected_settings) - set(${detected_settings} ${collected_settings} PARENT_SCOPE) -endfunction() - -macro(conan_parse_arguments) - set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_LOAD NO_OUTPUT_DIRS OUTPUT_QUIET NO_IMPORTS SKIP_STD) - set(oneValueArgs CONANFILE ARCH BUILD_TYPE INSTALL_FOLDER CONAN_COMMAND) - set(multiValueArgs DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE - PROFILE REQUIRES OPTIONS IMPORTS SETTINGS BUILD ENV GENERATORS PROFILE_AUTO - INSTALL_ARGS CONFIGURATION_TYPES PROFILE_BUILD BUILD_REQUIRES) - cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) -endmacro() - -function(old_conan_cmake_install) - # Calls "conan install" - # Argument BUILD is equivalant to --build={missing, PkgName,...} or - # --build when argument is 'BUILD all' (which builds all packages from source) - # Argument CONAN_COMMAND, to specify the conan path, e.g. in case of running from source - # cmake does not identify conan as command, even if it is +x and it is in the path - conan_parse_arguments(${ARGV}) - - if(CONAN_CMAKE_MULTI) - set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake_multi) - else() - set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake) - endif() - - set(CONAN_BUILD_POLICY "") - foreach(ARG ${ARGUMENTS_BUILD}) - if(${ARG} STREQUAL "all") - set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build) - break() - else() - set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build=${ARG}) - endif() - endforeach() - if(ARGUMENTS_CONAN_COMMAND) - set(CONAN_CMD ${ARGUMENTS_CONAN_COMMAND}) - else() - conan_check(REQUIRED) - endif() - set(CONAN_OPTIONS "") - if(ARGUMENTS_CONANFILE) - if(IS_ABSOLUTE ${ARGUMENTS_CONANFILE}) - set(CONANFILE ${ARGUMENTS_CONANFILE}) - else() - set(CONANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) - endif() - else() - set(CONANFILE ".") - endif() - foreach(ARG ${ARGUMENTS_OPTIONS}) - set(CONAN_OPTIONS ${CONAN_OPTIONS} -o=${ARG}) - endforeach() - if(ARGUMENTS_UPDATE) - set(CONAN_INSTALL_UPDATE --update) - endif() - if(ARGUMENTS_NO_IMPORTS) - set(CONAN_INSTALL_NO_IMPORTS --no-imports) - endif() - set(CONAN_INSTALL_FOLDER "") - if(ARGUMENTS_INSTALL_FOLDER) - set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER}) - endif() - foreach(ARG ${ARGUMENTS_GENERATORS}) - set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG}) - endforeach() - foreach(ARG ${ARGUMENTS_ENV}) - set(CONAN_ENV_VARS ${CONAN_ENV_VARS} -e=${ARG}) - endforeach() - set(conan_args install ${CONANFILE} ${settings} ${CONAN_ENV_VARS} ${CONAN_GENERATORS} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE} ${CONAN_INSTALL_NO_IMPORTS} ${CONAN_OPTIONS} ${CONAN_INSTALL_FOLDER} ${ARGUMENTS_INSTALL_ARGS}) - - string (REPLACE ";" " " _conan_args "${conan_args}") - message(STATUS "Conan executing: ${CONAN_CMD} ${_conan_args}") - - if(ARGUMENTS_OUTPUT_QUIET) - execute_process(COMMAND ${CONAN_CMD} ${conan_args} - RESULT_VARIABLE return_code - OUTPUT_VARIABLE conan_output - ERROR_VARIABLE conan_output - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - else() - execute_process(COMMAND ${CONAN_CMD} ${conan_args} - RESULT_VARIABLE return_code - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - endif() - - if(NOT "${return_code}" STREQUAL "0") - message(FATAL_ERROR "Conan install failed='${return_code}'") - endif() - -endfunction() - -function(conan_cmake_install) - if(DEFINED CONAN_COMMAND) - set(CONAN_CMD ${CONAN_COMMAND}) - else() - conan_check(REQUIRED) - endif() - - set(installOptions UPDATE NO_IMPORTS OUTPUT_QUIET ERROR_QUIET) - set(installOneValueArgs PATH_OR_REFERENCE REFERENCE REMOTE LOCKFILE LOCKFILE_OUT LOCKFILE_NODE_ID INSTALL_FOLDER) - set(installMultiValueArgs GENERATOR BUILD ENV ENV_HOST ENV_BUILD OPTIONS_HOST OPTIONS OPTIONS_BUILD PROFILE - PROFILE_HOST PROFILE_BUILD SETTINGS SETTINGS_HOST SETTINGS_BUILD) - cmake_parse_arguments(ARGS "${installOptions}" "${installOneValueArgs}" "${installMultiValueArgs}" ${ARGN}) - foreach(arg ${installOptions}) - if(ARGS_${arg}) - set(${arg} ${${arg}} ${ARGS_${arg}}) - endif() - endforeach() - foreach(arg ${installOneValueArgs}) - if(DEFINED ARGS_${arg}) - if("${arg}" STREQUAL "REMOTE") - set(flag "--remote") - elseif("${arg}" STREQUAL "LOCKFILE") - set(flag "--lockfile") - elseif("${arg}" STREQUAL "LOCKFILE_OUT") - set(flag "--lockfile-out") - elseif("${arg}" STREQUAL "LOCKFILE_NODE_ID") - set(flag "--lockfile-node-id") - elseif("${arg}" STREQUAL "INSTALL_FOLDER") - set(flag "--install-folder") - endif() - set(${arg} ${${arg}} ${flag} ${ARGS_${arg}}) - endif() - endforeach() - foreach(arg ${installMultiValueArgs}) - if(DEFINED ARGS_${arg}) - if("${arg}" STREQUAL "GENERATOR") - set(flag "--generator") - elseif("${arg}" STREQUAL "BUILD") - set(flag "--build") - elseif("${arg}" STREQUAL "ENV") - set(flag "--env") - elseif("${arg}" STREQUAL "ENV_HOST") - set(flag "--env:host") - elseif("${arg}" STREQUAL "ENV_BUILD") - set(flag "--env:build") - elseif("${arg}" STREQUAL "OPTIONS") - set(flag "--options") - elseif("${arg}" STREQUAL "OPTIONS_HOST") - set(flag "--options:host") - elseif("${arg}" STREQUAL "OPTIONS_BUILD") - set(flag "--options:build") - elseif("${arg}" STREQUAL "PROFILE") - set(flag "--profile") - elseif("${arg}" STREQUAL "PROFILE_HOST") - set(flag "--profile:host") - elseif("${arg}" STREQUAL "PROFILE_BUILD") - set(flag "--profile:build") - elseif("${arg}" STREQUAL "SETTINGS") - set(flag "--settings") - elseif("${arg}" STREQUAL "SETTINGS_HOST") - set(flag "--settings:host") - elseif("${arg}" STREQUAL "SETTINGS_BUILD") - set(flag "--settings:build") - endif() - list(LENGTH ARGS_${arg} numargs) - foreach(item ${ARGS_${arg}}) - if(${item} STREQUAL "all" AND ${arg} STREQUAL "BUILD") - set(${arg} "--build") - break() - endif() - set(${arg} ${${arg}} ${flag} ${item}) - endforeach() - endif() - endforeach() - if(DEFINED UPDATE) - set(UPDATE --update) - endif() - if(DEFINED NO_IMPORTS) - set(NO_IMPORTS --no-imports) - endif() - set(install_args install ${PATH_OR_REFERENCE} ${REFERENCE} ${UPDATE} ${NO_IMPORTS} ${REMOTE} ${LOCKFILE} ${LOCKFILE_OUT} ${LOCKFILE_NODE_ID} ${INSTALL_FOLDER} - ${GENERATOR} ${BUILD} ${ENV} ${ENV_HOST} ${ENV_BUILD} ${OPTIONS} ${OPTIONS_HOST} ${OPTIONS_BUILD} - ${PROFILE} ${PROFILE_HOST} ${PROFILE_BUILD} ${SETTINGS} ${SETTINGS_HOST} ${SETTINGS_BUILD}) - - string(REPLACE ";" " " _install_args "${install_args}") - message(STATUS "Conan executing: ${CONAN_CMD} ${_install_args}") - - if(ARGS_OUTPUT_QUIET) - set(OUTPUT_OPT OUTPUT_QUIET) - endif() - if(ARGS_ERROR_QUIET) - set(ERROR_OPT ERROR_QUIET) - endif() - - execute_process(COMMAND ${CONAN_CMD} ${install_args} - RESULT_VARIABLE return_code - ${OUTPUT_OPT} - ${ERROR_OPT} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - - if(NOT "${return_code}" STREQUAL "0") - if (ARGS_ERROR_QUIET) - message(WARNING "Conan install failed='${return_code}'") - else() - message(FATAL_ERROR "Conan install failed='${return_code}'") - endif() - endif() - -endfunction() - -function(conan_cmake_setup_conanfile) - conan_parse_arguments(${ARGV}) - if(ARGUMENTS_CONANFILE) - get_filename_component(_CONANFILE_NAME ${ARGUMENTS_CONANFILE} NAME) - # configure_file will make sure cmake re-runs when conanfile is updated - configure_file(${ARGUMENTS_CONANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk COPYONLY) - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk) - else() - conan_cmake_generate_conanfile(ON ${ARGV}) - endif() -endfunction() - -function(conan_cmake_configure) - conan_cmake_generate_conanfile(OFF ${ARGV}) -endfunction() - -# Generate, writing in disk a conanfile.txt with the requires, options, and imports -# specified as arguments -# This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) -function(conan_cmake_generate_conanfile DEFAULT_GENERATOR) - - conan_parse_arguments(${ARGV}) - - set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") - file(WRITE ${_FN} "") - - if(DEFINED ARGUMENTS_REQUIRES) - file(APPEND ${_FN} "[requires]\n") - foreach(REQUIRE ${ARGUMENTS_REQUIRES}) - file(APPEND ${_FN} ${REQUIRE} "\n") - endforeach() - endif() - - if (DEFAULT_GENERATOR OR DEFINED ARGUMENTS_GENERATORS) - file(APPEND ${_FN} "[generators]\n") - if (DEFAULT_GENERATOR) - file(APPEND ${_FN} "cmake\n") - endif() - if (DEFINED ARGUMENTS_GENERATORS) - foreach(GENERATOR ${ARGUMENTS_GENERATORS}) - file(APPEND ${_FN} ${GENERATOR} "\n") - endforeach() - endif() - endif() - - if(DEFINED ARGUMENTS_BUILD_REQUIRES) - file(APPEND ${_FN} "[build_requires]\n") - foreach(BUILD_REQUIRE ${ARGUMENTS_BUILD_REQUIRES}) - file(APPEND ${_FN} ${BUILD_REQUIRE} "\n") - endforeach() - endif() - - if(DEFINED ARGUMENTS_IMPORTS) - file(APPEND ${_FN} "[imports]\n") - foreach(IMPORTS ${ARGUMENTS_IMPORTS}) - file(APPEND ${_FN} ${IMPORTS} "\n") - endforeach() - endif() - - if(DEFINED ARGUMENTS_OPTIONS) - file(APPEND ${_FN} "[options]\n") - foreach(OPTION ${ARGUMENTS_OPTIONS}) - file(APPEND ${_FN} ${OPTION} "\n") - endforeach() - endif() - -endfunction() - - -macro(conan_load_buildinfo) - if(CONAN_CMAKE_MULTI) - set(_CONANBUILDINFO conanbuildinfo_multi.cmake) - else() - set(_CONANBUILDINFO conanbuildinfo.cmake) - endif() - if(ARGUMENTS_INSTALL_FOLDER) - set(_CONANBUILDINFOFOLDER ${ARGUMENTS_INSTALL_FOLDER}) - else() - set(_CONANBUILDINFOFOLDER ${CMAKE_CURRENT_BINARY_DIR}) - endif() - # Checks for the existence of conanbuildinfo.cmake, and loads it - # important that it is macro, so variables defined at parent scope - if(EXISTS "${_CONANBUILDINFOFOLDER}/${_CONANBUILDINFO}") - message(STATUS "Conan: Loading ${_CONANBUILDINFO}") - include(${_CONANBUILDINFOFOLDER}/${_CONANBUILDINFO}) - else() - message(FATAL_ERROR "${_CONANBUILDINFO} doesn't exist in ${CMAKE_CURRENT_BINARY_DIR}") - endif() -endmacro() - - -macro(conan_cmake_run) - conan_parse_arguments(${ARGV}) - - if(ARGUMENTS_CONFIGURATION_TYPES AND NOT CMAKE_CONFIGURATION_TYPES) - message(WARNING "CONFIGURATION_TYPES should only be specified for multi-configuration generators") - elseif(ARGUMENTS_CONFIGURATION_TYPES AND ARGUMENTS_BUILD_TYPE) - message(WARNING "CONFIGURATION_TYPES and BUILD_TYPE arguments should not be defined at the same time.") - endif() - - if(CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE AND NOT CONAN_EXPORTED - AND NOT ARGUMENTS_BUILD_TYPE) - set(CONAN_CMAKE_MULTI ON) - if (NOT ARGUMENTS_CONFIGURATION_TYPES) - set(ARGUMENTS_CONFIGURATION_TYPES "Release;Debug") - endif() - message(STATUS "Conan: Using cmake-multi generator") - else() - set(CONAN_CMAKE_MULTI OFF) - endif() - - if(NOT CONAN_EXPORTED) - conan_cmake_setup_conanfile(${ARGV}) - if(CONAN_CMAKE_MULTI) - foreach(CMAKE_BUILD_TYPE ${ARGUMENTS_CONFIGURATION_TYPES}) - set(ENV{CONAN_IMPORT_PATH} ${CMAKE_BUILD_TYPE}) - conan_cmake_settings(settings ${ARGV}) - old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) - endforeach() - set(CMAKE_BUILD_TYPE) - else() - conan_cmake_settings(settings ${ARGV}) - old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) - endif() - endif() - - if (NOT ARGUMENTS_NO_LOAD) - conan_load_buildinfo() - endif() - - if(ARGUMENTS_BASIC_SETUP) - foreach(_option CMAKE_TARGETS KEEP_RPATHS NO_OUTPUT_DIRS SKIP_STD) - if(ARGUMENTS_${_option}) - if(${_option} STREQUAL "CMAKE_TARGETS") - list(APPEND _setup_options "TARGETS") - else() - list(APPEND _setup_options ${_option}) - endif() - endif() - endforeach() - conan_basic_setup(${_setup_options}) - endif() -endmacro() - -macro(conan_check) - # Checks conan availability in PATH - # Arguments REQUIRED, DETECT_QUIET and VERSION are optional - # Example usage: - # conan_check(VERSION 1.0.0 REQUIRED) - set(options REQUIRED DETECT_QUIET) - set(oneValueArgs VERSION) - cmake_parse_arguments(CONAN "${options}" "${oneValueArgs}" "" ${ARGN}) - if(NOT CONAN_DETECT_QUIET) - message(STATUS "Conan: checking conan executable") - endif() - - find_program(CONAN_CMD conan) - if(NOT CONAN_CMD AND CONAN_REQUIRED) - message(FATAL_ERROR "Conan executable not found! Please install conan.") - endif() - if(NOT CONAN_DETECT_QUIET) - message(STATUS "Conan: Found program ${CONAN_CMD}") - endif() - execute_process(COMMAND ${CONAN_CMD} --version - RESULT_VARIABLE return_code - OUTPUT_VARIABLE CONAN_VERSION_OUTPUT - ERROR_VARIABLE CONAN_VERSION_OUTPUT) - - if(NOT "${return_code}" STREQUAL "0") - message(FATAL_ERROR "Conan --version failed='${return_code}'") - endif() - - if(NOT CONAN_DETECT_QUIET) - string(STRIP "${CONAN_VERSION_OUTPUT}" _CONAN_VERSION_OUTPUT) - message(STATUS "Conan: Version found ${_CONAN_VERSION_OUTPUT}") - endif() - - if(DEFINED CONAN_VERSION) - string(REGEX MATCH ".*Conan version ([0-9]+\\.[0-9]+\\.[0-9]+)" FOO - "${CONAN_VERSION_OUTPUT}") - if(${CMAKE_MATCH_1} VERSION_LESS ${CONAN_VERSION}) - message(FATAL_ERROR "Conan outdated. Installed: ${CMAKE_MATCH_1}, \ - required: ${CONAN_VERSION}. Consider updating via 'pip \ - install conan==${CONAN_VERSION}'.") - endif() - endif() -endmacro() - -function(conan_add_remote) - # Adds a remote - # Arguments URL and NAME are required, INDEX, COMMAND and VERIFY_SSL are optional - # Example usage: - # conan_add_remote(NAME bincrafters INDEX 1 - # URL https://api.bintray.com/conan/bincrafters/public-conan - # VERIFY_SSL True) - set(oneValueArgs URL NAME INDEX COMMAND VERIFY_SSL) - cmake_parse_arguments(CONAN "" "${oneValueArgs}" "" ${ARGN}) - - if(DEFINED CONAN_INDEX) - set(CONAN_INDEX_ARG "-i ${CONAN_INDEX}") - endif() - if(DEFINED CONAN_COMMAND) - set(CONAN_CMD ${CONAN_COMMAND}) - else() - conan_check(REQUIRED DETECT_QUIET) - endif() - set(CONAN_VERIFY_SSL_ARG "True") - if(DEFINED CONAN_VERIFY_SSL) - set(CONAN_VERIFY_SSL_ARG ${CONAN_VERIFY_SSL}) - endif() - message(STATUS "Conan: Adding ${CONAN_NAME} remote repository (${CONAN_URL}) verify ssl (${CONAN_VERIFY_SSL_ARG})") - execute_process(COMMAND ${CONAN_CMD} remote add ${CONAN_NAME} ${CONAN_INDEX_ARG} -f ${CONAN_URL} ${CONAN_VERIFY_SSL_ARG} - RESULT_VARIABLE return_code) - if(NOT "${return_code}" STREQUAL "0") - message(FATAL_ERROR "Conan remote failed='${return_code}'") - endif() -endfunction() - -macro(conan_config_install) - # install a full configuration from a local or remote zip file - # Argument ITEM is required, arguments TYPE, SOURCE, TARGET and VERIFY_SSL are optional - # Example usage: - # conan_config_install(ITEM https://github.com/conan-io/cmake-conan.git - # TYPE git SOURCE source-folder TARGET target-folder VERIFY_SSL false) - set(oneValueArgs ITEM TYPE SOURCE TARGET VERIFY_SSL) - set(multiValueArgs ARGS) - cmake_parse_arguments(CONAN "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - find_program(CONAN_CMD conan) - if(NOT CONAN_CMD AND CONAN_REQUIRED) - message(FATAL_ERROR "Conan executable not found!") - endif() - - if(DEFINED CONAN_VERIFY_SSL) - set(CONAN_VERIFY_SSL_ARG "--verify-ssl=${CONAN_VERIFY_SSL}") - endif() - - if(DEFINED CONAN_TYPE) - set(CONAN_TYPE_ARG "--type=${CONAN_TYPE}") - endif() - - if(DEFINED CONAN_ARGS) - set(CONAN_ARGS_ARGS "--args=\"${CONAN_ARGS}\"") - endif() - - if(DEFINED CONAN_SOURCE) - set(CONAN_SOURCE_ARGS "--source-folder=${CONAN_SOURCE}") - endif() - - if(DEFINED CONAN_TARGET) - set(CONAN_TARGET_ARGS "--target-folder=${CONAN_TARGET}") - endif() - - set (CONAN_CONFIG_INSTALL_ARGS ${CONAN_VERIFY_SSL_ARG} - ${CONAN_TYPE_ARG} - ${CONAN_ARGS_ARGS} - ${CONAN_SOURCE_ARGS} - ${CONAN_TARGET_ARGS}) - - message(STATUS "Conan: Installing config from ${CONAN_ITEM}") - execute_process(COMMAND ${CONAN_CMD} config install ${CONAN_ITEM} ${CONAN_CONFIG_INSTALL_ARGS} - RESULT_VARIABLE return_code) - if(NOT "${return_code}" STREQUAL "0") - message(FATAL_ERROR "Conan config failed='${return_code}'") - endif() -endmacro() diff --git a/cmake/conan_provider.cmake b/cmake/conan_provider.cmake new file mode 100644 index 00000000..6bf31b18 --- /dev/null +++ b/cmake/conan_provider.cmake @@ -0,0 +1,649 @@ +# The MIT License (MIT) +# +# Copyright (c) 2024 JFrog +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +set(CONAN_MINIMUM_VERSION 2.0.5) + + +function(detect_os OS OS_API_LEVEL OS_SDK OS_SUBSYSTEM OS_VERSION) + # it could be cross compilation + message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}") + if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(${OS} Macos PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") + set(${OS} Neutrino PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN") + set(${OS} Windows PARENT_SCOPE) + set(${OS_SUBSYSTEM} cygwin PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS") + set(${OS} Windows PARENT_SCOPE) + set(${OS_SUBSYSTEM} msys2 PARENT_SCOPE) + else() + set(${OS} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE) + endif() + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + if(DEFINED ANDROID_PLATFORM) + string(REGEX MATCH "[0-9]+" _OS_API_LEVEL ${ANDROID_PLATFORM}) + elseif(DEFINED CMAKE_SYSTEM_VERSION) + set(_OS_API_LEVEL ${CMAKE_SYSTEM_VERSION}) + endif() + message(STATUS "CMake-Conan: android api level=${_OS_API_LEVEL}") + set(${OS_API_LEVEL} ${_OS_API_LEVEL} PARENT_SCOPE) + endif() + if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS") + # CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja + # generators, but just has the original input string for Xcode. + if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT}) + set(_OS_SDK ${CMAKE_OSX_SYSROOT}) + else() + if(CMAKE_OSX_SYSROOT MATCHES Simulator) + set(apple_platform_suffix simulator) + else() + set(apple_platform_suffix os) + endif() + if(CMAKE_OSX_SYSROOT MATCHES AppleTV) + set(_OS_SDK "appletv${apple_platform_suffix}") + elseif(CMAKE_OSX_SYSROOT MATCHES iPhone) + set(_OS_SDK "iphone${apple_platform_suffix}") + elseif(CMAKE_OSX_SYSROOT MATCHES Watch) + set(_OS_SDK "watch${apple_platform_suffix}") + endif() + endif() + if(DEFINED _OS_SDK) + message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}") + set(${OS_SDK} ${_OS_SDK} PARENT_SCOPE) + endif() + if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET) + message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}") + set(${OS_VERSION} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + + +function(detect_arch ARCH) + # CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one. + # Therefore this code only finds one. If the recipes support multiple architectures, the + # build will work. Otherwise, there will be a linker error for the missing architecture(s). + if(DEFINED CMAKE_OSX_ARCHITECTURES) + string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}") + list(LENGTH apple_arch_list apple_arch_count) + if(apple_arch_count GREATER 1) + message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.") + endif() + endif() + if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "") + set(host_arch ${CMAKE_OSX_ARCHITECTURES}) + elseif(MSVC) + set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}) + else() + set(host_arch ${CMAKE_SYSTEM_PROCESSOR}) + endif() + if(host_arch MATCHES "aarch64|arm64|ARM64") + set(_ARCH armv8) + elseif(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7") + set(_ARCH armv7) + elseif(host_arch MATCHES armv7s) + set(_ARCH armv7s) + elseif(host_arch MATCHES "i686|i386|X86") + set(_ARCH x86) + elseif(host_arch MATCHES "AMD64|amd64|x86_64|x64") + set(_ARCH x86_64) + endif() + message(STATUS "CMake-Conan: cmake_system_processor=${_ARCH}") + set(${ARCH} ${_ARCH} PARENT_SCOPE) +endfunction() + + +function(detect_cxx_standard CXX_STANDARD) + set(${CXX_STANDARD} ${CMAKE_CXX_STANDARD} PARENT_SCOPE) + if(CMAKE_CXX_EXTENSIONS) + set(${CXX_STANDARD} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE) + endif() +endfunction() + + +macro(detect_gnu_libstdcxx) + # _CONAN_IS_GNU_LIBSTDCXX true if GNU libstdc++ + check_cxx_source_compiles(" + #include + #if !defined(__GLIBCXX__) && !defined(__GLIBCPP__) + static_assert(false); + #endif + int main(){}" _CONAN_IS_GNU_LIBSTDCXX) + + # _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI true if C++11 ABI + check_cxx_source_compiles(" + #include + static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\"); + int main () {}" _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI) + + set(_CONAN_GNU_LIBSTDCXX_SUFFIX "") + if(_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI) + set(_CONAN_GNU_LIBSTDCXX_SUFFIX "11") + endif() + unset (_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI) +endmacro() + + +macro(detect_libcxx) + # _CONAN_IS_LIBCXX true if LLVM libc++ + check_cxx_source_compiles(" + #include + #if !defined(_LIBCPP_VERSION) + static_assert(false); + #endif + int main(){}" _CONAN_IS_LIBCXX) +endmacro() + + +function(detect_lib_cxx LIB_CXX) + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}") + set(${LIB_CXX} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE) + return() + endif() + + include(CheckCXXSourceCompiles) + + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + detect_gnu_libstdcxx() + set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") + set(${LIB_CXX} "libc++" PARENT_SCOPE) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows") + # Check for libc++ + detect_libcxx() + if(_CONAN_IS_LIBCXX) + set(${LIB_CXX} "libc++" PARENT_SCOPE) + return() + endif() + + # Check for libstdc++ + detect_gnu_libstdcxx() + if(_CONAN_IS_GNU_LIBSTDCXX) + set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE) + return() + endif() + + # TODO: it would be an error if we reach this point + elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + # Do nothing - compiler.runtime and compiler.runtime_type + # should be handled separately: https://github.com/conan-io/cmake-conan/pull/516 + return() + else() + # TODO: unable to determine, ask user to provide a full profile file instead + endif() +endfunction() + + +function(detect_compiler COMPILER COMPILER_VERSION COMPILER_RUNTIME COMPILER_RUNTIME_TYPE) + if(DEFINED CMAKE_CXX_COMPILER_ID) + set(_COMPILER ${CMAKE_CXX_COMPILER_ID}) + set(_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION}) + else() + if(NOT DEFINED CMAKE_C_COMPILER_ID) + message(FATAL_ERROR "C or C++ compiler not defined") + endif() + set(_COMPILER ${CMAKE_C_COMPILER_ID}) + set(_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION}) + endif() + + message(STATUS "CMake-Conan: CMake compiler=${_COMPILER}") + message(STATUS "CMake-Conan: CMake compiler version=${_COMPILER_VERSION}") + + if(_COMPILER MATCHES MSVC) + set(_COMPILER "msvc") + string(SUBSTRING ${MSVC_VERSION} 0 3 _COMPILER_VERSION) + # Configure compiler.runtime and compiler.runtime_type settings for MSVC + if(CMAKE_MSVC_RUNTIME_LIBRARY) + set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY}) + else() + set(_msvc_runtime_library MultiThreaded$<$:Debug>DLL) # default value documented by CMake + endif() + + set(_KNOWN_MSVC_RUNTIME_VALUES "") + list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL) + list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL) + list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$:Debug> MultiThreaded$<$:Debug>DLL) + + # only accept the 6 possible values, otherwise we don't don't know to map this + if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES) + message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings") + endif() + + # Runtime is "dynamic" in all cases if it ends in DLL + if(_msvc_runtime_library MATCHES ".*DLL$") + set(_COMPILER_RUNTIME "dynamic") + else() + set(_COMPILER_RUNTIME "static") + endif() + message(STATUS "CMake-Conan: CMake compiler.runtime=${_COMPILER_RUNTIME}") + + # Only define compiler.runtime_type when explicitly requested + # If a generator expression is used, let Conan handle it conditional on build_type + if(NOT _msvc_runtime_library MATCHES ":Debug>") + if(_msvc_runtime_library MATCHES "Debug") + set(_COMPILER_RUNTIME_TYPE "Debug") + else() + set(_COMPILER_RUNTIME_TYPE "Release") + endif() + message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_COMPILER_RUNTIME_TYPE}") + endif() + + unset(_KNOWN_MSVC_RUNTIME_VALUES) + + elseif(_COMPILER MATCHES AppleClang) + set(_COMPILER "apple-clang") + string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) + list(GET VERSION_LIST 0 _COMPILER_VERSION) + elseif(_COMPILER MATCHES Clang) + set(_COMPILER "clang") + string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) + list(GET VERSION_LIST 0 _COMPILER_VERSION) + elseif(_COMPILER MATCHES GNU) + set(_COMPILER "gcc") + string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) + list(GET VERSION_LIST 0 _COMPILER_VERSION) + endif() + + message(STATUS "CMake-Conan: [settings] compiler=${_COMPILER}") + message(STATUS "CMake-Conan: [settings] compiler.version=${_COMPILER_VERSION}") + if (_COMPILER_RUNTIME) + message(STATUS "CMake-Conan: [settings] compiler.runtime=${_COMPILER_RUNTIME}") + endif() + if (_COMPILER_RUNTIME_TYPE) + message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_COMPILER_RUNTIME_TYPE}") + endif() + + set(${COMPILER} ${_COMPILER} PARENT_SCOPE) + set(${COMPILER_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE) + set(${COMPILER_RUNTIME} ${_COMPILER_RUNTIME} PARENT_SCOPE) + set(${COMPILER_RUNTIME_TYPE} ${_COMPILER_RUNTIME_TYPE} PARENT_SCOPE) +endfunction() + + +function(detect_build_type BUILD_TYPE) + get_property(_MULTICONFIG_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(NOT _MULTICONFIG_GENERATOR) + # Only set when we know we are in a single-configuration generator + # Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined + set(${BUILD_TYPE} ${CMAKE_BUILD_TYPE} PARENT_SCOPE) + endif() +endfunction() + +macro(set_conan_compiler_if_appleclang lang command output_variable) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang") + execute_process(COMMAND xcrun --find ${command} + OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE) + cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path) + cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path) + if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}") + set(${output_variable} "") + endif() + unset(_xcrun_out) + unset(_xcrun_toolchain_path) + unset(_compiler_parent_path) + endif() +endmacro() + + +macro(append_compiler_executables_configuration) + set(_conan_c_compiler "") + set(_conan_cpp_compiler "") + if(CMAKE_C_COMPILER) + set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\",") + set_conan_compiler_if_appleclang(C cc _conan_c_compiler) + else() + message(WARNING "CMake-Conan: The C compiler is not defined. " + "Please define CMAKE_C_COMPILER or enable the C language.") + endif() + if(CMAKE_CXX_COMPILER) + set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"") + set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler) + else() + message(WARNING "CMake-Conan: The C++ compiler is not defined. " + "Please define CMAKE_CXX_COMPILER or enable the C++ language.") + endif() + + if(NOT "x${_conan_c_compiler}${_conan_cpp_compiler}" STREQUAL "x") + string(APPEND PROFILE "tools.build:compiler_executables={${_conan_c_compiler}${_conan_cpp_compiler}}\n") + endif() + unset(_conan_c_compiler) + unset(_conan_cpp_compiler) +endmacro() + + +function(detect_host_profile output_file) + detect_os(MYOS MYOS_API_LEVEL MYOS_SDK MYOS_SUBSYSTEM MYOS_VERSION) + detect_arch(MYARCH) + detect_compiler(MYCOMPILER MYCOMPILER_VERSION MYCOMPILER_RUNTIME MYCOMPILER_RUNTIME_TYPE) + detect_cxx_standard(MYCXX_STANDARD) + detect_lib_cxx(MYLIB_CXX) + detect_build_type(MYBUILD_TYPE) + + set(PROFILE "") + string(APPEND PROFILE "[settings]\n") + if(MYARCH) + string(APPEND PROFILE arch=${MYARCH} "\n") + endif() + if(MYOS) + string(APPEND PROFILE os=${MYOS} "\n") + endif() + if(MYOS_API_LEVEL) + string(APPEND PROFILE os.api_level=${MYOS_API_LEVEL} "\n") + endif() + if(MYOS_VERSION) + string(APPEND PROFILE os.version=${MYOS_VERSION} "\n") + endif() + if(MYOS_SDK) + string(APPEND PROFILE os.sdk=${MYOS_SDK} "\n") + endif() + if(MYOS_SUBSYSTEM) + string(APPEND PROFILE os.subsystem=${MYOS_SUBSYSTEM} "\n") + endif() + if(MYCOMPILER) + string(APPEND PROFILE compiler=${MYCOMPILER} "\n") + endif() + if(MYCOMPILER_VERSION) + string(APPEND PROFILE compiler.version=${MYCOMPILER_VERSION} "\n") + endif() + if(MYCOMPILER_RUNTIME) + string(APPEND PROFILE compiler.runtime=${MYCOMPILER_RUNTIME} "\n") + endif() + if(MYCOMPILER_RUNTIME_TYPE) + string(APPEND PROFILE compiler.runtime_type=${MYCOMPILER_RUNTIME_TYPE} "\n") + endif() + if(MYCXX_STANDARD) + string(APPEND PROFILE compiler.cppstd=${MYCXX_STANDARD} "\n") + endif() + if(MYLIB_CXX) + string(APPEND PROFILE compiler.libcxx=${MYLIB_CXX} "\n") + endif() + if(MYBUILD_TYPE) + string(APPEND PROFILE "build_type=${MYBUILD_TYPE}\n") + endif() + + if(NOT DEFINED output_file) + set(_FN "${CMAKE_BINARY_DIR}/profile") + else() + set(_FN ${output_file}) + endif() + + string(APPEND PROFILE "[conf]\n") + string(APPEND PROFILE "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n") + + # propagate compilers via profile + append_compiler_executables_configuration() + + if(MYOS STREQUAL "Android") + string(APPEND PROFILE "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n") + endif() + + message(STATUS "CMake-Conan: Creating profile ${_FN}") + file(WRITE ${_FN} ${PROFILE}) + message(STATUS "CMake-Conan: Profile: \n${PROFILE}") +endfunction() + + +function(conan_profile_detect_default) + message(STATUS "CMake-Conan: Checking if a default profile exists") + execute_process(COMMAND ${CONAN_COMMAND} profile path default + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_stdout + ERROR_VARIABLE conan_stderr + ECHO_ERROR_VARIABLE # show the text output regardless + ECHO_OUTPUT_VARIABLE + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + if(NOT ${return_code} EQUAL "0") + message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.") + execute_process(COMMAND ${CONAN_COMMAND} profile detect + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_stdout + ERROR_VARIABLE conan_stderr + ECHO_ERROR_VARIABLE # show the text output regardless + ECHO_OUTPUT_VARIABLE + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() +endfunction() + + +function(conan_install) + cmake_parse_arguments(ARGS CONAN_ARGS ${ARGN}) + set(CONAN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/conan) + # Invoke "conan install" with the provided arguments + set(CONAN_ARGS ${CONAN_ARGS} -of=${CONAN_OUTPUT_FOLDER}) + message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN}") + + + # In case there was not a valid cmake executable in the PATH, we inject the + # same we used to invoke the provider to the PATH + if(DEFINED PATH_TO_CMAKE_BIN) + set(_OLD_PATH $ENV{PATH}) + set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}") + endif() + + execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN} --format=json + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_stdout + ERROR_VARIABLE conan_stderr + ECHO_ERROR_VARIABLE # show the text output regardless + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + if(DEFINED PATH_TO_CMAKE_BIN) + set(ENV{PATH} "${_OLD_PATH}") + endif() + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + + # the files are generated in a folder that depends on the layout used, if + # one is specified, but we don't know a priori where this is. + # TODO: this can be made more robust if Conan can provide this in the json output + string(JSON CONAN_GENERATORS_FOLDER GET ${conan_stdout} graph nodes 0 generators_folder) + cmake_path(CONVERT ${CONAN_GENERATORS_FOLDER} TO_CMAKE_PATH_LIST CONAN_GENERATORS_FOLDER) + # message("conan stdout: ${conan_stdout}") + message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${CONAN_GENERATORS_FOLDER}") + set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${CONAN_GENERATORS_FOLDER}") + # reconfigure on conanfile changes + string(JSON CONANFILE GET ${conan_stdout} graph nodes 0 label) + message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${CONANFILE}") + set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${CONANFILE}") + # success + set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE) + +endfunction() + + +function(conan_get_version conan_command conan_current_version) + execute_process( + COMMAND ${conan_command} --version + OUTPUT_VARIABLE conan_output + RESULT_VARIABLE conan_result + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(conan_result) + message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan") + endif() + + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output}) + set(${conan_current_version} ${conan_version} PARENT_SCOPE) +endfunction() + + +function(conan_version_check) + set(options ) + set(oneValueArgs MINIMUM CURRENT) + set(multiValueArgs ) + cmake_parse_arguments(CONAN_VERSION_CHECK + "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT CONAN_VERSION_CHECK_MINIMUM) + message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!") + endif() + if(NOT CONAN_VERSION_CHECK_CURRENT) + message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!") + endif() + + if(CONAN_VERSION_CHECK_CURRENT VERSION_LESS CONAN_VERSION_CHECK_MINIMUM) + message(FATAL_ERROR "CMake-Conan: Conan version must be ${CONAN_VERSION_CHECK_MINIMUM} or later") + endif() +endfunction() + + +macro(construct_profile_argument argument_variable profile_list) + set(${argument_variable} "") + if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE") + set(_arg_flag "--profile:host=") + elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE") + set(_arg_flag "--profile:build=") + endif() + + set(_profile_list "${${profile_list}}") + list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile") + list(TRANSFORM _profile_list PREPEND ${_arg_flag}) + set(${argument_variable} ${_profile_list}) + + unset(_arg_flag) + unset(_profile_list) +endmacro() + + +macro(conan_provide_dependency method package_name) + set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE) + get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS) + if(NOT _conan_install_success) + find_program(CONAN_COMMAND "conan" REQUIRED) + conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION) + conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION}) + message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan") + if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE) + conan_profile_detect_default() + endif() + if("auto-cmake" IN_LIST CONAN_HOST_PROFILE) + detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile) + endif() + construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE) + construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE) + if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py") + file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile) + if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") + message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile") + endif() + set(generator "") + elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt") + file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile) + if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") + message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. " + "Please define the generator as it will be mandatory in the future") + endif() + set(generator "-g;CMakeDeps") + endif() + get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(NOT _multiconfig_generator) + message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}") + conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator}) + else() + message(STATUS "CMake-Conan: Installing both Debug and Release") + conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${CONAN_INSTALL_ARGS} ${generator}) + conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${CONAN_INSTALL_ARGS} ${generator}) + endif() + unset(_host_profile_flags) + unset(_build_profile_flags) + unset(_multiconfig_generator) + unset(_conan_install_success) + else() + message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran") + unset(_conan_install_success) + endif() + + get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) + + # Ensure that we consider Conan-provided packages ahead of any other, + # irrespective of other settings that modify the search order or search paths + # This follows the guidelines from the find_package documentation + # (https://cmake.org/cmake/help/latest/command/find_package.html): + # find_package ( PATHS paths... NO_DEFAULT_PATH) + # find_package () + + # Filter out `REQUIRED` from the argument list, as the first call may fail + set(_find_args_${package_name} "${ARGN}") + list(REMOVE_ITEM _find_args_${package_name} "REQUIRED") + if(NOT "MODULE" IN_LIST _find_args_${package_name}) + find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + unset(_find_args_${package_name}) + endif() + + # Invoke find_package a second time - if the first call succeeded, + # this will simply reuse the result. If not, fall back to CMake default search + # behaviour, also allowing modules to be searched. + if(NOT ${package_name}_FOUND) + list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index) + if(_index EQUAL -1) + list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}") + endif() + unset(_index) + find_package(${package_name} ${ARGN} BYPASS_PROVIDER) + list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}") + endif() +endmacro() + + +cmake_language( + SET_DEPENDENCY_PROVIDER conan_provide_dependency + SUPPORTED_METHODS FIND_PACKAGE +) + + +macro(conan_provide_dependency_check) + set(_CONAN_PROVIDE_DEPENDENCY_INVOKED FALSE) + get_property(_CONAN_PROVIDE_DEPENDENCY_INVOKED GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED) + if(NOT _CONAN_PROVIDE_DEPENDENCY_INVOKED) + message(WARNING "Conan is correctly configured as dependency provider, " + "but Conan has not been invoked. Please add at least one " + "call to `find_package()`.") + if(DEFINED CONAN_COMMAND) + # supress warning in case `CONAN_COMMAND` was specified but unused. + set(_CONAN_COMMAND ${CONAN_COMMAND}) + unset(_CONAN_COMMAND) + endif() + endif() + unset(_CONAN_PROVIDE_DEPENDENCY_INVOKED) +endmacro() + + +# Add a deferred call at the end of processing the top-level directory +# to check if the dependency provider was invoked at all. +cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check) + +# Configurable variables for Conan profiles +set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile") +set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile") +set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install") + +find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH) +if(NOT _cmake_program) + get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY) + set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is") +endif() From e0abfcd3da5b7615ad7e46f287b375d5bdc032ee Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:41:22 +0200 Subject: [PATCH 27/48] install eigen through choco --- .github/workflows/windows_unit_tests.yml | 10 ++++++---- CMakeLists.txt | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 0320f7c7..2aae5bc9 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -21,14 +21,16 @@ jobs: with: python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Install conan - run: pip install conan numpy - - run: conan profile detect + - name: Install numpy + run: pip install numpy + + - run: choco install eigen + - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores - name: cmake - run: cmake -S . -B build -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=cmake/conan_provider.cmake -DCMAKE_BUILD_TYPE=Release + run: cmake -S . -B build -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DCMAKE_BUILD_TYPE=Release - name: compile run: cd build && cmake --build . -j${{ steps.cpu-cores.outputs.count }} --config Release - name: Run ctest diff --git a/CMakeLists.txt b/CMakeLists.txt index df9926a2..cf17c8a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ if(LIBCMAES_BUILD_PYTHON) endif() -find_package (Eigen3 3.0.0 REQUIRED) +find_package (Eigen3 3.4.0 REQUIRED) if (LIBCMAES_USE_OPENMP) find_package (OpenMP QUIET) From 4140bce2240f47a4f473c017ca9f9e4de284e543 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:44:56 +0200 Subject: [PATCH 28/48] add missing pip package --- .github/workflows/windows_unit_tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 2aae5bc9..8d85c8ae 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -21,8 +21,8 @@ jobs: with: python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Install numpy - run: pip install numpy + - name: Install pip packages + run: pip install numpy setuptools - run: choco install eigen From 485e0a5f1643579511aa1102e533c52146fc8d7a Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 00:52:35 +0200 Subject: [PATCH 29/48] try conan provider file for gflags on windows --- .github/workflows/windows_unit_tests.yml | 2 +- conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 8d85c8ae..b4d131ee 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -30,7 +30,7 @@ jobs: uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores - name: cmake - run: cmake -S . -B build -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DCMAKE_BUILD_TYPE=Release + run: cmake -S . -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=cmake/conan_provider.cmake -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DCMAKE_BUILD_TYPE=Release - name: compile run: cd build && cmake --build . -j${{ steps.cpu-cores.outputs.count }} --config Release - name: Run ctest diff --git a/conanfile.py b/conanfile.py index 94539325..19369bbf 100644 --- a/conanfile.py +++ b/conanfile.py @@ -40,7 +40,7 @@ class CmaesConan(ConanFile): ) def build_requirements(self): - pass + self.test_requires("gflags/2.2.2") def requirements(self): self.requires("eigen/3.4.0", transitive_headers=True) From 94ef8da393a3a6a08f6a67b2e58bd65d4e18227e Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 01:07:33 +0200 Subject: [PATCH 30/48] try through conan --- .github/workflows/conan.yml | 2 +- .github/workflows/windows_unit_tests.yml | 9 +++++++++ conanfile.py | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index 124529ea..13a4601a 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -35,4 +35,4 @@ jobs: - name: Install conan run: pip install conan>2 - run: conan profile detect - - run: conan create . + - run: conan create . --build=missing diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index b4d131ee..c9b708bf 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -29,6 +29,15 @@ jobs: - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores + + - run: conan install . --options enable_tests=True --build=boost/1.74.0 + - run: cmake --list-presets + - run: cmake --preset conan-release + - run: cmake --build --list-presets + - run: cmake --build --preset conan-release -j${{ steps.cpu-cores.outputs.count }} + - run: ctest --list-presets + - run: ctest --preset conan-release + - name: cmake run: cmake -S . -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=cmake/conan_provider.cmake -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DCMAKE_BUILD_TYPE=Release - name: compile diff --git a/conanfile.py b/conanfile.py index 19369bbf..c218b13a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -26,8 +26,15 @@ class CmaesConan(ConanFile): "shared": [True, False], "openmp": [True, False], "surrog": [True, False], + "enable_tests": [True, False], + } + default_options = { + "shared": True, + "openmp": True, + "surrog": True, + "enable_tests": False, + "boost/*:without_python": False, } - default_options = {"shared": True, "openmp": True, "surrog": True} # Sources are located in the same place as this recipe, copy them to the recipe exports_sources = ( @@ -40,7 +47,9 @@ class CmaesConan(ConanFile): ) def build_requirements(self): - self.test_requires("gflags/2.2.2") + if self.options.enable_tests: + self.test_requires("gflags/2.2.2") + self.test_requires("boost/1.74.0") def requirements(self): self.requires("eigen/3.4.0", transitive_headers=True) @@ -77,6 +86,8 @@ def generate(self): tc.variables["LIBCMAES_BUILD_SHARED_LIBS"] = self.options.shared tc.variables["LIBCMAES_USE_OPENMP"] = self.options.openmp tc.variables["LIBCMAES_ENABLE_SURROG"] = self.options.surrog + tc.variables["LIBCMAES_BUILD_PYTHON"] = self.options.enable_tests + tc.variables["LIBCMAES_BUILD_TESTS"] = self.options.enable_tests tc.generate() def build(self): From d177845569ae8f403f69125c368e537eae12239d Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Sun, 2 Jun 2024 01:12:43 +0200 Subject: [PATCH 31/48] Install conan --- .github/workflows/windows_unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index c9b708bf..0641e0fa 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -22,7 +22,7 @@ jobs: python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - name: Install pip packages - run: pip install numpy setuptools + run: pip install conan numpy setuptools - run: choco install eigen From e2ada2059949ad14e891425dc07981745beee486 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Sun, 2 Jun 2024 01:17:38 +0200 Subject: [PATCH 32/48] Update windows_unit_tests.yml --- .github/workflows/windows_unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 0641e0fa..6a663d31 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -24,7 +24,7 @@ jobs: - name: Install pip packages run: pip install conan numpy setuptools - - run: choco install eigen + - run: conan profile detect - name: Get number of CPU cores uses: SimenB/github-actions-cpu-cores@v1 From f504bbb5a37bc5417cdfb0ade8948ccca82cb066 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 07:33:04 +0200 Subject: [PATCH 33/48] Update boost version --- .github/workflows/windows_unit_tests.yml | 2 +- conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 6a663d31..1ff61d60 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -30,7 +30,7 @@ jobs: uses: SimenB/github-actions-cpu-cores@v1 id: cpu-cores - - run: conan install . --options enable_tests=True --build=boost/1.74.0 + - run: conan install . --options enable_tests=True --build=missing - run: cmake --list-presets - run: cmake --preset conan-release - run: cmake --build --list-presets diff --git a/conanfile.py b/conanfile.py index c218b13a..e8a61751 100644 --- a/conanfile.py +++ b/conanfile.py @@ -49,7 +49,7 @@ class CmaesConan(ConanFile): def build_requirements(self): if self.options.enable_tests: self.test_requires("gflags/2.2.2") - self.test_requires("boost/1.74.0") + self.test_requires("boost/1.85.0") def requirements(self): self.requires("eigen/3.4.0", transitive_headers=True) From 01ee12af384d11679f0d00140765c6652ca0522b Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 07:50:47 +0200 Subject: [PATCH 34/48] change preset name --- .github/workflows/windows_unit_tests.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 1ff61d60..9097c426 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -32,18 +32,13 @@ jobs: - run: conan install . --options enable_tests=True --build=missing - run: cmake --list-presets - - run: cmake --preset conan-release + - run: cmake --preset conan-default - run: cmake --build --list-presets - - run: cmake --build --preset conan-release -j${{ steps.cpu-cores.outputs.count }} + - run: cmake --build --preset conan-default -j${{ steps.cpu-cores.outputs.count }} - run: ctest --list-presets - - run: ctest --preset conan-release - - - name: cmake - run: cmake -S . -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=cmake/conan_provider.cmake -DLIBCMAES_BUILD_PYTHON=On -DLIBCMAES_BUILD_TESTS=On -DLIBCMAES_USE_OPENMP=On -DCMAKE_BUILD_TYPE=Release - - name: compile - run: cd build && cmake --build . -j${{ steps.cpu-cores.outputs.count }} --config Release - - name: Run ctest - run: cd build && ctest -j${{ steps.cpu-cores.outputs.count }} --output-on-failure -C Release + - run: ctest --preset conan-default --output-on-failure + + From c85eaf7d480c814f86c488cb180250f50047cba1 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 08:12:31 +0200 Subject: [PATCH 35/48] execute unit tests through conan --- .github/workflows/windows_unit_tests.yml | 14 +++----------- conanfile.py | 9 +++++++++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 9097c426..0685fb97 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -26,17 +26,9 @@ jobs: - run: conan profile detect - - name: Get number of CPU cores - uses: SimenB/github-actions-cpu-cores@v1 - id: cpu-cores - - - run: conan install . --options enable_tests=True --build=missing - - run: cmake --list-presets - - run: cmake --preset conan-default - - run: cmake --build --list-presets - - run: cmake --build --preset conan-default -j${{ steps.cpu-cores.outputs.count }} - - run: ctest --list-presets - - run: ctest --preset conan-default --output-on-failure + + - run: conan create . --options enable_tests=True --build=missing + diff --git a/conanfile.py b/conanfile.py index e8a61751..5d3c8e19 100644 --- a/conanfile.py +++ b/conanfile.py @@ -4,6 +4,7 @@ from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout from conan.tools.files import load +from conan.tools.env import Environment from conan.tools.scm import Git @@ -95,6 +96,14 @@ def build(self): cmake.configure() cmake.build() + environment = Environment() + environment.define("CTEST_OUTPUT_ON_FAILURE","1") + envvars = environment.vars(self) + + if self.options.enable_tests: + with envvars.apply(): + cmake.test() + def package(self): cmake = CMake(self) cmake.install() From 320e524c80f80f450569d40dae0c353b904ab68b Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 08:29:16 +0200 Subject: [PATCH 36/48] export tests --- conanfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conanfile.py b/conanfile.py index 5d3c8e19..d86e123c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -45,6 +45,7 @@ class CmaesConan(ConanFile): "libcmaes-config.cmake.in", "src/*", "libcmaes.pc.in", + "tests/*" ) def build_requirements(self): From 8a6d414707afad23f377e7825cdba29b37b3b247 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 08:48:55 +0200 Subject: [PATCH 37/48] add missing python export --- conanfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index d86e123c..859ef632 100644 --- a/conanfile.py +++ b/conanfile.py @@ -45,7 +45,8 @@ class CmaesConan(ConanFile): "libcmaes-config.cmake.in", "src/*", "libcmaes.pc.in", - "tests/*" + "tests/*", + "python/*" ) def build_requirements(self): From a1a98026dbfbcc79ddd3031fd90b4206f5f14bde Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 09:07:36 +0200 Subject: [PATCH 38/48] remove unused file --- cmake/conan_provider.cmake | 649 ------------------------------------- 1 file changed, 649 deletions(-) delete mode 100644 cmake/conan_provider.cmake diff --git a/cmake/conan_provider.cmake b/cmake/conan_provider.cmake deleted file mode 100644 index 6bf31b18..00000000 --- a/cmake/conan_provider.cmake +++ /dev/null @@ -1,649 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2024 JFrog -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -set(CONAN_MINIMUM_VERSION 2.0.5) - - -function(detect_os OS OS_API_LEVEL OS_SDK OS_SUBSYSTEM OS_VERSION) - # it could be cross compilation - message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}") - if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set(${OS} Macos PARENT_SCOPE) - elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") - set(${OS} Neutrino PARENT_SCOPE) - elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN") - set(${OS} Windows PARENT_SCOPE) - set(${OS_SUBSYSTEM} cygwin PARENT_SCOPE) - elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS") - set(${OS} Windows PARENT_SCOPE) - set(${OS_SUBSYSTEM} msys2 PARENT_SCOPE) - else() - set(${OS} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE) - endif() - if(CMAKE_SYSTEM_NAME STREQUAL "Android") - if(DEFINED ANDROID_PLATFORM) - string(REGEX MATCH "[0-9]+" _OS_API_LEVEL ${ANDROID_PLATFORM}) - elseif(DEFINED CMAKE_SYSTEM_VERSION) - set(_OS_API_LEVEL ${CMAKE_SYSTEM_VERSION}) - endif() - message(STATUS "CMake-Conan: android api level=${_OS_API_LEVEL}") - set(${OS_API_LEVEL} ${_OS_API_LEVEL} PARENT_SCOPE) - endif() - if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS") - # CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja - # generators, but just has the original input string for Xcode. - if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT}) - set(_OS_SDK ${CMAKE_OSX_SYSROOT}) - else() - if(CMAKE_OSX_SYSROOT MATCHES Simulator) - set(apple_platform_suffix simulator) - else() - set(apple_platform_suffix os) - endif() - if(CMAKE_OSX_SYSROOT MATCHES AppleTV) - set(_OS_SDK "appletv${apple_platform_suffix}") - elseif(CMAKE_OSX_SYSROOT MATCHES iPhone) - set(_OS_SDK "iphone${apple_platform_suffix}") - elseif(CMAKE_OSX_SYSROOT MATCHES Watch) - set(_OS_SDK "watch${apple_platform_suffix}") - endif() - endif() - if(DEFINED _OS_SDK) - message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}") - set(${OS_SDK} ${_OS_SDK} PARENT_SCOPE) - endif() - if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET) - message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}") - set(${OS_VERSION} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - - -function(detect_arch ARCH) - # CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one. - # Therefore this code only finds one. If the recipes support multiple architectures, the - # build will work. Otherwise, there will be a linker error for the missing architecture(s). - if(DEFINED CMAKE_OSX_ARCHITECTURES) - string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}") - list(LENGTH apple_arch_list apple_arch_count) - if(apple_arch_count GREATER 1) - message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.") - endif() - endif() - if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "") - set(host_arch ${CMAKE_OSX_ARCHITECTURES}) - elseif(MSVC) - set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}) - else() - set(host_arch ${CMAKE_SYSTEM_PROCESSOR}) - endif() - if(host_arch MATCHES "aarch64|arm64|ARM64") - set(_ARCH armv8) - elseif(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7") - set(_ARCH armv7) - elseif(host_arch MATCHES armv7s) - set(_ARCH armv7s) - elseif(host_arch MATCHES "i686|i386|X86") - set(_ARCH x86) - elseif(host_arch MATCHES "AMD64|amd64|x86_64|x64") - set(_ARCH x86_64) - endif() - message(STATUS "CMake-Conan: cmake_system_processor=${_ARCH}") - set(${ARCH} ${_ARCH} PARENT_SCOPE) -endfunction() - - -function(detect_cxx_standard CXX_STANDARD) - set(${CXX_STANDARD} ${CMAKE_CXX_STANDARD} PARENT_SCOPE) - if(CMAKE_CXX_EXTENSIONS) - set(${CXX_STANDARD} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE) - endif() -endfunction() - - -macro(detect_gnu_libstdcxx) - # _CONAN_IS_GNU_LIBSTDCXX true if GNU libstdc++ - check_cxx_source_compiles(" - #include - #if !defined(__GLIBCXX__) && !defined(__GLIBCPP__) - static_assert(false); - #endif - int main(){}" _CONAN_IS_GNU_LIBSTDCXX) - - # _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI true if C++11 ABI - check_cxx_source_compiles(" - #include - static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\"); - int main () {}" _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI) - - set(_CONAN_GNU_LIBSTDCXX_SUFFIX "") - if(_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI) - set(_CONAN_GNU_LIBSTDCXX_SUFFIX "11") - endif() - unset (_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI) -endmacro() - - -macro(detect_libcxx) - # _CONAN_IS_LIBCXX true if LLVM libc++ - check_cxx_source_compiles(" - #include - #if !defined(_LIBCPP_VERSION) - static_assert(false); - #endif - int main(){}" _CONAN_IS_LIBCXX) -endmacro() - - -function(detect_lib_cxx LIB_CXX) - if(CMAKE_SYSTEM_NAME STREQUAL "Android") - message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}") - set(${LIB_CXX} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE) - return() - endif() - - include(CheckCXXSourceCompiles) - - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - detect_gnu_libstdcxx() - set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") - set(${LIB_CXX} "libc++" PARENT_SCOPE) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows") - # Check for libc++ - detect_libcxx() - if(_CONAN_IS_LIBCXX) - set(${LIB_CXX} "libc++" PARENT_SCOPE) - return() - endif() - - # Check for libstdc++ - detect_gnu_libstdcxx() - if(_CONAN_IS_GNU_LIBSTDCXX) - set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE) - return() - endif() - - # TODO: it would be an error if we reach this point - elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - # Do nothing - compiler.runtime and compiler.runtime_type - # should be handled separately: https://github.com/conan-io/cmake-conan/pull/516 - return() - else() - # TODO: unable to determine, ask user to provide a full profile file instead - endif() -endfunction() - - -function(detect_compiler COMPILER COMPILER_VERSION COMPILER_RUNTIME COMPILER_RUNTIME_TYPE) - if(DEFINED CMAKE_CXX_COMPILER_ID) - set(_COMPILER ${CMAKE_CXX_COMPILER_ID}) - set(_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION}) - else() - if(NOT DEFINED CMAKE_C_COMPILER_ID) - message(FATAL_ERROR "C or C++ compiler not defined") - endif() - set(_COMPILER ${CMAKE_C_COMPILER_ID}) - set(_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION}) - endif() - - message(STATUS "CMake-Conan: CMake compiler=${_COMPILER}") - message(STATUS "CMake-Conan: CMake compiler version=${_COMPILER_VERSION}") - - if(_COMPILER MATCHES MSVC) - set(_COMPILER "msvc") - string(SUBSTRING ${MSVC_VERSION} 0 3 _COMPILER_VERSION) - # Configure compiler.runtime and compiler.runtime_type settings for MSVC - if(CMAKE_MSVC_RUNTIME_LIBRARY) - set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY}) - else() - set(_msvc_runtime_library MultiThreaded$<$:Debug>DLL) # default value documented by CMake - endif() - - set(_KNOWN_MSVC_RUNTIME_VALUES "") - list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL) - list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL) - list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$:Debug> MultiThreaded$<$:Debug>DLL) - - # only accept the 6 possible values, otherwise we don't don't know to map this - if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES) - message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings") - endif() - - # Runtime is "dynamic" in all cases if it ends in DLL - if(_msvc_runtime_library MATCHES ".*DLL$") - set(_COMPILER_RUNTIME "dynamic") - else() - set(_COMPILER_RUNTIME "static") - endif() - message(STATUS "CMake-Conan: CMake compiler.runtime=${_COMPILER_RUNTIME}") - - # Only define compiler.runtime_type when explicitly requested - # If a generator expression is used, let Conan handle it conditional on build_type - if(NOT _msvc_runtime_library MATCHES ":Debug>") - if(_msvc_runtime_library MATCHES "Debug") - set(_COMPILER_RUNTIME_TYPE "Debug") - else() - set(_COMPILER_RUNTIME_TYPE "Release") - endif() - message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_COMPILER_RUNTIME_TYPE}") - endif() - - unset(_KNOWN_MSVC_RUNTIME_VALUES) - - elseif(_COMPILER MATCHES AppleClang) - set(_COMPILER "apple-clang") - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) - list(GET VERSION_LIST 0 _COMPILER_VERSION) - elseif(_COMPILER MATCHES Clang) - set(_COMPILER "clang") - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) - list(GET VERSION_LIST 0 _COMPILER_VERSION) - elseif(_COMPILER MATCHES GNU) - set(_COMPILER "gcc") - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) - list(GET VERSION_LIST 0 _COMPILER_VERSION) - endif() - - message(STATUS "CMake-Conan: [settings] compiler=${_COMPILER}") - message(STATUS "CMake-Conan: [settings] compiler.version=${_COMPILER_VERSION}") - if (_COMPILER_RUNTIME) - message(STATUS "CMake-Conan: [settings] compiler.runtime=${_COMPILER_RUNTIME}") - endif() - if (_COMPILER_RUNTIME_TYPE) - message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_COMPILER_RUNTIME_TYPE}") - endif() - - set(${COMPILER} ${_COMPILER} PARENT_SCOPE) - set(${COMPILER_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE) - set(${COMPILER_RUNTIME} ${_COMPILER_RUNTIME} PARENT_SCOPE) - set(${COMPILER_RUNTIME_TYPE} ${_COMPILER_RUNTIME_TYPE} PARENT_SCOPE) -endfunction() - - -function(detect_build_type BUILD_TYPE) - get_property(_MULTICONFIG_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(NOT _MULTICONFIG_GENERATOR) - # Only set when we know we are in a single-configuration generator - # Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined - set(${BUILD_TYPE} ${CMAKE_BUILD_TYPE} PARENT_SCOPE) - endif() -endfunction() - -macro(set_conan_compiler_if_appleclang lang command output_variable) - if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang") - execute_process(COMMAND xcrun --find ${command} - OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE) - cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path) - cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path) - if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}") - set(${output_variable} "") - endif() - unset(_xcrun_out) - unset(_xcrun_toolchain_path) - unset(_compiler_parent_path) - endif() -endmacro() - - -macro(append_compiler_executables_configuration) - set(_conan_c_compiler "") - set(_conan_cpp_compiler "") - if(CMAKE_C_COMPILER) - set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\",") - set_conan_compiler_if_appleclang(C cc _conan_c_compiler) - else() - message(WARNING "CMake-Conan: The C compiler is not defined. " - "Please define CMAKE_C_COMPILER or enable the C language.") - endif() - if(CMAKE_CXX_COMPILER) - set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"") - set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler) - else() - message(WARNING "CMake-Conan: The C++ compiler is not defined. " - "Please define CMAKE_CXX_COMPILER or enable the C++ language.") - endif() - - if(NOT "x${_conan_c_compiler}${_conan_cpp_compiler}" STREQUAL "x") - string(APPEND PROFILE "tools.build:compiler_executables={${_conan_c_compiler}${_conan_cpp_compiler}}\n") - endif() - unset(_conan_c_compiler) - unset(_conan_cpp_compiler) -endmacro() - - -function(detect_host_profile output_file) - detect_os(MYOS MYOS_API_LEVEL MYOS_SDK MYOS_SUBSYSTEM MYOS_VERSION) - detect_arch(MYARCH) - detect_compiler(MYCOMPILER MYCOMPILER_VERSION MYCOMPILER_RUNTIME MYCOMPILER_RUNTIME_TYPE) - detect_cxx_standard(MYCXX_STANDARD) - detect_lib_cxx(MYLIB_CXX) - detect_build_type(MYBUILD_TYPE) - - set(PROFILE "") - string(APPEND PROFILE "[settings]\n") - if(MYARCH) - string(APPEND PROFILE arch=${MYARCH} "\n") - endif() - if(MYOS) - string(APPEND PROFILE os=${MYOS} "\n") - endif() - if(MYOS_API_LEVEL) - string(APPEND PROFILE os.api_level=${MYOS_API_LEVEL} "\n") - endif() - if(MYOS_VERSION) - string(APPEND PROFILE os.version=${MYOS_VERSION} "\n") - endif() - if(MYOS_SDK) - string(APPEND PROFILE os.sdk=${MYOS_SDK} "\n") - endif() - if(MYOS_SUBSYSTEM) - string(APPEND PROFILE os.subsystem=${MYOS_SUBSYSTEM} "\n") - endif() - if(MYCOMPILER) - string(APPEND PROFILE compiler=${MYCOMPILER} "\n") - endif() - if(MYCOMPILER_VERSION) - string(APPEND PROFILE compiler.version=${MYCOMPILER_VERSION} "\n") - endif() - if(MYCOMPILER_RUNTIME) - string(APPEND PROFILE compiler.runtime=${MYCOMPILER_RUNTIME} "\n") - endif() - if(MYCOMPILER_RUNTIME_TYPE) - string(APPEND PROFILE compiler.runtime_type=${MYCOMPILER_RUNTIME_TYPE} "\n") - endif() - if(MYCXX_STANDARD) - string(APPEND PROFILE compiler.cppstd=${MYCXX_STANDARD} "\n") - endif() - if(MYLIB_CXX) - string(APPEND PROFILE compiler.libcxx=${MYLIB_CXX} "\n") - endif() - if(MYBUILD_TYPE) - string(APPEND PROFILE "build_type=${MYBUILD_TYPE}\n") - endif() - - if(NOT DEFINED output_file) - set(_FN "${CMAKE_BINARY_DIR}/profile") - else() - set(_FN ${output_file}) - endif() - - string(APPEND PROFILE "[conf]\n") - string(APPEND PROFILE "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n") - - # propagate compilers via profile - append_compiler_executables_configuration() - - if(MYOS STREQUAL "Android") - string(APPEND PROFILE "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n") - endif() - - message(STATUS "CMake-Conan: Creating profile ${_FN}") - file(WRITE ${_FN} ${PROFILE}) - message(STATUS "CMake-Conan: Profile: \n${PROFILE}") -endfunction() - - -function(conan_profile_detect_default) - message(STATUS "CMake-Conan: Checking if a default profile exists") - execute_process(COMMAND ${CONAN_COMMAND} profile path default - RESULT_VARIABLE return_code - OUTPUT_VARIABLE conan_stdout - ERROR_VARIABLE conan_stderr - ECHO_ERROR_VARIABLE # show the text output regardless - ECHO_OUTPUT_VARIABLE - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - if(NOT ${return_code} EQUAL "0") - message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.") - execute_process(COMMAND ${CONAN_COMMAND} profile detect - RESULT_VARIABLE return_code - OUTPUT_VARIABLE conan_stdout - ERROR_VARIABLE conan_stderr - ECHO_ERROR_VARIABLE # show the text output regardless - ECHO_OUTPUT_VARIABLE - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - endif() -endfunction() - - -function(conan_install) - cmake_parse_arguments(ARGS CONAN_ARGS ${ARGN}) - set(CONAN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/conan) - # Invoke "conan install" with the provided arguments - set(CONAN_ARGS ${CONAN_ARGS} -of=${CONAN_OUTPUT_FOLDER}) - message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN}") - - - # In case there was not a valid cmake executable in the PATH, we inject the - # same we used to invoke the provider to the PATH - if(DEFINED PATH_TO_CMAKE_BIN) - set(_OLD_PATH $ENV{PATH}) - set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}") - endif() - - execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN} --format=json - RESULT_VARIABLE return_code - OUTPUT_VARIABLE conan_stdout - ERROR_VARIABLE conan_stderr - ECHO_ERROR_VARIABLE # show the text output regardless - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - - if(DEFINED PATH_TO_CMAKE_BIN) - set(ENV{PATH} "${_OLD_PATH}") - endif() - - if(NOT "${return_code}" STREQUAL "0") - message(FATAL_ERROR "Conan install failed='${return_code}'") - endif() - - # the files are generated in a folder that depends on the layout used, if - # one is specified, but we don't know a priori where this is. - # TODO: this can be made more robust if Conan can provide this in the json output - string(JSON CONAN_GENERATORS_FOLDER GET ${conan_stdout} graph nodes 0 generators_folder) - cmake_path(CONVERT ${CONAN_GENERATORS_FOLDER} TO_CMAKE_PATH_LIST CONAN_GENERATORS_FOLDER) - # message("conan stdout: ${conan_stdout}") - message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${CONAN_GENERATORS_FOLDER}") - set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${CONAN_GENERATORS_FOLDER}") - # reconfigure on conanfile changes - string(JSON CONANFILE GET ${conan_stdout} graph nodes 0 label) - message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${CONANFILE}") - set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${CONANFILE}") - # success - set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE) - -endfunction() - - -function(conan_get_version conan_command conan_current_version) - execute_process( - COMMAND ${conan_command} --version - OUTPUT_VARIABLE conan_output - RESULT_VARIABLE conan_result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(conan_result) - message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan") - endif() - - string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output}) - set(${conan_current_version} ${conan_version} PARENT_SCOPE) -endfunction() - - -function(conan_version_check) - set(options ) - set(oneValueArgs MINIMUM CURRENT) - set(multiValueArgs ) - cmake_parse_arguments(CONAN_VERSION_CHECK - "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT CONAN_VERSION_CHECK_MINIMUM) - message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!") - endif() - if(NOT CONAN_VERSION_CHECK_CURRENT) - message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!") - endif() - - if(CONAN_VERSION_CHECK_CURRENT VERSION_LESS CONAN_VERSION_CHECK_MINIMUM) - message(FATAL_ERROR "CMake-Conan: Conan version must be ${CONAN_VERSION_CHECK_MINIMUM} or later") - endif() -endfunction() - - -macro(construct_profile_argument argument_variable profile_list) - set(${argument_variable} "") - if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE") - set(_arg_flag "--profile:host=") - elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE") - set(_arg_flag "--profile:build=") - endif() - - set(_profile_list "${${profile_list}}") - list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile") - list(TRANSFORM _profile_list PREPEND ${_arg_flag}) - set(${argument_variable} ${_profile_list}) - - unset(_arg_flag) - unset(_profile_list) -endmacro() - - -macro(conan_provide_dependency method package_name) - set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE) - get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS) - if(NOT _conan_install_success) - find_program(CONAN_COMMAND "conan" REQUIRED) - conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION) - conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION}) - message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan") - if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE) - conan_profile_detect_default() - endif() - if("auto-cmake" IN_LIST CONAN_HOST_PROFILE) - detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile) - endif() - construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE) - construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE) - if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py") - file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile) - if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") - message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile") - endif() - set(generator "") - elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt") - file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile) - if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") - message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. " - "Please define the generator as it will be mandatory in the future") - endif() - set(generator "-g;CMakeDeps") - endif() - get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(NOT _multiconfig_generator) - message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}") - conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator}) - else() - message(STATUS "CMake-Conan: Installing both Debug and Release") - conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${CONAN_INSTALL_ARGS} ${generator}) - conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${CONAN_INSTALL_ARGS} ${generator}) - endif() - unset(_host_profile_flags) - unset(_build_profile_flags) - unset(_multiconfig_generator) - unset(_conan_install_success) - else() - message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran") - unset(_conan_install_success) - endif() - - get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) - - # Ensure that we consider Conan-provided packages ahead of any other, - # irrespective of other settings that modify the search order or search paths - # This follows the guidelines from the find_package documentation - # (https://cmake.org/cmake/help/latest/command/find_package.html): - # find_package ( PATHS paths... NO_DEFAULT_PATH) - # find_package () - - # Filter out `REQUIRED` from the argument list, as the first call may fail - set(_find_args_${package_name} "${ARGN}") - list(REMOVE_ITEM _find_args_${package_name} "REQUIRED") - if(NOT "MODULE" IN_LIST _find_args_${package_name}) - find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) - unset(_find_args_${package_name}) - endif() - - # Invoke find_package a second time - if the first call succeeded, - # this will simply reuse the result. If not, fall back to CMake default search - # behaviour, also allowing modules to be searched. - if(NOT ${package_name}_FOUND) - list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index) - if(_index EQUAL -1) - list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}") - endif() - unset(_index) - find_package(${package_name} ${ARGN} BYPASS_PROVIDER) - list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}") - endif() -endmacro() - - -cmake_language( - SET_DEPENDENCY_PROVIDER conan_provide_dependency - SUPPORTED_METHODS FIND_PACKAGE -) - - -macro(conan_provide_dependency_check) - set(_CONAN_PROVIDE_DEPENDENCY_INVOKED FALSE) - get_property(_CONAN_PROVIDE_DEPENDENCY_INVOKED GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED) - if(NOT _CONAN_PROVIDE_DEPENDENCY_INVOKED) - message(WARNING "Conan is correctly configured as dependency provider, " - "but Conan has not been invoked. Please add at least one " - "call to `find_package()`.") - if(DEFINED CONAN_COMMAND) - # supress warning in case `CONAN_COMMAND` was specified but unused. - set(_CONAN_COMMAND ${CONAN_COMMAND}) - unset(_CONAN_COMMAND) - endif() - endif() - unset(_CONAN_PROVIDE_DEPENDENCY_INVOKED) -endmacro() - - -# Add a deferred call at the end of processing the top-level directory -# to check if the dependency provider was invoked at all. -cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check) - -# Configurable variables for Conan profiles -set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile") -set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile") -set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install") - -find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH) -if(NOT _cmake_program) - get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY) - set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is") -endif() From de733a0b163f55da912f1ca6c9a06e60f791a1c4 Mon Sep 17 00:00:00 2001 From: Philipp Basler Date: Sun, 2 Jun 2024 09:14:51 +0200 Subject: [PATCH 39/48] Remove unused option --- CMakeLists.txt | 1 - README.md | 7 ------- 2 files changed, 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf17c8a5..59b64884 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,6 @@ option (LIBCMAES_BUILD_TESTS "build tests" OFF) option (LIBCMAES_BUILD_EXAMPLES "build examples" ${LIBCMAES_TOP_LEVEL}) option (LIBCMAES_USE_OPENMP "Use OpenMP for multithreading" ON) option (LIBCMAES_ENABLE_SURROG "support for surrogates" ON) -option (LIBCMAES_USE_CONAN "Use conan to get the dependencies" OFF) # Offer the user the choice of overriding the installation directories set (INSTALL_LIB_DIR lib${LIB_SUFFIX} diff --git a/README.md b/README.md index c21e73ec..8ae68159 100644 --- a/README.md +++ b/README.md @@ -69,13 +69,6 @@ make -j2 make install ``` -Additionally, you can use [conan](https://conan.io/center/) to take care of the dependencies. For this you run cmake as -``` -cmake -S . -B build -DCMAKE_INSTALL_PREFIX=~/.local/ -DLIBCMAES_USE_CONAN=On -cmake --build build -j2 -cmake --build build -j2 -t install -``` - ### Run examples ``` cd tests From 4c44f41d8e1919f55a7b6398916b3d876a20d255 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Tue, 4 Jun 2024 06:33:44 +0200 Subject: [PATCH 40/48] Add openmp as dependency --- conanfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conanfile.py b/conanfile.py index 859ef632..972f892b 100644 --- a/conanfile.py +++ b/conanfile.py @@ -57,6 +57,9 @@ def build_requirements(self): def requirements(self): self.requires("eigen/3.4.0", transitive_headers=True) + if self.options.openmp: + self.requires("llvm-openmp/17.0.6", transitive_headers=True) + def set_version(self): content = load(self, os.path.join(self.recipe_folder, "CMakeLists.txt")) value = re.search(r"set\(libcmaes_VERSION (.*)\)", content) From 0bab1ea6837e7cf2de3f96a723d8a6866b24fbdc Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Tue, 4 Jun 2024 06:42:00 +0200 Subject: [PATCH 41/48] only mp in not windows --- .github/workflows/conan.yml | 5 ++++- conanfile.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index 13a4601a..bab9b80d 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -35,4 +35,7 @@ jobs: - name: Install conan run: pip install conan>2 - run: conan profile detect - - run: conan create . --build=missing + - run: conan create . --build=missing --options shared=True + name: Build shared + - run: conan create . --build=missing --options shared=False + name: Build static diff --git a/conanfile.py b/conanfile.py index 972f892b..9b6c7d83 100644 --- a/conanfile.py +++ b/conanfile.py @@ -57,7 +57,7 @@ def build_requirements(self): def requirements(self): self.requires("eigen/3.4.0", transitive_headers=True) - if self.options.openmp: + if self.options.openmp and self.settings.os != "windows": self.requires("llvm-openmp/17.0.6", transitive_headers=True) def set_version(self): From 15e50cedb8b836566ab9c2b539019cd1dc015f64 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Tue, 4 Jun 2024 06:43:45 +0200 Subject: [PATCH 42/48] fix typo --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 9b6c7d83..c4308358 100644 --- a/conanfile.py +++ b/conanfile.py @@ -57,7 +57,7 @@ def build_requirements(self): def requirements(self): self.requires("eigen/3.4.0", transitive_headers=True) - if self.options.openmp and self.settings.os != "windows": + if self.options.openmp and self.settings.os != "Windows": self.requires("llvm-openmp/17.0.6", transitive_headers=True) def set_version(self): From 5ac44a5aa3a68a544263aaf31664059be7cfa494 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:22:13 +0100 Subject: [PATCH 43/48] Format conanfile --- conanfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conanfile.py b/conanfile.py index c4308358..9d12ffac 100644 --- a/conanfile.py +++ b/conanfile.py @@ -46,7 +46,7 @@ class CmaesConan(ConanFile): "src/*", "libcmaes.pc.in", "tests/*", - "python/*" + "python/*", ) def build_requirements(self): @@ -102,7 +102,7 @@ def build(self): cmake.build() environment = Environment() - environment.define("CTEST_OUTPUT_ON_FAILURE","1") + environment.define("CTEST_OUTPUT_ON_FAILURE", "1") envvars = environment.vars(self) if self.options.enable_tests: From 160bb4f0a8a58a53a936fdcc70b8cb19122645d6 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:29:03 +0100 Subject: [PATCH 44/48] Run unit tests in conan --- .github/workflows/conan.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index bab9b80d..083d1064 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -35,7 +35,7 @@ jobs: - name: Install conan run: pip install conan>2 - run: conan profile detect - - run: conan create . --build=missing --options shared=True + - run: conan create . --build=missing --options shared=True --options enable_tests=True name: Build shared - - run: conan create . --build=missing --options shared=False + - run: conan create . --build=missing --options shared=False --options enable_tests=True name: Build static From 18830149a4b377e75360bc608670607701440735 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:29:52 +0100 Subject: [PATCH 45/48] Revert "Run unit tests in conan" This reverts commit 160bb4f0a8a58a53a936fdcc70b8cb19122645d6. --- .github/workflows/conan.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conan.yml b/.github/workflows/conan.yml index 083d1064..bab9b80d 100644 --- a/.github/workflows/conan.yml +++ b/.github/workflows/conan.yml @@ -35,7 +35,7 @@ jobs: - name: Install conan run: pip install conan>2 - run: conan profile detect - - run: conan create . --build=missing --options shared=True --options enable_tests=True + - run: conan create . --build=missing --options shared=True name: Build shared - - run: conan create . --build=missing --options shared=False --options enable_tests=True + - run: conan create . --build=missing --options shared=False name: Build static From 457b9fc6252797f54c674c4c60bb66ab080268ef Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:45:57 +0100 Subject: [PATCH 46/48] Remove build missing --- .github/workflows/windows_unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 0685fb97..4a544166 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -27,7 +27,7 @@ jobs: - run: conan profile detect - - run: conan create . --options enable_tests=True --build=missing + - run: conan create . --options &:enable_tests=True From 783c3ac1d686545cbe321eab79e945dfd7f1b4f2 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:48:54 +0100 Subject: [PATCH 47/48] fix syntax --- .github/workflows/windows_unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml index 4a544166..bbd74768 100644 --- a/.github/workflows/windows_unit_tests.yml +++ b/.github/workflows/windows_unit_tests.yml @@ -27,7 +27,7 @@ jobs: - run: conan profile detect - - run: conan create . --options &:enable_tests=True + - run: conan create . --options '&:enable_tests=True' From cef09f0bce04b995eec7fc7e57151a2fd703bb52 Mon Sep 17 00:00:00 2001 From: Philipp Basler <28863303+phbasler@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:54:26 +0100 Subject: [PATCH 48/48] Remove windows unit tests --- .github/workflows/windows_unit_tests.yml | 36 ------------------------ 1 file changed, 36 deletions(-) delete mode 100644 .github/workflows/windows_unit_tests.yml diff --git a/.github/workflows/windows_unit_tests.yml b/.github/workflows/windows_unit_tests.yml deleted file mode 100644 index bbd74768..00000000 --- a/.github/workflows/windows_unit_tests.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Windows unit tests - -on: - push: - branches: [ master] - pull_request: - branches: [ master ] - workflow_dispatch: - - -jobs: - windows-tests-fullSetup: - runs-on: windows-latest - if: "!contains(github.event.head_commit.message, 'skip-ci')" - - steps: - - uses: actions/checkout@v3 - with: - persist-credentials: false - - uses: actions/setup-python@v3 - with: - python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax - architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Install pip packages - run: pip install conan numpy setuptools - - - run: conan profile detect - - - - run: conan create . --options '&:enable_tests=True' - - - - - -