|
function(detect_os OS) |
|
# it could be cross compilation |
|
message(DEBUG "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) |
|
else () |
|
set(${OS} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE) |
|
endif () |
|
endif () |
|
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() |
|
|
|
|
|
function(detect_compiler COMPILER COMPILER_VERSION) |
|
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(DEBUG "cmake-conan: CMake compiler=${_COMPILER}") |
|
message(DEBUG "cmake-conan: CMake compiler version=${_COMPILER_VERSION}") |
|
|
|
if (_COMPILER MATCHES MSVC) |
|
set(_COMPILER "msvc") |
|
string(SUBSTRING ${MSVC_VERSION} 0 3 _COMPILER_VERSION) |
|
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(DEBUG "cmake-conan: [settings] compiler=${_COMPILER}") |
|
message(DEBUG "cmake-conan: [settings] compiler.version=${_COMPILER_VERSION}") |
|
|
|
set(${COMPILER} ${_COMPILER} PARENT_SCOPE) |
|
set(${COMPILER_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE) |
|
endfunction() |
|
|
|
function(detect_build_type BUILD_TYPE) |
|
if (NOT CMAKE_CONFIGURATION_TYPES) |
|
# 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() |
|
|
|
|
|
function(detect_host_profile output_file) |
|
detect_os(MYOS) |
|
detect_compiler(MYCOMPILER MYCOMPILER_VERSION) |
|
detect_cxx_standard(MYCXX_STANDARD) |
|
detect_build_type(MYBUILD_TYPE) |
|
|
|
set(PROFILE "") |
|
string(APPEND PROFILE "include(default)\n") |
|
string(APPEND PROFILE "[settings]\n") |
|
if (MYOS) |
|
string(APPEND PROFILE os=${MYOS} "\n") |
|
endif () |
|
if (MYCOMPILER) |
|
string(APPEND PROFILE compiler=${MYCOMPILER} "\n") |
|
endif () |
|
if (MYCOMPILER_VERSION) |
|
string(APPEND PROFILE compiler.version=${MYCOMPILER_VERSION} "\n") |
|
endif () |
|
if (MYCXX_STANDARD) |
|
string(APPEND PROFILE compiler.cppstd=${MYCXX_STANDARD} "\n") |
|
endif () |
|
if (MYBUILD_TYPE) |
|
string(APPEND PROFILE "build_type=${MYBUILD_TYPE}\n") |
|
endif () |
|
|
|
if (NOT DEFINED output_file) |
|
set(_FN "${CMAKE_BINARY_DIR}/conan/profile") |
|
else () |
|
set(_FN ${output_file}) |
|
endif () |
|
|
|
string(APPEND PROFILE "[conf]\n") |
|
string(APPEND PROFILE "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n") |
|
|
|
string(TOUPPER "${CMAKE_BUILD_TYPE}" CONAN_BUILD_TYPE) |
|
set(CONAN_CXXFLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CONAN_BUILD_TYPE}}") |
|
set(CONAN_CFLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CONAN_BUILD_TYPE}}") |
|
set(CONAN_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}") |
|
string(APPEND PROFILE "[buildenv]\n") |
|
if(CONAN_CFLAGS) |
|
string(APPEND PROFILE "CFLAGS+=${CONAN_CFLAGS}\n") |
|
endif() |
|
if(CONAN_CXXFLAGS) |
|
string(APPEND PROFILE "CXXFLAGS+=${CONAN_CXXFLAGS}\n") |
|
endif() |
|
if(CONAN_LDFLAGS) |
|
string(APPEND PROFILE "LDFLAGS+=${CONAN_LDFLAGS}\n") |
|
endif() |
|
|
|
if(CMAKE_C_COMPILER) |
|
string(APPEND PROFILE "CC=${CMAKE_C_COMPILER}\n") |
|
endif() |
|
if(CMAKE_CXX_COMPILER) |
|
string(APPEND PROFILE "CXX=${CMAKE_CXX_COMPILER}\n") |
|
endif() |
|
if(CMAKE_Fortran_COMPILER) |
|
string(APPEND PROFILE "FC=${CMAKE_Fortran_COMPILER}\n") |
|
endif() |
|
|
|
message(STATUS "cmake-conan: Creating profile ${_FN}") |
|
file(WRITE ${_FN} ${PROFILE}) |
|
message(DEBUG "cmake-conan: Profile: \n${PROFILE}") |
|
endfunction() |
|
|
|
function(conan_install) |
|
cmake_parse_arguments(ARGS CONAN_ARGS ${ARGN}) |
|
if(DEFINED CONANFILE AND NOT DEFINED CONAN_PATH_OR_REFERENCE) |
|
set(CONAN_PATH_OR_REFERENCE "${CONANFILE}") |
|
elseif(NOT DEFINED CONAN_PATH_OR_REFERENCE) |
|
set(CONAN_PATH_OR_REFERENCE "${CMAKE_SOURCE_DIR}") |
|
endif() |
|
if(NOT DEFINED CONAN_OUTPUT_FOLDER) |
|
set(CONAN_OUTPUT_FOLDER "${CMAKE_BINARY_DIR}/conan") |
|
endif() |
|
|
|
# Invoke "conan install" with the provided arguments |
|
list(APPEND CONAN_ARGS -of=${CONAN_OUTPUT_FOLDER}) |
|
message(STATUS "cmake-conan: conan install ${CONAN_PATH_OR_REFERENCE} ${CONAN_ARGS} ${CONAN_OPTIONS} ${ARGN}") |
|
execute_process(COMMAND conan install "${CONAN_PATH_OR_REFERENCE}" ${CONAN_ARGS} ${CONAN_OPTIONS} ${ARGN} |
|
RESULT_VARIABLE return_code |
|
OUTPUT_VARIABLE conan_stdout |
|
ERROR_VARIABLE conan_stderr |
|
ECHO_OUTPUT_VARIABLE |
|
ECHO_ERROR_VARIABLE # show the text output regardless |
|
WORKING_DIRECTORY ${CONAN_OUTPUT_FOLDER}) |
|
if (NOT "${return_code}" STREQUAL "0") |
|
message(FATAL_ERROR "Conan install failed='${return_code}'") |
|
else () |
|
message(STATUS "cmake-conan: CONAN_OUTPUT_FOLDER=${CONAN_OUTPUT_FOLDER}") |
|
message(STATUS "cmake-conan:${conan_stdout}") |
|
set(CONAN_OUTPUT_FOLDER "${CONAN_OUTPUT_FOLDER}" PARENT_SCOPE) |
|
set(CONAN_INSTALL_SUCCESS TRUE CACHE BOOL "Conan install has been invoked and was successful") |
|
endif () |
|
endfunction() |
|
|
|
|
|
function(conan_provide_dependency package_name) |
|
if(NOT CONAN_INSTALL_SUCCESS OR NOT IS_DIRECTORY "${CMAKE_BINARY_DIR}/conan") |
|
message(STATUS "cmake-conan: first find_package(${ARGV1}) found. Installing dependencies with Conan") |
|
detect_host_profile(${CMAKE_BINARY_DIR}/conan/conan_host_profile) |
|
if(NOT CMAKE_CONFIGURATION_TYPES) |
|
message(STATUS "cmake-conan: Installing single configuration ${CMAKE_BUILD_TYPE}") |
|
conan_install(-pr ${CMAKE_BINARY_DIR}/conan/conan_host_profile --build=missing --build=outdated --build=cascade -g CMakeDeps) |
|
else() |
|
message(STATUS "cmake-conan: Installing both Debug and Release") |
|
conan_install(-pr ${CMAKE_BINARY_DIR}/conan/conan_host_profile -s build_type=Release --build=missing --build=outdated --build=cascade -g CMakeDeps) |
|
conan_install(-pr ${CMAKE_BINARY_DIR}/conan/conan_host_profile -s build_type=Debug --build=missing --build=outdated --build=cascade -g CMakeDeps) |
|
endif() |
|
if (CONAN_INSTALL_SUCCESS) |
|
set(CONAN_OUTPUT_FOLDER "${CONAN_OUTPUT_FOLDER}" CACHE PATH "Conan generators folder") |
|
set(CONAN_GENERATORS_FOLDER "${CONAN_OUTPUT_FOLDER}" CACHE PATH "Conan output folder") |
|
endif() |
|
else() |
|
message(DEBUG "cmake-conan: find_package(${ARGV1}) found, 'conan install' already ran") |
|
endif() |
|
|
|
if (NOT CONAN_OUTPUT_FOLDER IN_LIST CMAKE_PREFIX_PATH) |
|
message(STATUS "Prepending conan output folder to CMAKE_PREFIX_PATH: ${CONAN_OUTPUT_FOLDER}") |
|
list(PREPEND CMAKE_PREFIX_PATH "${CONAN_OUTPUT_FOLDER}") |
|
list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH) |
|
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} CACHE INTERNAL "") |
|
endif() |
|
find_package(${ARGN} BYPASS_PROVIDER) |
|
endfunction() |